当前位置: 首页 > news >正文

技术支持 滕州网站建设海南最新政策

技术支持 滕州网站建设,海南最新政策,优秀企业宣传册样本,广东住房和城乡建设部网站Linux版本号4.1.15 芯片I.MX6ULL 大叔学Linux 品人间百味 思文短情长 三、硬件原理图分析 四、驱动开发 1、platform设备与驱动程序开发 53 /* 54 * 设备资源信息#xff0c;也就是 LED0 所使用的所有寄存器 55 */ 56 static str…Linux版本号4.1.15   芯片I.MX6ULL                                    大叔学Linux    品人间百味  思文短情长  三、硬件原理图分析 四、驱动开发 1、platform设备与驱动程序开发 53 /* 54 * 设备资源信息也就是 LED0 所使用的所有寄存器 55 */ 56 static struct resource led_resources[] { 57 [0] { 58 .start CCM_CCGR1_BASE, 59 .end (CCM_CCGR1_BASE REGISTER_LENGTH - 1), 60 .flags IORESOURCE_MEM, 61 }, 62 [1] { 63 .start SW_MUX_GPIO1_IO03_BASE, 64 .end (SW_MUX_GPIO1_IO03_BASE REGISTER_LENGTH - 1), 65 .flags IORESOURCE_MEM, 66 }, 67 [2] { 68 .start SW_PAD_GPIO1_IO03_BASE, 69 .end (SW_PAD_GPIO1_IO03_BASE REGISTER_LENGTH - 1), 70 .flags IORESOURCE_MEM, 71 }, 72 [3] { 73 .start GPIO1_DR_BASE, 74 .end (GPIO1_DR_BASE REGISTER_LENGTH - 1), 75 .flags IORESOURCE_MEM, 76 }, 77 [4] { 78 .start GPIO1_GDIR_BASE, 79 .end (GPIO1_GDIR_BASE REGISTER_LENGTH - 1), 80 .flags IORESOURCE_MEM, 81 }, 82 }; led_resources 数组也就是设备资源描述了 LED 所要使用到的寄存器信息也就是 IORESOURCE_MEM 资源。 85 /* 86 * platform 设备结构体 87 */ 88 static struct platform_device leddevice { 89 .name imx6ul-led, 90 .id -1, 91 .dev { 92 .release led_release, 93 }, 94 .num_resources ARRAY_SIZE(led_resources), 95 .resource led_resources, 96 }; platform 设备结构体变量 leddevice这里要注意 name 字段为“imx6ul-led”所 以稍后编写 platform 驱动中的 name 字段也要为“imx6ul-led”否则设备和驱动匹配失败。 98 /* 99 * description : 设备模块加载 100 * param : 无 101 * return : 无 102 */ 103 static int __init leddevice_init(void) 104 { 105 return platform_device_register(leddevice); 106 } 设备模块加载函数在此函数里面通过 platform_device_register 向 Linux 内核注册 leddevice 这个 platform 设备。 108 /* 109 * description : 设备模块注销 110 * param : 无 111 * return : 无 112 */ 113 static void __exit leddevice_exit(void) 114 { 115 platform_device_unregister(leddevice); 116 } 设备模块卸载函数在此函数里面通过 platform_device_unregister 从 Linux内核中删除掉 leddevice 这个 platform 设备。 34 #define LEDDEV_CNT 1 /* 设备号长度 */ 35 #define LEDDEV_NAME platled /* 设备名字 */ 36 #define LEDOFF 0 37 #define LEDON 1 38 39 /* 寄存器名 */ 40 static void __iomem *IMX6U_CCM_CCGR1; 41 static void __iomem *SW_MUX_GPIO1_IO03; 42 static void __iomem *SW_PAD_GPIO1_IO03; 43 static void __iomem *GPIO1_DR; 44 static void __iomem *GPIO1_GDIR; 45 46 /* leddev 设备结构体 */ 47 struct leddev_dev{ 48 dev_t devid; /* 设备号 */ 49 struct cdev cdev; /* cdev */ 50 struct class *class; /* 类 */ 51 struct device *device; /* 设备 */ 52 int major; /* 主设备号 */ 53 }; 54 55 struct leddev_dev leddev; /* led 设备 */ 56 57 /* 58 * description : LED 打开/关闭 59 * param - sta : LEDON(0) 打开 LED LEDOFF(1) 关闭 LED 60 * return : 无 61 */ 62 void led0_switch(u8 sta) 63 { 64 u32 val 0; 65 if(sta LEDON){ 66 val readl(GPIO1_DR); 67 val ~(1 3); 68 writel(val, GPIO1_DR); 69 }else if(sta LEDOFF){ 70 val readl(GPIO1_DR); 71 val| (1 3); 72 writel(val, GPIO1_DR); 73 } 74 } 75 76 /* 77 * description : 打开设备 78 * param – inode : 传递给驱动的 inode 79 * param - filp : 设备文件 file 结构体有个叫做 private_data 的成员变量 80 * 一般在 open 的时候将 private_data 指向设备结构体。 81 * return : 0 成功;其他 失败 82 */ 83 static int led_open(struct inode *inode, struct file *filp) 84 { 85 filp-private_data leddev; /* 设置私有数据 */ 86 return 0; 87 } 88 89 /* 90 * description : 向设备写数据 91 * param – filp : 设备文件表示打开的文件描述符 92 * param - buf : 要写给设备写入的数据 93 * param - cnt : 要写入的数据长度 94 * param - offt : 相对于文件首地址的偏移 95 * return : 写入的字节数如果为负值表示写入失败 96 */ 97 static ssize_t led_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt) 98 { 99 int retvalue; 100 unsigned char databuf[1]; 101 unsigned char ledstat; 102 103 retvalue copy_from_user(databuf, buf, cnt); 104 if(retvalue 0) { 105 return -EFAULT; 106 } 107 108 ledstat databuf[0]; /* 获取状态值 */ 109 if(ledstat LEDON) { 110 led0_switch(LEDON); /* 打开 LED 灯 */ 111 }else if(ledstat LEDOFF) { 112 led0_switch(LEDOFF); /* 关闭 LED 灯 */ 113 } 114 return 0; 115 } 116 117 /* 设备操作函数 */ 118 static struct file_operations led_fops { 119 .owner THIS_MODULE, 120 .open led_open, 121 .write led_write, 122 }; 以上是传统的字符设备驱动。 124 /* 125 * description : flatform 驱动的 probe 函数当驱动与设备 126 * 匹配以后此函数就会执行 127 * param - dev : platform 设备 128 * return : 0成功;其他负值,失败 129 */ 130 static int led_probe(struct platform_device *dev) 131 { 132 int i 0; 133 int ressize[5]; 134 u32 val 0; 135 struct resource *ledsource[5]; 136 137 printk(led driver and device has matched!\r\n); 138 /* 1、获取资源 */ 139 for (i 0; i 5; i) { 140 ledsource[i] platform_get_resource(dev, IORESOURCE_MEM, i); 141 if (!ledsource[i]) { 142 dev_err(dev-dev, No MEM resource for always on\n); 143 return -ENXIO; 144 } 145 ressize[i] resource_size(ledsource[i]); 146 } 147 148 /* 2、初始化 LED */ 149 /* 寄存器地址映射 */ 150 IMX6U_CCM_CCGR1 ioremap(ledsource[0]-start, ressize[0]); 151 SW_MUX_GPIO1_IO03 ioremap(ledsource[1]-start, ressize[1]); 152 SW_PAD_GPIO1_IO03 ioremap(ledsource[2]-start, ressize[2]); 153 GPIO1_DR ioremap(ledsource[3]-start, ressize[3]); 154 GPIO1_GDIR ioremap(ledsource[4]-start, ressize[4]); 155 156 val readl(IMX6U_CCM_CCGR1); 157 val ~(3 26); /* 清除以前的设置 */ 158 val | (3 26); /* 设置新值 */ 159 writel(val, IMX6U_CCM_CCGR1); 160 161 /* 设置 GPIO1_IO03 复用功能将其复用为 GPIO1_IO03 */ 162 writel(5, SW_MUX_GPIO1_IO03); 163 writel(0x10B0, SW_PAD_GPIO1_IO03); 164 165 /* 设置 GPIO1_IO03 为输出功能 */ 166 val readl(GPIO1_GDIR); 167 val ~(1 3); /* 清除以前的设置 */ 168 val | (1 3); /* 设置为输出 */ 169 writel(val, GPIO1_GDIR); 170 171 /* 默认关闭 LED1 */ 172 val readl(GPIO1_DR); 173 val | (1 3) ; 174 writel(val, GPIO1_DR); 175 176 /* 注册字符设备驱动 */ 177 /*1、创建设备号 */ 178 if (leddev.major) { /* 定义了设备号 */ 179 leddev.devid MKDEV(leddev.major, 0); 180 register_chrdev_region(leddev.devid, LEDDEV_CNT, LEDDEV_NAME); 181 } else { /* 没有定义设备号 */ 182 alloc_chrdev_region(leddev.devid, 0, LEDDEV_CNT, LEDDEV_NAME); 183 leddev.major MAJOR(leddev.devid); 184 } 185 186 /* 2、初始化 cdev */ 187 leddev.cdev.owner THIS_MODULE; 188 cdev_init(leddev.cdev, led_fops); 189 190 /* 3、添加一个 cdev */ 191 cdev_add(leddev.cdev, leddev.devid, LEDDEV_CNT); 192 193 /* 4、创建类 */ 194 leddev.class class_create(THIS_MODULE, LEDDEV_NAME); 195 if (IS_ERR(leddev.class)) { 196 return PTR_ERR(leddev.class); 197 } 198 199 /* 5、创建设备 */ 200 leddev.device device_create(leddev.class, NULL, leddev.devid, NULL, LEDDEV_NAME); 201 if (IS_ERR(leddev.device)) { 202 return PTR_ERR(leddev.device); 203 } 204 205 return 0; 206 } probe 函数当设备和驱动匹配以后此函数就会执行当匹配成功以后会在终端上输出“led driver and device has matched!”这样语句。在 probe 函数里面初始化 LED、注册字符设备驱动。也就是将原来在驱动加载函数里面做的工作全部放到 probe 函数里面完成。 208 /* 209 * description :移除 platform 驱动的时候此函数会执行 210 * param - dev : platform 设备 211 * return : 0成功;其他负值,失败 212 */ 213 static int led_remove(struct platform_device *dev) 214 { 215 iounmap(IMX6U_CCM_CCGR1); 216 iounmap(SW_MUX_GPIO1_IO03); 217 iounmap(SW_PAD_GPIO1_IO03); 218 iounmap(GPIO1_DR); 219 iounmap(GPIO1_GDIR); 220 221 cdev_del(leddev.cdev); /* 删除 cdev */ 222 unregister_chrdev_region(leddev.devid, LEDDEV_CNT); 223 device_destroy(leddev.class, leddev.devid); 224 class_destroy(leddev.class); 225 return 0; 226 } remove 函数当卸载 platform 驱动的时候此函数就会执行。在此函数里面释放内存、注销字符设备等。也就是将原来驱动卸载函数里面的工作全部都放到 remove 函数中完成。 228 /* platform 驱动结构体 */ 229 static struct platform_driver led_driver { 230 .driver { 231 .name imx6ul-led, /* 驱动名字用于和设备匹配 */ 232 }, 233 .probe led_probe, 234 .remove led_remove, 235 }; platform_driver 驱动结构体注意 name 字段为imx6ul-led和我们在leddevice.c 文件里面设置的设备 name 字段一致。 237 /* 238 * description : 驱动模块加载函数 239 * param : 无 240 * return : 无 241 */ 242 static int __init leddriver_init(void) 243 { 244 return platform_driver_register(led_driver); 245 } 驱动模块加载函数在此函数里面通过 platform_driver_register 向 Linux 内核注册 led_driver 驱动。 247 /* 248 * description : 驱动模块卸载函数 249 * param : 无 250 * return : 无 251 */ 252 static void __exit leddriver_exit(void) 253 { 254 platform_driver_unregister(led_driver); 255 } 驱动模块卸载函数在此函数里面通过 platform_driver_unregister 从 Linux 内核卸载 led_driver 驱动。 2、测试APP开发 1 #include stdio.h 2 #include unistd.h 3 #include sys/types.h 4 #include sys/stat.h 5 #include fcntl.h 6 #include stdlib.h 7 #include string.h 8 /*************************************************************** 9 Copyright © ALIENTEK Co., Ltd. 1998-2029. All rights reserved. 10 文件名 : ledApp.c 11 作者 : 左忠凯 12 版本 : V1.0 13 描述 : platform 驱动驱测试 APP。 14 其他 : 无 15 使用方法 ./ledApp /dev/platled 0 关闭 LED 16 ./ledApp /dev/platled 1 打开 LED 17 论坛 : www.openedv.com 18 日志 : 初版 V1.0 2019/8/16 左忠凯创建 19 ***************************************************************/ 20 #define LEDOFF 0 21 #define LEDON 1 22 23 /* 24 * description : main 主程序 25 * param - argc : argv 数组元素个数 26 * param - argv : 具体参数 27 * return : 0 成功;其他 失败 28 */ 29 int main(int argc, char *argv[]) 30 { 31 int fd, retvalue; 32 char *filename; 33 unsigned char databuf[2]; 34 35 if(argc ! 3){ 36 printf(Error Usage!\r\n); 37 return -1; 38 } 39 40 filename argv[1]; 41 /* 打开 led 驱动 */ 42 fd open(filename, O_RDWR); 43 if(fd 0){ 44 printf(file %s open failed!\r\n, argv[1]); 45 return -1; 46 } 47 48 databuf[0] atoi(argv[2]); /* 要执行的操作打开或关闭 */ 49 retvalue write(fd, databuf, sizeof(databuf)); 50 if(retvalue 0){ 51 printf(LED Control Failed!\r\n); 52 close(fd); 53 return -1; 54 } 55 56 retvalue close(fd); /* 关闭文件 */ 57 if(retvalue 0){ 58 printf(file %s close failed!\r\n, argv[1]); 59 return -1; 60 } 61 return 0; 62 } 五、运行测试 1、编译驱动程序和测试APP 4 obj-m : leddevice.o leddriver.o 设置 obj-m 变量的值为“leddevice.o leddriver.o”。 输入如下命令编译出驱动模块文件                 make -j32         编译成功以后就会生成一个名为“leddevice.ko leddriver.ko”的驱动模块文件。 输入如下命令编译测试 ledApp.c 这个测试程序                 arm-linux-gnueabihf-gcc ledApp.c -o ledApp         编译成功以后就会生成 ledApp 这个应用程序。 2、运行测试 depmod //第一次加载驱动的时候需要运行此命令 modprobe leddevice.ko //加载设备模块 modprobe leddriver.ko //加载驱动模块 根文件系统中/sys/bus/platform/目录下保存着当前板子 platform 总线下的设备和驱动其中 devices 子目录为 platform 设备 drivers 子目录为 plartofm 驱动。查看/sys/bus/platform/devices/ 目录看看我们的设备是否存在我们在 leddevice.c 中设置 leddevice(platform_device 类型)的 name 字段为“imx6ul-led”也就是设备名字为 imx6ul-led因此肯定在/sys/bus/platform/devices/ 目录下存在一个名字“imx6ul-led”的文件否则说明我们的设备模块加载失败结果如图 所示 查看/sys/bus/platform/drivers/目录看一下驱动是否存在我们在 leddriver.c 中设置 led_driver (platform_driver 类型)的 name 字段为“imx6ul-led”因此会在/sys/bus/platform/drivers/ 目录下存在名为“imx6ul-led”这个文件结果如图 所示 驱动模块和设备模块加载成功以后 platform 总线就会进行匹配当驱动和设备匹配成功以 后就会输出如图 所示一行语句 驱动和设备匹配成功以后就可以测试 LED 灯驱动了输入如下命令打开 LED 灯 /ledApp /dev/platled 1 //打开 LED 灯 在输入如下命令关闭 LED 灯 ./ledApp /dev/platled 0 //关闭 LED 灯 观察一下 LED 灯能否打开和关闭如果可以的话就说明驱动工作正常如果要卸载驱动的 话输入如下命令即可rmmod leddevice.kormmod leddriver.ko 六、总结 本篇笔记主要学习了platform设备驱动开发的相关概念。将分成两次笔记进行学习。本次笔记主要学习platform设备驱动开发相关的理论知识。主要内容包括Linux驱动的分离与分层、platform平台驱动模型简介。其中驱动的分离与分层有包括驱动的分离、驱动的分层。platform平台驱动模型简介主要包括platform总线、platform驱动与platform设备。 ———————————————— 版权声明本文为CSDN博主「大叔学Linux」的原创文章遵循CC 4.0 BY-SA版权协议转载请附上原文出处链接及本声明。 原文链接https://blog.csdn.net/jiage987450/article/details/134125677         本文为参考正点原子开发板配套教程整理而得仅用于学习交流使用不得用于商业用途。
http://www.sadfv.cn/news/379058/

相关文章:

  • 网站建设方案书 广东python官方下载
  • 域名买完后如何做网站wordpress重新安装如何做
  • 怎么做属于自己的网站做网站的时候旋转图片
  • wordpress 与 微信怎么配合北京网站优化哪家好
  • 多就能自己做网站梅州网站制作
  • 南宁制作网站公司做的网站需要什么技术支持
  • 中文网站做google广告好吗加油卡系统搭建
  • 晚上必看正能量网站短视频改版网站收费
  • 网站如何做ssl认证网络营销的核心是
  • 随州做网站的公司网站建设方案前言
  • 四川网站建设找哪家wordpress验证码代码
  • 关于网站建设的简历模板佛山高端网站建设工作室
  • ps网站导航制作qq网页版手机版
  • html5 特效网站iis 网站绑定域名
  • 网站的访问量统计怎么做东莞网络推广营销公司
  • 竹溪县网站集约化建设邓州网站制作
  • 成都做整站优化技术支持::天空网络-临汾做网站
  • 长沙百度网站推广优化品牌建设 企业要
  • 网站建设方案 规划学校网站建设及管理制度
  • 在线一键建站系统手机网站 微信平台
  • 学校手机网站建设免费自助建站哪个最好
  • 家居企业网站建设方案产品设计的定义
  • 网站建设工作是干什么的桂林最新新闻
  • 怎样建个人网站 步骤西宁网站制作费用是多少钱
  • 甘肃省住房和建设厅网站沈阳铁西做网站公司
  • 罗庄区住房和城乡建设局网站小说网站开发
  • 建设网站怎样做工程项目信息网
  • 天煜科技网站建设ppt模板下载的网站有哪些
  • 文山网站建设报价李宁网站开发ppt模板
  • 环翠区网站建设wordpress的编辑器