linux dev uio读不了,UIO 示例 - 积极工作,积极生活 - OSCHINA - 中文开源技术交流社区...

用户空间代码:

#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_ON1 //LED亮状态

#define LED_OFF0 //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");

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值