获取 ns 时间戳(已弃用)
1 2 3 4 5 6 7
| #include <linux/timekeeping32.h>
struct timespec ts; u64 ns;
getnstimeofday(&ts); ns = timespec_to_ns(&ts);
|
ktime accessors — The Linux Kernel documentation
可以使用 ktime_get_ns() 替代。 如果要获取 us 时间会涉及到 64bit 除法问题,会遇到如下问题:
1
| ERROR: modpost: "__aeabi_uldivmod" [common_drivers/drivers/usb/dwc_otg.ko] undefined!
|
调用 div_u64() 函数,需要 include <linux/math64.h>
1
| u64 tm = div_u64(ktime_get_raw_ns(),1000);
|
Dump Stack
1 2
| #include <asm/ptrace.h> dump_stack();
|
Linux 中根据函数指针打印函数名
1
| printk("func: %pS at address: %px\\n", func, func);
|
调整线程优先级
1 2 3 4 5
| #include <uapi/linux/sched/types.h>
struct sched_param param = { .sched_priority = 99 }; thread_handle = kthread_run(thread_capture, audio_pcm, "dsp_cap"); sched_setscheduler(thread_handle, SCHED_FIFO, ¶m);
|
信号量
1 2 3 4 5
| #include <linux/semaphore.h>
sema_init(&sem, 0); up(&sem); down_timeout(&sem, usecs_to_jiffies(sleep_us))
|
Timer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| #include <linux/module.h> #include<linux/timer.h> MODULE_LICENSE("GPL"); struct tests{ int my_number; struct timer_list my_timer; } my_data;
void my_timer_function(struct timer_list *t) { printk("In the my_timer_function\\n"); printk("the jiffies is :%ld\\n", jiffies); struct tests *datas = from_timer(datas,t,my_timer); printk("my number is :%d\\n", tests->my_number); }
int __init setup_timer_init(void) { printk("my_timer will be created.\\n"); printk("the jiffies is :%ld\\n", jiffies); my_data.my_timer.expires = jiffies + 1*HZ;
timer_setup(&my_data.my_timer, my_timer_function, 0); add_timer(&my_data.my_timer); printk("my_timer init.\\n"); return 0; }
void __exit setup_timer_exit(void) { printk("Goodbye setup_timer\\n"); del_timer(&my_data.my_timer); }
module_init(setup_timer_init); module_exit(setup_timer_exit);
|
module param
module_param(insmod ko 文件时传递参数)
1 2 3
| static int global_val_test = MY_MAJOR; module_param(global_val_test, int, 0644);
|
再编译模块后,再 insmod 加载模块时就可以传参数进去了,如:
1 2 3 4 5 6
| [root@bogon hello_world] [root@bogon hello_world] May 26 14:20:08 localhost kernel: [63460.994397] global_val_test = 5 May 26 14:20:08 localhost kernel: [63460.994409] hello world enter May 26 14:20:08 localhost kernel: global_val_test = 5 May 26 14:20:08 localhost kernel: hello world enter
|
同时,在模块目录下会生成 parameter 目录及参数文件,如下:
1 2 3 4 5
| [root@bogon hello_world] coresize holders/ initsize initstate notes/ parameters/ refcnt rhelversion sections/ srcversion taint uevent version [root@bogon hello_world] total 0 -rw-r--r-- 1 root root 16384 May 26 14:54 global_val_test
|
MODULE_PARM_DESC
MODULE_PARM_DESC 是用来描述驱动模块的参数信息的。 例如驱动内有这么一行代码:MODULE_PARM_DESC(stacfgpath, "Get path of sta cfg"); 假设编译生成的驱动文件为 test.ko 我们使用:modinfo test.ko
1 2 3 4 5 6 7 8 9
| filename: /home/test/test.ko license: GPL srcversion: depends: retpoline: Y name: test vermagic: 4.15.0-129-generic SMP mod_unload parm: stacfgpath:Get path of sta cfg (charp)
|
MODULE_PARM_DESC 内描述的信息就会在 parm 这一行参数显示出来,这样用户就知道要加载这个驱动可以传入哪些参数了。