OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4312|回复: 2

字符设备开发驱动的理解----为什么非要12个字

[复制链接]

19

主题

49

帖子

0

精华

高级会员

Rank: 4

积分
728
金钱
728
注册时间
2015-8-20
在线时间
58 小时
发表于 2020-4-11 19:18:31 | 显示全部楼层 |阅读模式
本帖最后由 zuozhongkai 于 2020-4-13 16:58 编辑

在家学习原子哥的linux视频.......学到了第一个字符设备开发(chrdevbase)
左老师对整个字符设备驱动开发的原理讲的很详细。
在他的基础上,有了一些自己的理解,在这里分享给大家。
1.回顾一下从驱动到LED亮灭实验完成,我们做了哪些事情
①在驱动中
    #define LED_MAJOR  200  /* 主设备号 */---------以后我们这个设备在系统的设备节点上就是c-200-0(字符-主-次设备)
    #define LED_NAME  "led"  /* 设备名字 */
    led_switch----(操作寄存器,控制灯亮灭)
    led_open----(空的)
    led_read----(空的)
    led_write----(操作有点多,回头再说)
   led_release---(空的)
    struct file_operations led_fops ---(几个赋值)
          ------(让open=这个模块的led_open)
          ------(让read=这个模块的led_read)
          ------(让write=这个模块的led_write)
          ------(让release=这个模块的led_release)
    led_init-----(操作几组寄存器,为LED的亮灭做准备)
    led_exit----(断开了几个地址映射)
    module_init(led_init)---------模块注册------insmod 模块时调用
    module_exit(led_exit)--------模块注销------rmmod 模块时调用
②在测试代码中
    if(argc != 3)----判断运行APP时的参数是不是3个-----   ./ledAPP   /dev/led    1
    filename = argv[1]; ----------将/dev/led赋给filename
    fd = open(filename, O_RDWR);--------调用open-----和驱动中的结构体赋值对应起来看,它是led_open吗?
    if(fd < 0)---------一个判断
    databuf[0] = atoi(argv[2]); ----------一个类型转换
    retvalue = write(fd, databuf, sizeof(databuf));--------调用write--------和驱动中的结构体赋值对应起来看,它是led_write吗?
    if(retvalue < 0)-------一个判断
    close(fd);---------关闭文件。
③在开发板中的操作
    insmod led.ko
    mknod  /dev/led c 200 0---在系统中创建设备文件
    ./ledAPP /dev/led 1 ---------运行ledAPP,并给两个参数,argv[0]=/dev/led,argv[1]='1'
以上三个操作,就实现了LED的亮灭。
针对这个过程我们提出几个值得我们思考的问题:
①执行insmod后,linux做了什么?---------linux加载了我们的驱动模块
②执行mknod 后,linux做了什么?-------linux在设备节点的c-200-0上做了一个命名,命名为/dev/led,以后/dev/led就=该设备
③运行APP,linux做了什么?---------------linux把/dev/led和1传递给APP,并执行了APP这个程序。
--------------------------------------------------------------------------------------------------------------------------------------------
从字面上看没有问题。我又有几个问题:
①linux把设备节点c-200-0命名为/dev/led,那这个和具体的LED是怎么建立对应关系的?
------mknod后,设备节点c-200-0的设备就是/dev/led
------在运行APP时,把/dev/led传递给了APP,相当于给APP传了一个c-200-0的设备号,
------在众多驱动中,c-200-0的驱动就对应led.ko
------APP对/dev/led这个设备的使用系统调用函数open、write等的时候就注定了要和led.ko中的led_open、led_write函数。
②为什么要insmod led.ko去加载模块?
------linux用户空间和内核空间是分开的。
------单纯一个led.ko文件,是磁盘(或者flash)上的一堆数据,要把这对数据加载到内存(ddr-RAM)中(的内核空间)去。


---------------------------------这几个问题搞清楚了,我们再来看一个很有意思的编程思想---------------------------------------

这个问题是这样产生的:
系统调用write函数怎么和我们的led_write函数建立联系的呢?或者说
那么多驱动的XXX_write函数,系统怎么就知道了一个设备号就知道用哪个_write呢?
我们看一个例子
--------------------------------------------------注意这只是说一个编程思想-------------------------------------
#include <stdio.h>
struct _worker{
    unsigned int worker_id;   //员工ID
    unsigned int work_day;    //工作天数
    unsigned int(*jiesuan)(unsigned int days);//工资结算公式

    unsigned int money;       //本月的工资
};
typedef struct _worker worker;
unsigned int jiesuan_1(unsigned int days);
unsigned int jiesuan_2(unsigned int days);
unsigned int jiesuan_3(unsigned int days);
int main(int argc,char argv[])
{
    worker zhangsan,
lisi;
    zhangsan.worker_id = 1387;
    zhangsan.work_day = 35;

    zhangsan.jiesuan = &jiesuan_1;
    printf("zhangsan's money=%d\r\n",zhangsan.jiesuan(zhangsan.work_day));

    lisi.worker_id = 0105;
    lisi.work_day = 29;
    lisi.jiesuan = &jiesuan_3;
    printf("lisi's money=%d\r\n", lisi.jiesuan(lisi.work_day));getchar();
}
unsigned int jiesuan_1(unsigned int days) { return 100 * days;}
unsigned int jiesuan_2(unsigned int days) { return 200 * days;}
unsigned int jiesuan_3(unsigned int days) { return 300 * days;}

-------------------------------------------------------------------------------------------------
我们在对(有函数指针的结构体)赋值的时候,它的函数指针指其实是指向一类函数。
对于不同的结构体变量a和b,
a.jiesuan和b.jiesuan就是不同的函数,以至于a.jiesuan(20)和b.jiesuan(20)的结果是不一样的。
---------------------------------------------------------------------------------------------------------------------
初学者很生硬的理解,必定有很多不严谨的地方,欢迎大家批评指正!











正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

19

主题

49

帖子

0

精华

高级会员

Rank: 4

积分
728
金钱
728
注册时间
2015-8-20
在线时间
58 小时
 楼主| 发表于 2020-4-11 19:21:05 | 显示全部楼层
最后那个图怎么还在......气死自己了!
回复 支持 反对

使用道具 举报

88

主题

7377

帖子

5

精华

资深版主

Rank: 8Rank: 8

积分
14980
金钱
14980
注册时间
2013-11-13
在线时间
1823 小时
发表于 2020-4-13 16:58:06 | 显示全部楼层
总结的不错,点个赞。后面的图片给你删了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-25 10:00

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表