完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
Linux驱动
晴空霹雳一阵响,开始写自己的技术博客了。深思熟虑后编写此系列文章记录自己学习过程中遇到的问题和今后复习所用。Linux驱动IO输出高低电平和单片机类似,也是通过控制寄存器控制高低电平,不过在linux中就进行了分层。将程序分成了驱动和应用层程序,驱动负责底层操作和控制,应用层负责逻辑,侧重于怎么使用。驱动在驱动层将控制的接口写好,注册驱动时将IO口寄存器进行配置。应用层直接操作设备节点,使用文件IO控制LED灯。 基本步骤: 1、 开发环境介绍:迅为开发板:iTop4412,Ubuntu14 2、 查看芯片的技术手册,确定LED连接的IO口控制寄存器。 3、 编写驱动代码。 4、 编写应用代码。 5、 编写Makefile文件,编译驱动程序和应用程序。 6、 导入板子运行测试。 1、电路图如下: 通过查询官方给出的技术手册和硬件电路连接图可知具体的寄存器如下: LED2配置寄存器和数据寄存器 LED3配置寄存器和数据寄存器 2、编写驱动代码: #include 《linux/init.h》 #include 《linux/module.h》 #include 《linux/fs.h》 #include 《linux/device.h》 #include 《linux/uaccess.h》 #include 《asm/io.h》 //LED2 #define CPX2_CON 0x11000100 #define GPX2_SIZE 2 //LED3 #define CPX3_CON 0x11000060 #define GPX3_SIZE 2 //指针存放虚拟地址 volatile unsigned long *gpx2conf; volatile unsigned long *gpx2dat; volatile unsigned long *gpx3conf; volatile unsigned long *gpx3dat; static unsigned int dev_major = 125; static struct class *devcls; static struct device *dev; static int kernel_val = 555; int chr_dev_open(struct inode *inode,struct file *filp) { printk(“******dev %s***********n”,__FUNCTION__); return 0; } //read(fd,buffer,size); //fd --》 filp //buffer --》 buffer //size --》 count //必须通过copy_to_user进行传递数据。 ssize_t chr_dev_read(struct file *filp, char __user *buffer,size_t count,loff_t *fpos) { int ret = copy_to_user(buffer,&kernel_val,count); printk(“******%s**********n”,__FUNCTION__); if(ret 》 0){ printk(“ copy_to_user error ret:%dn”,ret); return -EFAULT; } return 0; } ssize_t chr_dev_write(struct file *filp, const char __user *buffer,unsigned int count ,loff_t *fpos) { int value; int ret = copy_from_user(&value,buffer,count); if(ret 》 0){ printk(“ copy_from_user error ret:%dn”,ret); return -EFAULT; } printk(“******%s*********n”,__FUNCTION__); printk(“ value = %dn”,value); if(value){ *gpx2dat |= 0x01; //led2点灯 *gpx3dat |= 0x02; //led3点灯 }else{ *gpx2dat &= ~(0x01); //led2灭灯 *gpx3dat &= ~(0x02);//led3灭灯 } return 0; } int chr_dev_close(struct inode *inode,struct file *filp) { printk(“******%s*********n”,__FUNCTION__); return 0; } const struct file_operations my_fops = { .open = chr_dev_open, .read = chr_dev_read, .write = chr_dev_write, .release = chr_dev_close, }; static int __init chr_dev_init(void) { //申请设备号 int ret; ret = register_chrdev(dev_major,“chr_dev_test”,&my_fops); if(ret == 0){ printk(“register okn”); }else{ printk(“register failedn”); return -EINVAL; } // /dev/chr2 创建类 devcls = class_create(THIS_MODULE,“chr_dev_test”); if(devcls != NULL){ printk(“register class ok!n”); }else { printk(“register class faild!n”); } //创建设备节点 以device_create()最后一个参数为准。 dev = device_create(devcls,NULL,MKDEV(dev_major,0),NULL,“chr_dev_cls2”); if(dev != NULL){ printk(“register dev okn”); }else{ printk(“register dev failedn”); } //LED2 地址映射。 gpx2conf = ioremap(CPX2_CON,GPX2_SIZE); gpx2dat = gpx2conf + 1; //LED3 gpx3conf = ioremap(CPX3_CON,GPX3_SIZE); gpx3dat = gpx3conf +1; //LED2配置 *gpx2conf &= ~(0xFF); *gpx2conf |= (0x1); //LED3 配置 *gpx3conf &= ~(0xFF); *gpx3conf |= (0x10); return 0; } static void __exit chr_dev_exit(void) { //一般释放资源 //和注册时顺序相反 iounmap(gpx3conf); iounmap(gpx2conf); device_destroy(devcls,MKDEV(dev_major,0)); class_destroy(devcls); unregister_chrdev(dev_major,“chr_dev_cls2”); printk(“*************chr_dev_exit OK!********n”); } module_init(chr_dev_init); module_exit(chr_dev_exit); MODULE_LICENSE(“GPL”); 驱动的Makefile编写: KERN_DIR = /home/usr/iTop4412_Kernel_3.0 obj-m +=chr_dev.o all: make -C $(KERN_DIR) M=$(PWD) modules clean: make -C $(KERN_DIR) M=$(PWD) modules clean rm -rf modules.order 应用层程序编写: #include 《fcntl.h》 #include 《unistd.h》 #include 《string.h》 #include 《stdlib.h》 #include 《stdio.h》 #include 《sys/types.h》 #include 《sys/stat.h》 int main(int argc,char *argv[]) { int fd = open(“/dev/chr_dev_cls2”,O_RDWR); //路径和驱动设备节点名字保持一致 int value = 0; if(fd 《 0){ perror(“open failed”); exit(0); } read(fd,&value,4); printf(“__USER__ value : %dn”,value); //重新给value赋值 value = 666; write(fd,&value,4); while(1) { value = 0; write(fd,&value,4); sleep(1); value = 1; write(fd,&value,4); sleep(1); } close(fd); return 0; } 3、将编译好的驱动程序和引用程序在arm上运行 |
|
|
|
只有小组成员才能发言,加入小组>>
4345个成员聚集在这个小组
加入小组3287 浏览 0 评论
航顺(HK)联合电子发烧友推出“近距离体验高性能Cortex-M3,免费申请价值288元评估板
4232 浏览 1 评论
4238 浏览 0 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 00:49 , Processed in 0.662859 second(s), Total 73, Slave 58 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号