#DAYU200体验官# RK3568三色灯点灯流程 原创 精华
我在Hi3516开发板上做过LED灯的点灯示例程序以演示OpenHarmony驱动开发的一些要点,但因为一开始不知道DAYU200上的三色灯的GPIO管脚号是多少,就没做灯控测试。有小伙伴问我“DAYU200上的RGB灯怎么控制”?,我就抽空研究了一下这部分流程,写了个测试程序。
1. 先看视频
视频链接
这是ledx测试程序运行的效果和log。
led_rgb测试程序运行效果未录制视频。
2. 驱动代码分析
先看一下驱动配置文件:
//vendor/hihope/rk3568/hdf_config/khdf/light/light_config.hcs
这就是三色灯的驱动配置,包含了三色灯的GPIO管脚号。再从:
//vendor/hihope/rk3568/hdf_config/khdf/device_info/device_info.hcs
找到:hostName = “light_host” 的相关信息。
再往上找到light的内核态驱动程序:
//drivers/framework/model/misc/light/driver/
这里有include/light_driver.h和src/light_driver.c
再往上找到light的用户态HAL接口:
//drivers/peripheral/misc/light/hal/
这里也有src/light_controller.h 和 src/light_controller.c。
在//drivers/peripheral/misc/light/下还有hdi_service和interfaces。
还可以找到//drivers/interface/light/v1_0/ILightInterface.idl
经过代码的解读和画图整理,可以得到如下的流程图。
3. 流程图
【附件有原始大图】
4. 测试程序
虽然//drivers/peripheral/misc/light/test/路径下已经有测试程序了,但我还是自己用C语言实现了一个简单的无界面测试程序。
- ledx:可执行程序,你可将其推送到平台的/bin/目录下,然后在shell上执行./bin/ledx即可看到效果。
- ledx.c:测试程序源代码
- BUILD.gn:测试程序编译脚本,在//applications/standard/hap/ohos.build文件的 module_list 下增加一句:
“//…(BUILD.gn部署路径)…/ledx:ledx”,
让它参与编译即可。
- light_driver.c 经过我修改的light驱动程序,见宏liangkz_modify包括住的部分代码。
【原始的内核态驱动程序light_driver.c中存在bug,导致实际运行并不如预期,需要修复light_driver.c中的bug后才完全如预期。】
ledx 测试程序会自动跑以下一个点灯序列:
HILOG_INFO(LOG_APP, " ledId [-1, 0, 1, 2]: -1-Exit, 0-GetLightInfo, 1-Led1, 2-Led2");
HILOG_INFO(LOG_APP, " ledMod[-1, 0, 1 ]: -1-Flash,0-Off, 1-On");
HILOG_INFO(LOG_APP, " ledBrt[ 1, 2, 4, x]: 1-R, 2-G, 4-B, x-bit");
int32_t matrix[][3] =
{
{0, 0, 0}, //GetLightInfo
{1, 0, 7}, //LED1 Off all RGB
{1, 1, 1}, //LED1 On R
{1, 1, 2}, //LED1 On G
{1, 1, 4}, //LED1 On B
{1, 0, 0}, //LED1 Off
{1, 1, 7}, //LED1 On BGR:111
{1, 1, 6}, //LED1 On BG-:110
{1, 1, 5}, //LED1 On B-R:101
{1, 1, 4}, //LED1 On B--:100
{1, 1, 3}, //LED1 On -GR:011
{1, 1, 2}, //LED1 On -G-:010
{1, 1, 1}, //LED1 On --R:001
{1, 0, 0}, //LED1 Off
{1, -1, 7}, //LED1 Flash RGB
{-1, 0, 0},//Exit
};
小伙伴们可自行根据规则添加测试序列。
5. 发现并修复bug
在写ledx测试程序做验证时,发现死活都得不到预期效果,我就干脆从下到上把整个流程画了图出来,发现驱动程序果然有不可预料的行为。
5.1 LED灯的数量
在没得到原理图和GPIO管脚编号的情况下,我猜测DAYU200开发板排线旁边的LED灯,应该是如下图所示:
在light_config.hcs中写 lightId = [1, 2]; 相当于说是有两盏灯,但实际上,我认为要么是1盏(三色LED合一),要么是3盏(三色LED各自独立),我这里暂且把RGB合在一起当做1盏灯来处理。
5.2 GpioWrite()的行为
light_driver.c中对GpioWrite()的几处调用中,对drvData->info[lightId]->busNum的使用,很明显是不合理的,这是造成测试效果不符合预期的根本原因。
我对此做了一下修改,用 UpdateLight(uint32_t lightId, uint32_t lightOn)来替代,小伙伴们读一下附件的代码估计就清楚了。
【注意】后来我再想了一下,上面提到的“bug”以及附件代码里的修改,除了Disable()函数里的一处:
if (GpioWrite(drvData->info[lightId]->busRNum, GPIO_VAL_LOW) != HDF_SUCCESS)
可以确信是bug(busRNum应为 busNum)之外,其它几处很可能并不是bug,只是他们设计的灯控流程和参数设置我没搞清楚而已。
实测效果来看,默认三色灯是紫色的(红色+蓝色),绿色灯并未点亮;在跑我的测试程序过程中,红色和蓝色两灯会出现非预期的亮灯行为。
因此,我怀疑在light_config.hcs中写 lightId = [1, 2]; 所说的两盏灯,有可能是指红色和蓝色两灯,在系统中有其他地方有控制这两盏灯的亮灯行为,不过没有控制绿灯的行为。
6.更简单的示例程序
由上面的流程图可以看出,一个简单的点灯流程,被设计得非常复杂(但也非常规范化),这对新手来说很难理解。加上APP的灯控参数和DRV的灯控逻辑,非常容易让人产生困惑。
为此,我结合早期在Hi3516开发板上的LED灯控示例程序,对RK3568开发板做了一下兼容,重新写了一个更简单的示例程序,方便大家学习。
源代码开放在码云上了:
OhosLedRGB:https://gitee.com/liangkzgitee/led_rgb
这个示例程序包含了驱动开发的必要要素,应用程序led_rgb直接通过消息机制与内核驱动进行交互,设置RGB三色灯的亮灯行为。同时它也兼容Hi3516开发板上的三个系统和RK3568开发板上的标准系统,详情请看仓库上的README文档。
示例程序的代码目录结构如下:
./led_rgb/
├── apps
│ └── led_rgb
│ ├── BUILD.gn
│ └── led_rgb.c
├── config
│ ├── device_info
│ │ └── device_info.hcs
│ └── led
│ ├── led_config_hi3516.hcs
│ └── led_config_rk3568.hcs
├── drv
│ ├── build_linux
│ │ └── Makefile
│ ├── build_liteos
│ │ ├── BUILD.gn
│ │ └── Makefile
│ └── led_drv.c
└── README.md
在平台的shell上执行./bin/led_rgb时,
- 带参数,参数为0~7的一个数字,按位与0b111,去点亮“BGR”三个LED,如写入参数6,则0b110,点亮“BG-”两灯,熄灭“R”灯。
- 不带参数,默认会自动执行7~0这个点灯序列后退出。
录制视频楼主可以先放在极客show中:https://ost.51cto.com/show
贴一下楼主视频链接:https://ost.51cto.com/show/11590
感谢。
感谢梁老师解惑
非常想玩一下这个
突然发现大佬文章附件更新了
感谢分享
非常棒的分享
你的书啥时候出版
感谢关注,出版社消息,预计7月份可上市。
请问如何将lex推送到平台?我因为权限问题无法使用file send方式将lex推送到开发板。
确保平台上的hdc版本与pc或linux上的hdc版本一致,然后在pc上连接上平台后,执行一下:
hdc shell mount -o rw,remount /
重新挂载根目录,带rw权限,再去执行file send就可以了。
来顶一下,昨天被连志安老师称赞的帖子
梁老师,这个GPIO的管脚为什么定义成146/147/149呢?他跟GPIO4_C2是什么样的转换关系啊?
如果我要驱动别的GPIO该怎么把GPIO号转换成具体的类似于146这样的数呢?
一般情况下,需要我们查看开发板的原理图,找到板子上这三颗LED灯连接的是SoC的哪几根管脚,然后根据芯片手册的说明进行计算,比如说RK3568的GPIO管脚分若干组,每组32个GPIO,组内编号分别是A0-A7、B0-B7、C0-C7、D0-D7,绿灯连接的是GPIO04_C2 =32x4+8x2+2=146,红灯连接的是GPIO04_C3 =32x4+8x2+3=147,蓝色灯连接的是GPIO04_C5 =32x4+8x2+5=149。
但是目前我们看不到dayu200的原理图,那就直接去
这个文件查看LED灯对应的管脚,这也是需要对OH的代码结构以及驱动框架有所理解才比较容易找到这个文件。
梁老师,我使用的是您gitee上的例程,通过串口终端运行./bin/led_rgb 0xXX 时显示:device led_service not in configed device list,是哪里可能出了问题呢?
以解决
同学,我也是一样的问题,请问你是怎么解决的?QAQ
vendor/hihope/rk3568/config.json:“build_selinux":true -->false 关闭安全增强选项