博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UIO 示例
阅读量:6986 次
发布时间:2019-06-27

本文共 6424 字,大约阅读时间需要 21 分钟。

hot3.png

用户空间代码:

#include 
#include
#include
#include
#include
#include
#define UIO_DEV "/dev/uio0"#define UIO_ADDR "/sys/class/uio/uio0/maps/map0/addr"#define UIO_SIZE "/sys/class/uio/uio0/maps/map0/size"#define UIO_ADDR1 "/sys/class/uio/uio0/maps/map1/addr"#define UIO_SIZE1 "/sys/class/uio/uio0/maps/map1/size"#define LED_ON 1 //LED亮状态#define LED_OFF 0 //LED灭状态 static char uio_addr_buf[16], uio_size_buf[16];int main(int argc, char **argv){ int uio_fd, addr_fd, size_fd, addr_fd_1, size_fd_1; int uio_size, uio_size_1; void *uio_addr, *uio_addr_1, *access_address, *access_address_1; volatile unsigned long virt, virt_1; volatile unsigned long *GPBCON, *GPBDAT, *GPBUP, *RETVAL; unsigned long pagesz; int turn, index; uio_fd = open(UIO_DEV,O_RDWR); addr_fd = open(UIO_ADDR, O_RDONLY); size_fd = open(UIO_SIZE, O_RDONLY); addr_fd_1 = open(UIO_ADDR1, O_RDONLY); size_fd_1 = open(UIO_SIZE1, O_RDONLY); if(addr_fd < 0 || size_fd < 0 || uio_fd < 0 || addr_fd_1 < 0 || size_fd_1 < 0) { fprintf(stderr, "mmap: %s\n", strerror(errno)); exit(-1); } read(addr_fd, uio_addr_buf, sizeof(uio_addr_buf)); read(size_fd, uio_size_buf, sizeof(uio_size_buf)); uio_addr = (void*)strtoul(uio_addr_buf, NULL, 0); uio_size = (int)strtol(uio_size_buf, NULL, 0); read(addr_fd_1, uio_addr_buf, sizeof(uio_addr_buf)); read(size_fd_1, uio_size_buf, sizeof(uio_size_buf)); uio_addr_1 = (void*)strtoul(uio_addr_buf, NULL, 0); uio_size_1 = (int)strtol(uio_size_buf, NULL, 0); access_address = mmap(NULL, uio_size, PROT_READ | PROT_WRITE, MAP_SHARED, uio_fd, 0); access_address_1 = mmap(NULL, uio_size_1, PROT_READ | PROT_WRITE, MAP_SHARED, uio_fd, getpagesize()); if (access_address == (void*) -1 || access_address_1 == (void*) -1) { fprintf(stderr, "mmap: %s\n", strerror(errno)); exit(-1); } printf("The device address %p (lenth %d)\ncan be accessed over\nlogical address %p\n\n", uio_addr, uio_size, access_address); pagesz = getpagesize(); virt = (unsigned long)uio_addr; virt = ((unsigned long)access_address + (virt & (pagesz - 1))); virt_1 = (unsigned long)uio_addr_1; virt_1 = ((unsigned long)access_address_1 + (virt_1 & (pagesz - 1))); GPBCON = (unsigned long *)(virt + 0x00); GPBDAT = (unsigned long *)(virt + 0x04); GPBUP = (unsigned long *)(virt + 0x08); RETVAL = (unsigned long *)virt_1; int retval = (int)(*RETVAL); printf("GPBCON %p \n" "GPBDAT %p \n" "GPBUP %p \n\n", GPBCON, GPBDAT, GPBUP); printf("retval ==============> %d \n", retval); // GPBCON if(*GPBCON != 0x154FD) *GPBCON = 0x154FD; // GPBDAT close all leds *GPBDAT = 0x1E0; // open all leds //*GPBDAT = 0x00; // GPBUP if(*GPBUP != 0x7FF) *GPBUP = 0x7FF; fd_set rd_fds, tmp_fds; /*************************** while (1) { // 清空文件描述符集合 FD_ZERO(&rd_fds); FD_SET(uio_fd, &rd_fds); tmp_fds = rd_fds; // 以阻塞的方式等待 tmp_fds(此处为读取数据文件描述集合)中读取数据事件的发生 // 此方法会清除掉没有事件发生的相文件应描述符位 // ret 待处理事件总数 int ret = select(uio_fd+1, &tmp_fds, NULL, NULL, NULL); if (ret > 0) { // 检测读管道文件描述符是否存储在tmp_fds中 // 检测此文件描述符中是否有事件发生 if (FD_ISSET(uio_fd, &tmp_fds)) { int c; read(uio_fd, &c, sizeof(int)); retval = (int)(*RETVAL); printf("current event count is: %d \n", c); printf("current return value is: %d \n", retval); } } if(retval == 10) break; } **********************************/ close(uio_fd); return 0;}

 

内核空间代码:

#include 
#include
#include
#include
#include
/* kmalloc, kfree */#include
/* IRQ_TYPE_EDGE_BOTH */static irqreturn_t my_interrupt(int irq, void *dev_id){ struct uio_info *info = (struct uio_info *)dev_id; unsigned long *ret_val_add = (unsigned long *)(info->mem[1].addr); *ret_val_add = 10; printk("----------------------------------------------------%d \n" ,(int)(*ret_val_add)); return IRQ_RETVAL(IRQ_HANDLED);}struct uio_info kpart_info = { .name = "kpart", .version = "0.1", .irq = IRQ_EINT19, .handler = my_interrupt, .irq_flags = IRQ_TYPE_EDGE_RISING,};struct button_irq_desc { int irq; int num; char *name; }; static struct button_irq_desc button_irqs [] = { {IRQ_EINT8 , 1, "KEY0"}, {IRQ_EINT11, 2, "KEY1"}, {IRQ_EINT13, 3, "KEY2"}, {IRQ_EINT14, 4, "KEY3"}, {IRQ_EINT15, 5, "KEY4"},}; static int drv_kpart_probe(struct device *dev);static int drv_kpart_remove(struct device *dev);static struct device_driver uio_dummy_driver = { .name = "kpart", .bus = &platform_bus_type, .probe = drv_kpart_probe, .remove = drv_kpart_remove,};static irqreturn_t buttons_interrupt(int irq, void *dev_id){ struct button_irq_desc *button_irqs = (struct button_irq_desc *)dev_id; unsigned long *ret_val_add = (unsigned long *)(kpart_info.mem[1].addr); *ret_val_add = button_irqs->num; printk("%s is being pressed ..... \n", button_irqs->name); uio_event_notify(&kpart_info); return IRQ_RETVAL(IRQ_HANDLED);} static int drv_kpart_probe(struct device *dev){ printk("drv_kpart_probe(%p)\n", dev); unsigned long phys = 0x56000010; // 0x56000010 = GPBCON kpart_info.mem[0].addr = phys; kpart_info.mem[0].memtype = UIO_MEM_PHYS; kpart_info.mem[0].size = 12; kpart_info.mem[1].addr = (unsigned long)kmalloc(4,GFP_KERNEL);; if(kpart_info.mem[1].addr == 0) return -ENOMEM; kpart_info.mem[1].memtype = UIO_MEM_LOGICAL; kpart_info.mem[1].size = 4; unsigned long *ret_val_add = (unsigned long *)(kpart_info.mem[1].addr); *ret_val_add = 999; if(uio_register_device(dev, &kpart_info)){ kfree((void *)kpart_info.mem[1].addr); return -ENODEV; } int i = 0 ,err = 0; for (i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++) { err = request_irq(button_irqs[i].irq, buttons_interrupt, IRQ_TYPE_EDGE_RISING, button_irqs[i].name, (void *)&button_irqs[i]); if (err) break; } return 0;} static int drv_kpart_remove(struct device *dev){ kfree((void *)kpart_info.mem[1].addr); uio_unregister_device(&kpart_info); return 0;}static struct platform_device * uio_dummy_device;static int __init uio_kpart_init(void){ printk("Hello, Mini2440 module is installed !\n"); uio_dummy_device = platform_device_register_simple("kpart", -1, NULL, 0); return driver_register(&uio_dummy_driver);}static void __exit uio_kpart_exit(void){ platform_device_unregister(uio_dummy_device); driver_unregister(&uio_dummy_driver);}module_init(uio_kpart_init);module_exit(uio_kpart_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("Benedikt Spranger");MODULE_DESCRIPTION("UIO dummy driver");

 

转载于:https://my.oschina.net/hanshubo/blog/796838

你可能感兴趣的文章
iOS开发网络篇—网络请求(HTTP协议)小结(转)
查看>>
navicate连接Linux下mysql慢,卡,以及mysql相关查询,授权
查看>>
Unity 各平台中的路径
查看>>
New Concept English three(21)
查看>>
试卷考试
查看>>
六大赚钱定律,让你赚大钱
查看>>
手写ORM入门篇(一)
查看>>
每天读5分钟,受益匪浅、
查看>>
HTTP学习笔记:HTTP的消息结构
查看>>
queue POJ 2259 Team Queue
查看>>
Codeforces Round #345 (Div. 2)
查看>>
java数组-如何在一堆数据中使用数组!
查看>>
BZOJ5286:[HNOI/AHOI2018]转盘——题解
查看>>
37.Intellij IDEA解决GBK乱码
查看>>
Go语言的多态(Polymorphism)
查看>>
Struts2--DomainModel接收参数---使用广泛!!!
查看>>
如何用cocoapods 来管理项目中的第三方框架?
查看>>
手工成本维护不可以将成本改为零
查看>>
运算符优先级
查看>>
请教 Discuz syscache 中一段cache 的意思
查看>>