• Linux驱动开发一


    一、开发模块框架

        1),编写源代码
        #include
        #include

        //加载函数
        static int __init hello_init(void)
        {
            printk("----- ^_^  --------%s-------\n",__FUNCTION__);

            return 0;
        }

        //卸载函数
        static void __exit hello_exit(void)
        {
            printk("-----------%s-----------\n",__FUNCTION__);
        }


        module_init(hello_init);//声明加载函数
        module_exit(hello_exit);//声明卸载函数
        MODULE_LICENSE("GPL");//认证
        
        2):写Makefile
          1 #指定内核源码的路径
          2 KERNEL_DIR = /home/GNNUXXL/s5pv210/kernel/linux-3.0.8
          3 CURENT_DIR = $(shell pwd)
          4
          5 all:
          6             #将当前路径下的源码编译为内核模块
          7             make -C $(KERNEL_DIR) M=$(CURENT_DIR) modules
          8 clean:
          9             #清除生成的模块文件
         10             make -C $(KERNEL_DIR) M=$(CURENT_DIR) clean
         11 install:
         12             cp *.ko /opt/rootfs/drv_module/
         13 #指定哪个文件生成模块
         14 obj-m = hello_drv.o
         
         3):将生成的模块拷贝到开发板中
            cp *.ko /opt/rootfs/drv_module/   或者使用 make install
         
         4)加载模块
         [root@GNNUXXL /drv_module]# insmod hello_drv.ko
            ----- ^_^  --------hello_init-------
        5)查看模块信息
        root@GNNUXXL /drv_module]# lsmod
                hello_drv 779 0 - Live 0x7f00c000
        6)卸载模块        
        [root@GNNUXXL /drv_module]# rmmod hello_drv
            -----------hello_exit-----------
    二、模块传参特性
            1)在加载模块时,可以进行传参,但是在编写代码时要对参数进行声明
                例如:
                module_param(变量名,类型,权限 0644);
                
                module_param(num,int, 0644);
                module_param(name, charp, 0644);

                [root@GNNUXXL /drv_module]# insmod hello_arg.ko
                -------------hello_arg_init------------
                num=1001        name=bao_ma_nan
                [root@GNNUXXL /drv_module]# rmmod hello_arg
                -------------hello_arg_exit------------
                [root@GNNUXXL /drv_module]# insmod hello_arg.ko num=1999 name="fansha"
                -------------hello_arg_init------------
                num=1999        name=fansha

                
                在加载模块时会创建一个同名文件存放相关参数
                [root@GNNUXXL /drv_module]# ls -l /sys/module/hello_arg/parameters/
                total 0
                -rw-r--r--    1 0        0             4096 Jan  1 02:29 name
                -rw-r--r--    1 0        0             4096 Jan  1 02:29 num

         
            2)模块调用
            
            
                //被调用模块
                int mysum(int a,int b)
                {
                    return a+b;
                }

                //声明mysum函数
                EXPORT_SYMBOL(mysum);
            
                在加载过程中,先加载被调用模块,后加载本身模块
            
                [root@GNNUXXL /drv_module]# insmod mysum.ko
                [root@GNNUXXL /drv_module]# lsmod
                mysum 561 0 - Live 0x7f010000
                [root@GNNUXXL /drv_module]# insmod hello_call.ko n=100 m=150
                -----------hello_call_init-------------
                100+150 = 250
                [root@GNNUXXL /drv_module]# lsmod
                hello_call 1000 0 - Live 0x7f014000
                mysum 561 1 hello_call, Live 0x7f010000
                
                在卸载时,先卸载本身模块,后卸载调用模块            
                [root@GNNUXXL /drv_module]# rmmod hello_call
                ------------hello_call_exit-----------
                [root@GNNUXXL /drv_module]# rmmod mysum
                
                
    三、一个完成驱动程序的开发
                设备号由32位组成
                    -----------> 主设备号 -------高12位
                    -----------> 次设备号 -------低20位
            
            1)申请设备号:
            register_chrdev(unsigned int major, const char * name, const struct file_operations * fops)
            参数1:
                当major=0时,主设备号为动态分配,函数返回主设备号
                当major>0时,主设备号为静态分配,成功函数返回0
            参数2:驱动的描述信息---->自定义
            参数3:操作方法
            
            查看设备号 cat /proc/devices
            [root@GNNUXXL /drv_module]# cat /proc/devices
            Character devices:
              1 mem
            256 hello_drv
              2 pty
              3 ttyp
              4 /dev/vc/0
              4 tty
              4 ttyS
              5 /dev/tty
              5 /dev/console
              5 /dev/ptmx
              7 vcs
             10 misc
             13 input
             21 sg
            128 ptm
            136 pts
            204 ttySAC

            
            2)创建设备节点
                ----->手动创建设备节点
                    mknod 设备名 设备类型  主设备号  次设备号
                    mknod /dev/hello c 254 0 
            
            
                ----->自动创建设备节点
                    创建类                
                    class_create(owner, name)
        
                    
                    创建设备
                    register_device(char * name, unsigned long start, unsigned long len)
            
            3)实现操作方法
         
         
         
         
         
         
         
         
         
         
         
         
         
         
         
         

        

  • 相关阅读:
    第十四章 Productions最佳实践 - 创建或编辑路由进程
    注册公司资本认缴和实缴有何区别?
    【3D建模制作技巧分享】用3dsmax制作炫酷的机器人模型
    web音视频播放器(html5)方案总结
    原始套接字
    C++中的双冒号(::) 使用小结
    统一响应,自定义校验器,自定义异常,统一异常处理器
    使用 TiUP 部署运维 TiDB 线上集群
    数学与机器学习:共舞于智能时代的双璧
    Redis分布式锁
  • 原文地址:https://blog.csdn.net/GNNUXXL/article/details/126880237