Examples

本文包含了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()
", __FUNCTION__);

    allow_signal(SIGKILL); //使得线程可以接收SIGKILL信号
    mdelay(2000);
    
    printk("should stop: %d
",kthread_should_stop());


    while (!signal_pending(current) && !kthread_should_stop())         //使得线程可以被杀死,也可以在rmmod的时候结束                
    {    
        printk(" jiffies is %lu
", jiffies);
        set_current_state(TASK_INTERRUPTIBLE);     
        schedule_timeout(HZ * 5);                   //这两句是为了延时5s,在这5s内,处理器会处理其他进程。
        printk("should stop: %d
",kthread_should_stop());
    }
    

    printk("Leaving my_function
");
    flag = 1;

    return 0;
}
static int __init sama5d3_gpio_init(void)
{
   printk("SAMA5D3 gpio init!
") ;

     task = kthread_run(my_function,NULL,"my_function");
//     printk("<1> init wait_for_completion()
");
    return 0;
}


static void __exit sama5d3_gpio_exit(void)
{
    int ret ;
    printk("sama5d3 gpio exit!
");
    if(!flag)
    {
        if(!IS_ERR(task))
        {
            ret = kthread_stop(task);
            printk(KERN_INFO "First thread function has stopped ,return %d
", ret);
        }
    }//  printk("task_struct: 0x%x",task);
    printk(" Goodbye
");
    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   -----清除打印信息

原文地址:https://www.cnblogs.com/hjj801006/p/4552614.html