嵌入式Linux驱动开发基础知识点精要


一、开发环境搭建
  1. 交叉编译工具链
    • 安装:arm-linux-gnueabihf-gcc
    • 验证:arm-linux-gnueabihf-gcc -v
  2. 内核编译与设备树
    • 编译内核:make Image dtbs
    • 设备树文件:.dts(源码) → .dtb(二进制)
    • 关键配置:屏幕分辨率(display-timings节点)

二、驱动开发核心基础
  1. 内核模块开发

    • 模块入口/出口函数:
      module_init(drv_init);  
      module_exit(drv_exit);  
      
    • 字符设备注册流程:
      1. 分配设备号:alloc_chrdev_region
      2. 初始化cdev结构体
      3. 关联文件操作集:cdev_init(&cdev, &fops)
      4. 添加设备到内核:cdev_add
  2. 用户态交互

    • 文件操作接口:
      struct file_operations {  
          .owner = THIS_MODULE,  
          .open = drv_open,  
          .read = drv_read,  
          .write = drv_write,  
          .release = drv_release  
      };  
      
    • 测试APP:通过open/read/write系统调用与驱动交互

三、设备树(DTS)核心操作
  1. 设备树解析函数

    • 查找节点:of_find_node_by_path("/soc/gpio@ff260000")
    • 获取属性:of_get_property(node, "compatible", NULL)
    • 地址转换:of_iomap(自动映射物理地址到虚拟地址)
  2. 资源管理

    • 定义资源结构体:
      struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);  
      
    • 手动映射寄存器:
      void __iomem *reg = ioremap(res->start, resource_size(res));  
      

四、并发与竞争控制
机制适用场景核心API
原子操作单个变量的简单保护atomic_read(), atomic_set()
自旋锁短时临界区,不可睡眠spin_lock(), spin_unlock()
信号量允许休眠的长时任务down(), up()
互斥体替代信号量,支持优先级继承mutex_lock(), mutex_unlock()
读写锁读多写少场景read_lock(), write_lock()

五、中断处理
  1. 注册中断
    request_irq(irq_num, handler, IRQF_TRIGGER_RISING, "key_irq", dev);  
    
  2. 顶半部与底半部
    • 顶半部:快速响应(清除中断标志)
    • 底半部:
      • Tasklet:不可睡眠,轻量级
        DECLARE_TASKLET(my_tasklet, tasklet_func, data);  
        
      • 工作队列:可睡眠,处理复杂逻辑
        INIT_WORK(&work, work_func);  
        schedule_work(&work);  
        

六、内核定时器
  1. 定时器使用
    struct timer_list my_timer;  
    timer_setup(&my_timer, timer_callback, 0);  
    mod_timer(&my_timer, jiffies + msecs_to_jiffies(1000));  
    
  2. 延时函数
    • 毫秒级:mdelay(10)
    • 纳秒级:ndelay(100)

七、阻塞与非阻塞IO
  1. 等待队列
    DECLARE_WAIT_QUEUE_HEAD(wq);  
    wait_event_interruptible(wq, condition);  
    wake_up_interruptible(&wq);  
    
  2. 应用场景
    • 按键防抖:定时器延时处理中断
    • 数据等待:进程休眠直到数据就绪

基础学习路径

  1. 环境搭建:交叉编译器 + 内核编译
  2. 第一个驱动:字符设备控制虚拟LED
  3. 设备树实战:修改GPIO引脚定义并验证
  4. 并发实验:用自旋锁保护共享计数器
  5. 中断实验:按键触发LED状态切换
  6. 综合练习:按键防抖 + 定时器呼吸灯

常见面试考点

  1. 设备号管理:主/次设备号分配机制
  2. 内存映射:ioremap与mmap的区别
  3. 中断上下文:为什么顶半部不能休眠?
  4. 自旋锁 vs 信号量:使用场景对比
  5. 设备树作用:为什么取代了板级文件?

核心文档参考:

  • 《Linux设备驱动开发详解》第5章(字符设备)
  • 《Linux内核设计与实现》第10章(中断处理)
  • 内核源码:drivers/char(简单驱动参考)

掌握以上知识点后,可尝试实现一个多按键LED控制系统(含防抖、并发控制、sysfs调试接口),作为面试展示项目。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐