## 1. 设备树驱动开发实例分析 ### 1.1 系统架构设计 LED驱动采用分层架构设计包含以下核心组件 1. 应用层ledtest.c用户空间控制接口 2. 驱动层leddrv.c通用设备操作封装 3. 硬件层chip_demo_gpio.c具体硬件操作实现 系统调用流程应用层write() → 驱动层led_drv_write() → 硬件层board_demo_led_ctl()### 1.2 设备树节点配置 在i.MX6ULL处理器设备树中添加LED节点 dts #define GROUP_PIN(g,p) ((g16) | (p)) 100ask_led0 { compatible 100as,leddrv; pin GROUP_PIN(5,3); };关键配置说明compatible属性驱动匹配标识符pin属性自定义GPIO组和引脚编号组5引脚3地址编码规则高16位存储GPIO组号低16位存储引脚号2. 驱动实现关键技术2.1 平台设备匹配机制驱动使用设备树匹配流程内核扫描设备树节点将符合规则的节点转换为platform_device通过compatible属性匹配platform_driver匹配优先级设备树compatible属性匹配主要方式传统ACPI匹配已过时ID表匹配已过时2.2 关键驱动函数实现硬件初始化函数static int board_demo_led_init(int which) { // 1. 寄存器地址映射 CCM_CCGR1 ioremap(CCM_CCGR1_BASE, 4); SW_MUX_GPIO5_IO03 ioremap(SW_MUX_GPIO5_IO03_BASE, 4); // 2. 时钟使能配置 val readl(CCM_CCGR1); val ~(330); val | (330); writel(val, CCM_CCGR1); // 3. GPIO模式配置 writel(5, SW_MUX_GPIO5_IO03); val readl(GPIO5_GDIR); val | (13); writel(val, GPIO5_GDIR); }Probe函数设备树匹配后执行static int chip_demo_gpio_probe(struct platform_device *pdev) { // 1. 获取设备树自定义属性 of_property_read_u32(np, pin, pin); // 2. 注册LED设备 g_ledpins[0] pin; register_led_operations(board_demo_led_opr); }3. 寄存器操作详解3.1 关键寄存器配置寄存器名称物理地址功能描述CCM_CCGR10x020C406C时钟门控寄存器SW_MUX_GPIO5_IO030x02290014GPIO复用控制寄存器GPIO5_DR0x020AC000GPIO数据寄存器GPIO5_GDIR0x020AC004GPIO方向寄存器3.2 GPIO控制流程时钟使能配置CCM_CCGR1寄存器bit[31:30]为0b11引脚复用设置SW_MUX_GPIO5_IO03为GPIO模式值5方向设置配置GPIO5_GDIR bit3为输出模式电平控制亮灯GPIO5_DR bit30灭灯GPIO5_DR bit314. 测试与验证4.1 用户空间测试命令# 点亮LED ./ledtest /dev/100ask_led0 on # 熄灭LED ./ledtest /dev/100ask_led0 off4.2 设备树节点验证查看已加载的设备树节点# 查看节点属性 ls /sys/firmware/devicetree/base/100ask_led0 # 读取属性值 cat /sys/firmware/devicetree/base/100ask_led0/compatible hexdump /sys/firmware/devicetree/base/100ask_led0/pin5. 设计要点总结设备树优势将硬件配置与驱动代码分离提高可移植性驱动分层硬件操作与设备接口分离便于维护寄存器操作必须遵循映射-配置-使用流程属性读取使用of_property_read_u32()获取设备树自定义参数完整驱动代码已通过i.MX6ULL开发板验证实测GPIO5_3引脚可正确控制LED亮灭状态。
Linux设备树驱动开发与GPIO控制实例
## 1. 设备树驱动开发实例分析 ### 1.1 系统架构设计 LED驱动采用分层架构设计包含以下核心组件 1. 应用层ledtest.c用户空间控制接口 2. 驱动层leddrv.c通用设备操作封装 3. 硬件层chip_demo_gpio.c具体硬件操作实现 系统调用流程应用层write() → 驱动层led_drv_write() → 硬件层board_demo_led_ctl()### 1.2 设备树节点配置 在i.MX6ULL处理器设备树中添加LED节点 dts #define GROUP_PIN(g,p) ((g16) | (p)) 100ask_led0 { compatible 100as,leddrv; pin GROUP_PIN(5,3); };关键配置说明compatible属性驱动匹配标识符pin属性自定义GPIO组和引脚编号组5引脚3地址编码规则高16位存储GPIO组号低16位存储引脚号2. 驱动实现关键技术2.1 平台设备匹配机制驱动使用设备树匹配流程内核扫描设备树节点将符合规则的节点转换为platform_device通过compatible属性匹配platform_driver匹配优先级设备树compatible属性匹配主要方式传统ACPI匹配已过时ID表匹配已过时2.2 关键驱动函数实现硬件初始化函数static int board_demo_led_init(int which) { // 1. 寄存器地址映射 CCM_CCGR1 ioremap(CCM_CCGR1_BASE, 4); SW_MUX_GPIO5_IO03 ioremap(SW_MUX_GPIO5_IO03_BASE, 4); // 2. 时钟使能配置 val readl(CCM_CCGR1); val ~(330); val | (330); writel(val, CCM_CCGR1); // 3. GPIO模式配置 writel(5, SW_MUX_GPIO5_IO03); val readl(GPIO5_GDIR); val | (13); writel(val, GPIO5_GDIR); }Probe函数设备树匹配后执行static int chip_demo_gpio_probe(struct platform_device *pdev) { // 1. 获取设备树自定义属性 of_property_read_u32(np, pin, pin); // 2. 注册LED设备 g_ledpins[0] pin; register_led_operations(board_demo_led_opr); }3. 寄存器操作详解3.1 关键寄存器配置寄存器名称物理地址功能描述CCM_CCGR10x020C406C时钟门控寄存器SW_MUX_GPIO5_IO030x02290014GPIO复用控制寄存器GPIO5_DR0x020AC000GPIO数据寄存器GPIO5_GDIR0x020AC004GPIO方向寄存器3.2 GPIO控制流程时钟使能配置CCM_CCGR1寄存器bit[31:30]为0b11引脚复用设置SW_MUX_GPIO5_IO03为GPIO模式值5方向设置配置GPIO5_GDIR bit3为输出模式电平控制亮灯GPIO5_DR bit30灭灯GPIO5_DR bit314. 测试与验证4.1 用户空间测试命令# 点亮LED ./ledtest /dev/100ask_led0 on # 熄灭LED ./ledtest /dev/100ask_led0 off4.2 设备树节点验证查看已加载的设备树节点# 查看节点属性 ls /sys/firmware/devicetree/base/100ask_led0 # 读取属性值 cat /sys/firmware/devicetree/base/100ask_led0/compatible hexdump /sys/firmware/devicetree/base/100ask_led0/pin5. 设计要点总结设备树优势将硬件配置与驱动代码分离提高可移植性驱动分层硬件操作与设备接口分离便于维护寄存器操作必须遵循映射-配置-使用流程属性读取使用of_property_read_u32()获取设备树自定义参数完整驱动代码已通过i.MX6ULL开发板验证实测GPIO5_3引脚可正确控制LED亮灭状态。