AUTHOR: Joseph Yang (杨红刚) <[email protected]>
CONTENT: uio驱动编写 实例1
NOTE: linux-3.0
LAST MODIFIED:09-06-2011
-----------------------------------------------------------------------------------------------------------
Distributed and Embedded System Lab (分布式嵌入式系统实验室,兰州大学)
===============================================================
怎么编写uio驱动详解
======================---------- simple.c -------------
/** * This is a simple demon of uio driver. * Last modified by 09-05-2011 Joseph Yang(Yang Honggang)<[email protected]> * * Compile: * Save this file name it simple.c * # echo "obj-m := simple.o" > Makefile * # make -Wall -C /lib/modules/`uname -r`/build M=`pwd` modules * Load the module: * #modprobe uio * #insmod simple.ko */ #include <linux/module.h> #include <linux/platform_device.h> #include <linux/uio_driver.h> #include <linux/slab.h> /* kmalloc, kfree */ struct uio_info kpart_info = { .name = "kpart", .version = "0.1", .irq = UIO_IRQ_NONE, }; 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 int drv_kpart_probe(struct device *dev) { printk("drv_kpart_probe( %p)\n", dev); kpart_info.mem[0].addr = (unsigned long)kmalloc(1024,GFP_KERNEL); if(kpart_info.mem[0].addr == 0) return -ENOMEM; kpart_info.mem[0].memtype = UIO_MEM_LOGICAL; kpart_info.mem[0].size = 1024; if( uio_register_device(dev, &kpart_info)) return -ENODEV; return 0; } static int drv_kpart_remove(struct device *dev) { uio_unregister_device(&kpart_info); return 0; } static struct platform_device * uio_dummy_device; static int __init uio_kpart_init(void) { 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");
#include <stdio.h> #include <fcntl.h> #include <stdlib.h> #include <unistd.h> #include <sys/mman.h> #include <errno.h> #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" static char uio_addr_buf[16], uio_size_buf[16]; int main(void) { int uio_fd, addr_fd, size_fd; int uio_size; void* uio_addr, *access_address; uio_fd = open(UIO_DEV, /*O_RDONLY*/O_RDWR); addr_fd = open(UIO_ADDR, O_RDONLY); size_fd = open(UIO_SIZE, O_RDONLY); if( addr_fd < 0 || size_fd < 0 || uio_fd < 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); access_address = mmap(NULL, uio_size, PROT_READ | PROT_WRITE, MAP_SHARED, uio_fd, 0); if ( access_address == (void*) -1) { fprintf(stderr, "mmap: %s\n", strerror(errno)); exit(-1); } printf("The device address %p (lenth %d)\n" "can be accessed over\n" "logical address %p\n", uio_addr, uio_size, access_address); //读写操作 /* access_address = (void*)mremap(access_address, getpagesize(), uio_size + getpagesize() + 11111, MAP_SHARED); if ( access_address == (void*) -1) { fprintf(stderr, "mremmap: %s\n", strerror(errno)); exit(-1); } printf(">>>AFTER REMAP:" "logical address %p\n", access_address); */ return 0; }
可能有用的链接: