PC平台UIO用户空间中断处理实现问题咨询
在Ubuntu PC上用UIO处理ISA中断的解决方案
因为PC架构没有设备树,没法用嵌入式系统里常见的设备树绑定UIO的方式。不过你可以通过编写一个极简的内核模块来手动注册UIO设备,生成/dev下的uio节点,具体步骤如下:
1. 确认目标ISA IRQ状态
首先要确定你连接的ISA IRQ号,以及它是否空闲:
cat /proc/interrupts
找到对应的IRQ行,确保没有其他设备在使用它(如果是共享IRQ,需要后续模块中设置共享标志)。另外,记得检查BIOS是否启用了该ISA IRQ,有些PC默认会禁用部分ISA中断线路。
2. 编写极简UIO内核模块
创建一个名为uio_isa_irq.c的文件,内容如下(替换IRQ_NUMBER为你的实际IRQ号,比如5):
#include <linux/module.h> #include <linux/uio_driver.h> #include <linux/interrupt.h> // 替换成你的ISA IRQ编号 #define IRQ_NUMBER 5 static struct uio_info uio_isa_irq_info = { .name = "uio_isa_irq", .version = "0.1", .irq = IRQ_NUMBER, // 如果IRQ需要共享,保留IRQF_SHARED;独占则去掉 .irq_flags = IRQF_SHARED, // 使用UIO提供的默认中断处理函数,会自动通知用户空间 .handler = uio_interrupt, }; static int __init uio_isa_irq_init(void) { return uio_register_device(NULL, &uio_isa_irq_info); } static void __exit uio_isa_irq_exit(void) { uio_unregister_device(&uio_isa_irq_info); } module_init(uio_isa_irq_init); module_exit(uio_isa_irq_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("UIO Driver for ISA External Interrupt");
3. 编译模块
创建Makefile文件:
obj-m += uio_isa_irq.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
先安装内核头文件依赖:
sudo apt update && sudo apt install linux-headers-$(uname -r)
然后编译模块:
make
4. 加载模块并验证
加载模块:
sudo insmod uio_isa_irq.ko
查看/dev目录下是否生成了uio设备节点:
ls /dev/uio*
通常会生成/dev/uio0(如果已有其他uio设备,编号会递增)。
5. 用户空间测试程序
创建一个简单的用户空间程序uio_test.c来验证中断:
#include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <sys/mman.h> #define UIO_DEV_PATH "/dev/uio0" int main() { int fd = open(UIO_DEV_PATH, O_RDWR); if (fd < 0) { perror("Failed to open UIO device"); return 1; } unsigned long irq_count; printf("Waiting for ISA interrupts...\n"); while (1) { // 读取中断计数,此调用会阻塞直到中断触发 if (read(fd, &irq_count, sizeof(irq_count)) == sizeof(irq_count)) { printf("Interrupt received! Total count: %lu\n", irq_count); } } close(fd); return 0; }
编译并运行:
gcc uio_test.c -o uio_test sudo ./uio_test
此时触发外部微控制器的中断,就能看到程序打印中断信息了。
额外注意事项
- 权限问题:默认
/dev/uioX只有root可访问,你可以临时修改权限:
或者添加udev规则永久设置权限:创建sudo chmod 666 /dev/uio0/etc/udev/rules.d/99-uio.rules,内容为:
然后重载udev规则:SUBSYSTEM=="uio", MODE="0666"sudo udevadm control --reload-rules && sudo udevadm trigger - 卸载模块:如果需要卸载模块,执行:
sudo rmmod uio_isa_irq
内容的提问来源于stack exchange,提问作者jshh
相关产品推荐
相关产品推荐

