本文包含了linux驱动模块化编程的基本,包括创建多线程,延时,以及makefile
以一个实例来说明
#include<linux/init.h> #include<linux/module.h> #include<linux/kernel.h> #include<linux/sched.h> #include<linux/init.h> #include<linux/timer.h> #include<linux/kthread.h> #include<linux/delay.h> #include<linux/sched.h> #include<linux/completion.h> #include<linux/signal.h> #include <asm/processor.h> #include <asm/system.h> #include <linux/param.h> #include<linux/gpio.h> #include "gpio-sama5d3-test.h" //如果没有对应的.h文件,请注释 //static DECLARE_COMPLETION(my_completion); static struct task_struct *task; int flag = 0; int my_function(void *arg) { // printk(" in %s()\n", __FUNCTION__); allow_signal(SIGKILL); //使得线程可以接收SIGKILL信号 mdelay(2000); printk("should stop: %d\n",kthread_should_stop()); while (!signal_pending(current) && !kthread_should_stop()) //使得线程可以被杀死,也可以在rmmod的时候结束 { printk(" jiffies is %lu\n", jiffies); set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ * 5); //这两句是为了延时5s,在这5s内,处理器会处理其他进程。 printk("should stop: %d\n",kthread_should_stop()); } printk("Leaving my_function\n"); flag = 1; return 0; } static int __init sama5d3_gpio_init(void) { printk("SAMA5D3 gpio init!\n") ; task = kthread_run(my_function,NULL,"my_function"); // printk("<1> init wait_for_completion()\n"); return 0; } static void __exit sama5d3_gpio_exit(void) { int ret ; printk("sama5d3 gpio exit!\n"); if(!flag) { if(!IS_ERR(task)) { ret = kthread_stop(task); printk(KERN_INFO "First thread function has stopped ,return %d\n", ret); } }// printk("task_struct: 0x%x",task); printk(" Goodbye\n"); return; } module_init(sama5d3_gpio_init); module_exit(sama5d3_gpio_exit); MODULE_AUTHOR("HUANGJJY"); MODULE_DESCRIPTION("GPIO driver for sama5d3"); MODULE_LICENSE("GPL");
makefile如下:
ifeq ($(KERNELRELEASE),) #KERNEL_DIR = /home/user/project2/ATMEL/linux-at91/ //如果是交叉编译,此为内核路径 KERNEL_DIR ?= /lib/modules/$(shell uname -r)/build PWD :=$(shell pwd) #CROSS_COMPILE = /home/user/project2/ATMEL/toolchain/gcc-linaro-arm-linux-gnueabihf-4.7-2013.04-20130415_linux/bin/arm-linux-gnueabihf- #CC = $(CROSS_COMPILE)gcc //如果是交叉编译,此为交叉编译工具链名称和路径#INCLUDE = $(PWD)/gpio-sama5d3-test.h //如果.c文件有.h文件,这是.h的路径 modules: $(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules #$(MAKE) -I$(INCLUDE) -C $(KERNEL_DIR) M=$(PWD) modules //如果该.c文件有.h文件,则用此编译语法 .PHONY:modules clean clean: $(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean else obj-m := gpio-sama5d3-test.o endif
编写完上述两个文件后,保存退出。
# make
会生成.ko文件
# insmod ****.ko -------挂载驱动
#lsmod --------查看挂载的驱动
#rmmod ***.ko ------卸载驱动
#dmesg or dmesg | tail -20 查看驱动打印信息
#dmesg -c -----清除打印信息
时间: 2024-10-28 09:53:51