驱动基础知识
makefile添加模块编译好.ko文件后 insmod添加模块 由于学习使用的是虚拟终端需要使用dmesg指令显示Kconfig是定义可配置项让用户选择对应功能Makefile会根据用户选择的配置项来控制代码的编译行为。驱动三种状态编译进内核编译成模块不编译进内核如何把驱动编译进内核使用kconfig和Makefile在内核路径下打开kconfig文件将驱动放到哪个目录下就到那个目录下的kconfig添加kconfig将menuconfig中的驱动选择星号编译进内核后会在内核目录下生成一个 .config目录vi.config文件找到对应的配置选项下一步是Makefile编译字符目录下的Makefile与kconfig一样要哪一个类型的驱动就打开哪一个目录下的MakefileMakefile中的蓝色字体宏改成CONFIG_LEDS_MP1A 后面的项目名字改成驱动文件名字最后可以进行编译内核了编译完成后会生成uImage文件将生成的uImage文件拷贝到tftp目录下更新内核setenv bootargs root/dev/nfs nfsroot192.168.100.240:/home/hqyj/rootfs rwconsolettySAC2,115200 init/linuxrc ip192.168.100.241 clk_ignore_unusedtrue内核拷贝完成后创建设备运行应用程序。写完驱动和应用程序加载成外部模块led为例子驱动编写创建设备号 dev_t devnoMKDEV(主设备号次设备号申请设备号 retregister_chrdev_region(devno,decive_number,led)设备初始化 cdev_init(cdev,led_fops)设备注册 retcdev_add(cdev,devno,device_number);将写好的驱动.c文件交叉编译成.ko文件Makefile中内核所在的路径需要改成自己的路径linuxubuntu:$ make ARCHarm CROSS_COMPILEarm-fsmp1x-linux-gnueabihf- modules编译可执行文件test在上图的 最后一行通过scp tftp 或者nfs 将应用程序和驱动放到开发班上在开发板上insmod .ko文件安装模块mknod dev/cdev c 300 0创建设备./开启可执行文件将写好的led驱动编译进内核过程将所需的文件放到内核中对应的文件夹下用kconfi和Makefile进行编译进内核进入到驱动文件放置的文件夹下打开当前文件夹下的kconfig添加对应的选项内核目录下进入menuconfig进行图像选择进入到设备 -字符设备 将自己编写this is the mainboard leds of MP1A 选为 * 编译进内核完成后保存并退出会生成一个.config文件进入.config文件再进入到驱动下字符设备下的Makefile括号中的宏改为.config中的宏 等号后的文件名改为驱动的文件名退到内核目录进行编译内核编译完成后生成uImage文件将他拷贝到tftp目录下 uImage在下面的目录下arch/arm/boot内核编译选择对应平台才可以编译内核需要配置关于platform——device写好的设备文件编译后会出现在sys/bus/platform/devices目录下各种结构体inode-i_cdev指向struct cdev实例的指针probe函数中这行代码是给内核的 I2C 设备对象 “贴标签”—— 告诉内核这个clientI2C 传感器对应的驱动私有数据是sensor后续可以通过client快速找到sensor。对于大量结构体的总结关于inode注册字符设备后mknod会在内核中产生inode内核通过inode里的设备号匹配到你之前注册的struct cdev并把cdev的指针赋值给inode-i_cdev。内核调用cdev关联的file_operations中的open函数并把这个inode作为参数传进去。inode-i_cdev本质上就是sensor.cdevsensor是私有结构体的名字也就是你自定义结构体里的cdev成员的指针。这一步的目的把恢复出来的sensor指针保存起来这样在后续的read、ioctl等函数中就可以直接从file-private_data中取出sensor进而访问sensor-clientmodule_platform_driver(platform_drv)关于insmod和mknod编译进内核后就不用在开发板上打insmod使用device_creat函数后就不用mknod了设备树设备树节点所在目录厂商给的写好的设备树文件一般是不会动的自己可以写一个test.dts文件去然后去修改文件关于保存一些传参中给的参数例如inode和clientdevice在probe函数之后驱动的其他函数如read、ioctl、remove被调用时内核不会再直接传入client指针。我们需要通过自定义的sensor结构体来找回这个指针从而与硬件进行通信。ioctl中copy_to_user((void *)arg, (void *)value, sizeof(int)) arg是用户态存放数据的地址设备号300在之前学习中被编译进内核占用了如何确定有自己设备树节点然后再去sys/bus/下看后面蓝色的就是路径/sys/firmware/devicetree/base/soc/i2c4001200/sth2040注意重启之后要下载扩展板的。设置私有数据的作用将驱动侧的私有数据结构与设备实例绑定方便在整个驱动生命周期中随时获取和使用。sys和dev的区别/sys目录下的文件是虚拟文本文件核心作用是 “暴露硬件的属性和状态”让你用最简单的cat/echo就能查看 / 配置不用写复杂代码。按 “总线 - 设备 - 驱动” 的层级组织如/sys/class/leds/每个文件对应一个属性如亮度、GPIO 号、使能状态读写文件会直接触发驱动的show/store回调本质是操作内核变量无主 / 次设备号纯属性映射/dev目录下的文件是设备文件不是普通文本每个文件对应一个硬件设备核心作用是给应用层提供 “操作硬件的入口”。关键特性设备文件有固定的类型c字符设备如 LED、串口、b块设备如硬盘每个设备文件绑定 “主设备号 次设备号”内核通过这组编号找到对应的驱动不能用cat/echo直接读写少数简单设备除外需要通过编程调用open/read/write。获取私有数据指针的函数**核心通用函数**dev_get_drvdata/dev_set_drvdata所有设备类型都能复用2. **总线专属函数**Platform 用 platform_xxxI2C 用 i2c_xxxSPI 用 spi_xxx本质是对 dev_get/set_drvdata 的封装3. **文件操作专属**直接读写 file-private_data需在 open 中初始化
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2561556.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!