本文约1800字,今天调试外设功能, 完成对白光灯/红外灯/IR-CUT的控制,本文整理了一套通过复用GPIO控制外设功能的通用方法,可适用日常普通的外设功能调试。
关注公众号, 即可获得与Linux相关的电子书籍以及常用开发工具,文末有文档清单。
本文主要分析外设(如白光灯、红外灯)通过复用GPIO实现相关功能的通用原理、通用流程、通用命令、通用排查,任何用 GPIO 控制补光灯/白光灯的设备都能直接用。以爱芯AX615为例分析。
白光灯本质是 LED 补光灯,由 GPIO 输出高低电平控制开关管(MOS/三极管)导通/截止,实现亮灭。
很多摄像头/IPC 会把红外灯、白光灯、喇叭、ICR共用同一套 GPIO 驱动框架,只换引脚编号即可复用:
从硬件工程师整理的AX615*_PIN_OUT.xlsx 引脚功能复用关系表中可查到白光灯/红外灯的引脚复用关系和对应寄存器地址,如下图所示:



可在硬件原理图上再次进行确认:

最终我们可知道红外灯引脚是GPIO1_A23,白光灯引脚是GPIO1_A24。
axera系列uboot/kernel/riscv等都统一使用pinmux.h里面定义的引脚配置: 将白光灯/红外灯对应寄存器的功能配置不对的根据上面确认的信息进行修改,修改后如下所示:

查询SDK文档中的《AX 外围设备驱动开发指南》可知GPIO引脚值转换后的GPIO控制值为:
GPIO1_23: 32x1+23 = 55
GPIO1_24: 32x1+24 = 56
下面的步骤均以白光灯(gpio56)为例:
echo 56 > /sys/class/gpio/export56 是白光灯 GPIO 编号(设备是多少就改多少)
echo out > /sys/class/gpio/gpio56/direction# 开灯echo 1 > /sys/class/gpio/gpio56/value# 关灯echo 0 > /sys/class/gpio/gpio56/valueecho 56 > /sys/class/gpio/unexport#include<stdio.h>#include<fcntl.h>#include<unistd.h>#include<string.h>#define GPIO_NUM 56 // 白光灯GPIO// 导出GPIOintgpio_export(int gpio){char buf[64];int fd = open("/sys/class/gpio/export", O_WRONLY);if (fd < 0) return-1;sprintf(buf, "%d", gpio); write(fd, buf, strlen(buf)); close(fd);return0;}// 设置方向 out/inintgpio_set_dir(int gpio, constchar *dir){char path[64];int fd;sprintf(path, "/sys/class/gpio/gpio%d/direction", gpio); fd = open(path, O_WRONLY); write(fd, dir, strlen(dir)); close(fd);return0;}// 写值 1/0intgpio_set_value(int gpio, int val){char path[64];int fd;sprintf(path, "/sys/class/gpio/gpio%d/value", gpio); fd = open(path, O_WRONLY); dprintf(fd, "%d", val); close(fd);return0;}// 使用示例voidwhite_light_ctrl(int on){ gpio_export(GPIO_NUM); gpio_set_dir(GPIO_NUM, "out"); gpio_set_value(GPIO_NUM, on ? 1 : 0);}从软件 → 硬件 → 驱动一步步查,绝大部分问题都能定位。
ls /sys/class/gpio/gpio56 → 没导出cat /sys/class/gpio/gpio56/direction必须是:out
# 写1echo 1 > /sys/class/gpio/gpio56/valuecat /sys/class/gpio/gpio56/valuedmesg | grep gpio看到 gpio56 被其他设备注册 → 冲突,需修改设备树或关闭对应驱动。
echo 56 > /sys/class/gpio/exportecho out > /sys/class/gpio/gpio56/directionecho 1 > /sys/class/gpio/gpio56/value红外灯、白光灯、喇叭、警灯,都可以用同一套 GPIO 函数,只换编号:
// 统一接口typedefstruct {int gpio;int active_level; // 高/低有效} GPIO_DEV;GPIO_DEV white_light = {56, 1};GPIO_DEV ir_light = {55, 1};GPIO_DEV speaker = {27, 1};// 统一控制voiddev_on(GPIO_DEV dev){ gpio_export(dev.gpio); gpio_set_dir(dev.gpio, "out"); gpio_set_value(dev.gpio, dev.active_level);}好处:
往期文章(欢迎订阅技术分享栏目全部文章):

这里是女程序员的笔记本
15年+嵌入式软件工程师兼二胎宝妈
分享读书心得、工作经验,自我成长和生活方式。
希望我的文字能对你有所帮助