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

网站侧边栏菜单广东平台网站建设制作

网站侧边栏菜单,广东平台网站建设制作,做app 的模板下载网站,wordpress灰色产业5.2.16.静态映射操作LED3 5.2.16.1、添加驱动中的写函数 (1)先定义好应用和驱动之间的控制接口#xff0c;这个是由自己来定义的。譬如定义为#xff1a;应用向驱动写on则驱动让LED亮#xff0c;应用向驱动写off#xff0c;驱动就让LED灭 1. 驱动文…5.2.16.静态映射操作LED3 5.2.16.1、添加驱动中的写函数 (1)先定义好应用和驱动之间的控制接口这个是由自己来定义的。譬如定义为应用向驱动写on则驱动让LED亮应用向驱动写off驱动就让LED灭 1. 驱动文件 module_test.c #include linux/module.h // module_init module_exit #include linux/init.h // __init __exit #include linux/fs.h #include asm/uaccess.h //copy_from_user #include linux/errno.h // 错误码 #include mach/regs-gpio.h//arch/arm/mach-s5pv210/include/mach/regs-gpio.h 这两个顺序不能放错c语言基础 #include mach/gpio-bank.h //arch/arm/mach-s5pv210/include/mach/gpio-bank.h #include linux/string.h//包含 内核的 memset 、strcmp#define MYMAJOR 200 /* 定义 register_chrdev 注册设备的 主设备号 */#define MYNAME test_char /* 定义 register_chrdev 注册设备的 设备名字 */#define GPJ0CON S5PV210_GPJ0CON // FD500240 虚拟地址 #define GPJ0DAT S5PV210_GPJ0DAT // FD500244#define rGPJ0CON *((volatile unsigned int *)GPJ0CON) #define rGPJ0DAT *((volatile unsigned int *)GPJ0DAT)int mymajor; /* 定义 register_chrdev 注册设备号*/char kbuf[100];/* 内核空间的 buf*//* NOTE 自己定义函数指针 test_chrdev_open */ static int test_chrdev_open(struct inode *inode, struct file *file) {/* 这个函数中真正应该 放置 打开这个硬件设备的 操作代码 ,我们先 printk 代替一下 */printk(KERN_INFO test_chrdev_open module_test.c-test_chrdev_open \n); /* 在应用app.c 执行open 时就会执行 LED亮 */rGPJ0CON 0x11111111;//rGPJ0DAT ((03)|(04)|(05)); //LED亮return 0;} /* test_chrdev_open() *//* NOTE 自己定义函数指针 test_chrdev_release , release对应的就是 close */ static int test_chrdev_release(struct inode *inode, struct file *file) {printk(KERN_INFO test_chrdev_release module_test.c-test_chrdev_release \n);/* 在应用app.c 执行close 时就会执行 LED灭 */rGPJ0DAT ((13)|(14)|(15)); //LED灭return 0; }static ssize_t test_chrdev_read(struct file *file, char __user *ubuf, size_t size, loff_t *ppos) {int ret -1;printk(KERN_INFO test_chrdev_release module_test.c-test_chrdev_read \n);/* 从内核 的 kbuf 复制到用户的 ubuf */ret copy_to_user(ubuf,kbuf,size); /* 成功后 就会拷贝到用户 ubuf */if(ret) /* 如果 不成功复制则返回尚未成功复制剩下的字节数, 这里 就不做 纠错 机制了 */{printk(KERN_ERR copy_to_user fail \n); return -EINVAL;}printk(KERN_INFO copy_to_user OK!!! module_test.c-test_chrdev_write\n);return 0; }// 写函数的本质将应用层 传递过来的数据先 复制到 内核中然后将之正确的方式写入硬件完成的操作数据从应用层到驱动层的复制 // 内核有一个 虚拟地址空间应用层有一个 虚拟地址空间 static ssize_t test_chrdev_write(struct file *file, const char __user *user_buf,size_t count, loff_t *ppos) {int ret -1;printk(KERN_INFO test_chrdev_release module_test.c-test_chrdev_write\n);memset(kbuf,0,sizeof(kbuf)); /*清除kbuf *///使用改函数将: 应用层传过来的 ubuf 中的内容 拷贝到驱动空间中的 一个 kbuf 中/* 不能用memcpy(kbuf,buf); 因为 2 个 不在一个地址空间中不能 比较 霍元甲和成龙 谁更厉害 不在一个年龄段*/ret copy_from_user(kbuf,user_buf,count); /* 成功后 就会 放到 kbuf 中 */if(ret) /* 如果 不成功复制则返回尚未成功复制剩下的字节数, 这里 就不做 纠错 机制了 */{printk(KERN_ERR copy_from_user fail \n); return -EINVAL;}printk(KERN_INFO copy_from_user OK!!! module_test.c-test_chrdev_write\n);/* 真正的 驱动的 数据从 应用层 复制 到 驱动中后我们就要根据这个数据去写硬件的操作所以下面就应该操作硬件 */if (!strcmp(kbuf,on)) /*strcmp相等的话应该是 0 */{rGPJ0DAT ((03)|(04)|(05)); //LED亮}else if(!strcmp(kbuf,off)) {rGPJ0DAT ((13)|(14)|(15)); //LED灭}return 0; }//自定义 file_operations 结构体 及其元素填充 /* NOTE 定义 register_chrdev 注册设备的 设备结构体 test_fops */ static const struct file_operations test_fops {.owner THIS_MODULE, /* 所有的驱动 代码这一行不需要动所有的都是这样不是函数指针, 惯例直接写即可 */.open test_chrdev_open, /* 将来应用 open 打开这个设备时实际 调用的就是这个 .open 函数指针*/.release test_chrdev_release, /* release对应的就是 close 函数指针 */.write test_chrdev_write, .read test_chrdev_read, };// 模块安装函数 static int __init chrdev_init(void) { //int ret -1; /* 定义 register_chrdev 的返回值 */printk(KERN_INFO chrdev_init helloworld init\n);// 在 module_init 宏 调用函数中去注册字符串 设备驱动mymajor register_chrdev(0, test_char, test_fops); /* major设成0内核帮我们自动分配空白的设备号分配的值会 做返回值 负数还是返回失败 */if(mymajor 0){printk(KERN_ERR registe_chrdev fail \n);return -EINVAL; /* 返回一个错误码 需要加 ’-‘负号*/}printk(KERN_INFO 自动分配 register_chrdev success....mymajor %d \n,mymajor); #if 0 /* 现在把 硬件操作放到这里不用操作app.c 就可以操作硬件 */rGPJ0CON 0x11111111;rGPJ0DAT ((03)|(04)|(05)); //LED亮printk(KERN_INFO S5PV210_GPJ0CON %p \n,S5PV210_GPJ0CON);printk(KERN_INFO S5PV210_GPJ0DAT %p \n,S5PV210_GPJ0DAT ); #endif return 0; }// 模块卸载函数 static void __exit chrdev_exit(void) {printk(KERN_INFO chrdev_exit helloworld exit\n);// 在 module_exit宏 调用函数中去注销 字符串 设备驱动unregister_chrdev(mymajor, test_char); /* 这里不判断返回值 了一般不会出错 */ #if 0 // 模块卸载 LED灭rGPJ0DAT ((13)|(14)|(15)); //LED灭 #endif }module_init(chrdev_init); module_exit(chrdev_exit);// MODULE_xxx这种宏作用是用来添加模块描述信息 MODULE_LICENSE(GPL); // 描述模块的许可证 MODULE_AUTHOR(aston); // 描述模块的作者 MODULE_DESCRIPTION(module test); // 描述模块的介绍信息 MODULE_ALIAS(alias xxx); // 描述模块的别名信息/*********************************************************** 如果 KERN_DEBUG 打印不出来更改打印级别 或者 printk(KERN_DEBUG chrdev_init helloworld init\n); [rootliang_x210 driver_test]# cat /proc/sys/kernel/printk 7 4 1 7 [rootliang_x210 driver_test]# echo 8 /proc/sys/kernel/printk [rootliang_x210 driver_test]# cat /proc/sys/kernel/printk 8 4 1 7************************************************************/ 2. app.cMkfile无更改 #include stdio.h #include sys/types.h #include sys/stat.h #include fcntl.h#define FILE /dev/test // 刚才mknod创建的设备文件 名必须保持一致char buf[100];int main(void) {int fd -1;fd open(FILE, O_RDWR);if(fd 0){printf(open %s error \n,FILE);return -1;}printf(open %s success..\n,FILE);//读写文件write(fd,on,2);sleep(2);write(fd,off,3);sleep(2);write(fd,on,2);sleep(2);write(fd,off,3);sleep(2);//关闭文件close(fd);return 0; } 运行效果 上面的代码可以正常运行但是实际开发中一般驱动中只要可以实现简单功能更多的功能代码都放到 app.c 看下面的示例 (2)应用和驱动的接口定义做的尽量简单譬如用1个字目来表示。譬如定义为应用写1字符串表示灯亮写0表示让灯灭。 5.2.16.2、写应用来测试写函数 5.2.16.3、驱动和应用中来添加读功能 1. 驱动文件 module_test.c #include linux/module.h // module_init module_exit #include linux/init.h // __init __exit #include linux/fs.h #include asm/uaccess.h //copy_from_user #include linux/errno.h // 错误码 #include mach/regs-gpio.h//arch/arm/mach-s5pv210/include/mach/regs-gpio.h 这两个顺序不能放错c语言基础 #include mach/gpio-bank.h //arch/arm/mach-s5pv210/include/mach/gpio-bank.h #include linux/string.h//包含 内核的 memset 、strcmp#define MYMAJOR 200 /* 定义 register_chrdev 注册设备的 主设备号 */#define MYNAME test_char /* 定义 register_chrdev 注册设备的 设备名字 */#define GPJ0CON S5PV210_GPJ0CON // FD500240 虚拟地址 #define GPJ0DAT S5PV210_GPJ0DAT // FD500244#define rGPJ0CON *((volatile unsigned int *)GPJ0CON) #define rGPJ0DAT *((volatile unsigned int *)GPJ0DAT)int mymajor; /* 定义 register_chrdev 注册设备号*/char kbuf[100];/* 内核空间的 buf*//* NOTE 自己定义函数指针 test_chrdev_open */ static int test_chrdev_open(struct inode *inode, struct file *file) {/* 这个函数中真正应该 放置 打开这个硬件设备的 操作代码 ,我们先 printk 代替一下 */printk(KERN_INFO test_chrdev_open module_test.c-test_chrdev_open \n); /* 在应用app.c 执行open 时就会执行 LED */rGPJ0CON 0x11111111;//rGPJ0DAT ((03)|(04)|(05)); //LED亮return 0;} /* test_chrdev_open() *//* NOTE 自己定义函数指针 test_chrdev_release , release对应的就是 close */ static int test_chrdev_release(struct inode *inode, struct file *file) {printk(KERN_INFO test_chrdev_release module_test.c-test_chrdev_release \n);/* 在应用app.c 执行close 时就会执行 LED灭 */rGPJ0DAT ((13)|(14)|(15)); //LED灭return 0; }static ssize_t test_chrdev_read(struct file *file, char __user *ubuf, size_t size, loff_t *ppos) {int ret -1;printk(KERN_INFO test_chrdev_release module_test.c-test_chrdev_read \n);/* 从内核 的 kbuf 复制到用户的 ubuf */ret copy_to_user(ubuf,kbuf,size); /* 成功后 就会拷贝到用户 ubuf */if(ret) /* 如果 不成功复制则返回尚未成功复制剩下的字节数, 这里 就不做 纠错 机制了 */{printk(KERN_ERR copy_to_user fail \n); return -EINVAL;}printk(KERN_INFO copy_to_user OK!!! module_test.c-test_chrdev_write\n);return 0; }// 写函数的本质将应用层 传递过来的数据先 复制到 内核中然后将之正确的方式写入硬件完成的操作数据从应用层到驱动层的复制 // 内核有一个 虚拟地址空间应用层有一个 虚拟地址空间 static ssize_t test_chrdev_write(struct file *file, const char __user *user_buf,size_t count, loff_t *ppos) {int ret -1;printk(KERN_INFO test_chrdev_release module_test.c-test_chrdev_write\n);memset(kbuf,0,sizeof(kbuf)); /*清除kbuf *///使用改函数将: 应用层传过来的 ubuf 中的内容 拷贝到驱动空间中的 一个 kbuf 中/* 不能用memcpy(kbuf,buf); 因为 2 个 不在一个地址空间中不能 比较 霍元甲和成龙 谁更厉害 不在一个年龄段*/ret copy_from_user(kbuf,user_buf,count); /* 成功后 就会 放到 kbuf 中 */if(ret) /* 如果 不成功复制则返回尚未成功复制剩下的字节数, 这里 就不做 纠错 机制了 */{printk(KERN_ERR copy_from_user fail \n); return -EINVAL;}printk(KERN_INFO copy_from_user OK!!! module_test.c-test_chrdev_write\n);/* 真正的 驱动的 数据从 应用层 复制 到 驱动中后我们就要根据这个数据去写硬件的操作所以下面就应该操作硬件 */if(kbuf[0] 1){rGPJ0DAT ((03)|(04)|(05)); //LED亮}else if (kbuf[0]0){rGPJ0DAT ((13)|(14)|(15)); //LED灭}return 0; }//自定义 file_operations 结构体 及其元素填充 /* NOTE 定义 register_chrdev 注册设备的 设备结构体 test_fops */ static const struct file_operations test_fops {.owner THIS_MODULE, /* 所有的驱动 代码这一行不需要动所有的都是这样不是函数指针, 惯例直接写即可 */.open test_chrdev_open, /* 将来应用 open 打开这个设备时实际 调用的就是这个 .open 函数指针*/.release test_chrdev_release, /* release对应的就是 close 函数指针 */.write test_chrdev_write, .read test_chrdev_read, };// 模块安装函数 static int __init chrdev_init(void) { //int ret -1; /* 定义 register_chrdev 的返回值 */printk(KERN_INFO chrdev_init helloworld init\n);// 在 module_init 宏 调用函数中去注册字符串 设备驱动mymajor register_chrdev(0, test_char, test_fops); /* major设成0内核帮我们自动分配空白的设备号分配的值会 做返回值 负数还是返回失败 */if(mymajor 0){printk(KERN_ERR registe_chrdev fail \n);return -EINVAL; /* 返回一个错误码 需要加 ’-‘负号*/}printk(KERN_INFO 自动分配 register_chrdev success....mymajor %d \n,mymajor); #if 0 /* 现在把 硬件操作放到这里不用操作app.c 就可以操作硬件 */rGPJ0CON 0x11111111;rGPJ0DAT ((03)|(04)|(05)); //LED亮printk(KERN_INFO S5PV210_GPJ0CON %p \n,S5PV210_GPJ0CON);printk(KERN_INFO S5PV210_GPJ0DAT %p \n,S5PV210_GPJ0DAT ); #endif return 0; }// 模块卸载函数 static void __exit chrdev_exit(void) {printk(KERN_INFO chrdev_exit helloworld exit\n);// 在 module_exit宏 调用函数中去注销 字符串 设备驱动unregister_chrdev(mymajor, test_char); /* 这里不判断返回值 了一般不会出错 */ #if 0 // 模块卸载 LED灭rGPJ0DAT ((13)|(14)|(15)); //LED灭 #endif }module_init(chrdev_init); module_exit(chrdev_exit);// MODULE_xxx这种宏作用是用来添加模块描述信息 MODULE_LICENSE(GPL); // 描述模块的许可证 MODULE_AUTHOR(aston); // 描述模块的作者 MODULE_DESCRIPTION(module test); // 描述模块的介绍信息 MODULE_ALIAS(alias xxx); // 描述模块的别名信息/*********************************************************** 如果 KERN_DEBUG 打印不出来更改打印级别 或者 printk(KERN_DEBUG chrdev_init helloworld init\n); [rootliang_x210 driver_test]# cat /proc/sys/kernel/printk 7 4 1 7 [rootliang_x210 driver_test]# echo 8 /proc/sys/kernel/printk [rootliang_x210 driver_test]# cat /proc/sys/kernel/printk 8 4 1 7************************************************************/ 2. app.c #include stdio.h #include sys/types.h #include sys/stat.h #include fcntl.h #include string.h#define FILE /dev/test // 刚才mknod创建的设备文件 名必须保持一致char buf[100];int main(void) {int fd -1;int i 0;fd open(FILE, O_RDWR);if(fd 0){printf(open %s error \n,FILE);return -1;}printf(open %s success..\n,FILE); #if 0//璇诲啓鏂囦欢write(fd, 1,1);//亮sleep(2);write(fd, 0,1);//灭sleep(2);write(fd, 1,1);sleep(2); #endifwhile(1){memset(buf, 0, sizeof(buf));printf(请输入 on|off \n\n);scanf(%s,buf);if (!strcmp(buf,on)){write(fd, 1,1);//亮}else if (!strcmp(buf,off)) {write(fd, 0,1);//灭} else if (!strcmp(buf,flash)) { for(i0;i3;i){write(fd, 1,1);//亮sleep(2);write(fd, 0,1);//灭sleep(2);}}else if (!strcmp(buf,quit)) {break;}}//鍏抽棴鏂囦欢close(fd);return 0; } 3.Mkfile无更改 #ubuntu的内核源码树如果要编译在ubuntu中安装的模块就打开这2个 #KERN_VER $(shell uname -r) #KERN_DIR /lib/modules/$(KERN_VER)/build # 开发板的linux内核的源码树目录 KERN_DIR /root/driver/kernelobj-m module_test.oall:make -C $(KERN_DIR) Mpwd modules # app 是在 开发板运行 所以 arm-linux-gcc arm-linux-gcc app.c -o app cp:cp *.ko app /root/rootfs/rootfs/driver_test#cp app /root/rootfs/rootfs/driver_test .PHONY: clean clean:rm -rf app make -C $(KERN_DIR) Mpwd modules clean 运行效果
http://www.sadfv.cn/news/4275/

相关文章:

  • 大朗镇仿做网站网站如何做好优化
  • 大学生可做的网站主题WordPress安装jetpack
  • 网站被人做跳转mg线上注册
  • 做公众号的网站模板下载涿州做网站的公司
  • 企业网站设计分析济南官网seo技术厂家
  • 网站 类库jsp网站开发 开题依据
  • wordpress博客网站多少钱推盟
  • 自己做优惠券网站网站建设比较好的公司
  • 兰州网站建设lzwlxc重庆妇科医院在线咨询
  • 义乌网站建设微信开发wordpress手机导航栏设置
  • 图书信息管理系统代码网站建设论坛企业推广
  • 企业网站网页布局代写简历哪个平台比较好
  • 响应式网站代码超市会员管理系统
  • 建设网站包括哪些什么网站的新闻做参考文献
  • 销售网站开发网页版qq登录网址
  • 成都网站建设好多钱邯郸信息港最新招聘信息2023
  • 建筑之家宁波网站seo哪家好
  • 网站建设动画教程网站与个人网站
  • 涞源网站建设模板网站建设
  • 湖北省网站建设caddy搭建wordpress
  • 为什么后台编辑内容和网站上面显示的内容不一致百度海外视频网站建设
  • 汕头网站设计公司做网站卖东西赚钱么
  • 临沂兰山建设局网站如何看出网站是用wordpress搭建
  • 网站美工建设意见广州网站开发小程序
  • 建网站多少钱网站备案号显示红色
  • 深圳网站建设 外包合作拼多多网站的类型
  • 柳州企业网站开发公司apache搭建网站
  • 阳山网站建设深圳手机集团网站建设
  • 风景名胜区建设部网站哪些网站可以做翻译兼职
  • wordpress分类二级域名seo内部优化