UIO使用基础

//内核态注册UIO:
struct platform_device g_demo_uio_pdev = {
    .name = "demo_uio",
    .id = 0,
};

struct uio_info g_demo_uio_info[] = {
    {
        .name = "demo1",
        .version = "1.0",
        .mem = {
            {
                .name = "demo1_mem0",
                .addr = 0x10000000,
                .size = 0x00010000,
                .memtype = UIO_MEM_PHYS,
            },
            {
                .name = "demo1_mem1",
                .addr = 0x20000000,
                .size = 0x00020000,
                .memtype = UIO_MEM_PHYS,
            },
            {
                .name = "demo1_mem2",
                .addr = 0x30000000,
                .size = 0x00030000,
                .memtype = UIO_MEM_PHYS,
            },
            {
                .name = "demo1_mem3",
                .addr = 0x40000000,
                .size = 0x00040000,
                .memtype = UIO_MEM_PHYS,
            },
            {
                .name = "demo1_mem4",
                .addr = 0x50000000,
                .size = 0x00050000,
                .memtype = UIO_MEM_PHYS,
            },
        },
    },
    {
        .name = "demo2",
        .version = "2.0",
        .mem = {
            {
                .name = "demo2_mem0",
                .addr = 0x60000000,
                .size = 0x00010000,
                .memtype = UIO_MEM_PHYS,
            },
            {
                .name = "demo2_mem1",
                .addr = 0x70000000,
                .size = 0x00020000,
                .memtype = UIO_MEM_PHYS,
            },
            {
                .name = "demo2_mem2",
                .addr = 0x80000000,
                .size = 0x00030000,
                .memtype = UIO_MEM_PHYS,
            },
            {
                .name = "demo2_mem3",
                .addr = 0x90000000,
                .size = 0x00040000,
                .memtype = UIO_MEM_PHYS,
            },
            {
                .name = "demo2_mem4",
                .addr = 0xa0000000,
                .size = 0x00050000,
                .memtype = UIO_MEM_PHYS,
            },
        },
    },
}

platform_device_register(&g_demo_uio_pdev);
uio_register_device(&g_demo_uio_pdev.dev, &g_demo_uio_info[0]);
uio_register_device(&g_demo_uio_pdev.dev, &g_demo_uio_info[1]);


//用户态使用:
1.
读取节点名字,即为g_demo_uio_info[%d].name 的值
FILE *fp = fopen("/sys/class/uio/uio%d/name", "rb");
fgetc + strcmp 命中对应的节点,得到 %d 编号 index

2. 再基于第一步获取的index,填充uio%d编号后,查其下的子节点名字,即 g_demo_uio_info[%d].mem[%d].name
FILE *fp = fopen("/sys/class/uio/uio%d/maps/map%d/name", "rb");
fgetc + strcmp 命中对应的节点,得到 mem[%d] 编号 index_mem

3. 基于前两步获取的index, 获取
FILE *fp_addr = fopen("/sys/class/uio/uio%d/maps/map%d/addr", "rb");
FILE *fp_size = fopen("/sys/class/uio/uio%d/maps/map%d/size", "rb");
fgetc 获取值字符串 + strtoull 转为数字得到地址与长度信息



uio_fd = open("/dev/uio0",O_RDWR);
addr_fd = open("/sys/class/uio/uio0/maps/map0/addr", O_RDONLY);
size_fd = open("/sys/class/uio/uio0/maps/map0/size", O_RDONLY);
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_0 = mmap(NULL, uio_size, PROT_READ | PROT_WRITE, MAP_SHARED, uio_fd, 0 * getpagesize());

uio_fd = open("/dev/uio0",O_RDWR);
addr_fd_1 = open("/sys/class/uio/uio0/maps/map1/addr", O_RDONLY);
size_fd_1 = open("/sys/class/uio/uio0/maps/map1/size", O_RDONLY);
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_1 = mmap(NULL, uio_size_1, PROT_READ | PROT_WRITE, MAP_SHARED, uio_fd, 1 * getpagesize());

注意:
正常mmap的最后参数为需要映射的物理地址,但是对于UIO而言,系统调用mmap UIO的fd的时候,会重定向到UIO内部的mmap函数.
因此对于mmap最后的参数是: UIO设备的mem段的数组编号 * getpagesize()

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值