#DAYU200体验官# RK3568三色灯点灯流程 原创 精华

liangkz_梁开祝
发布于 2022-4-19 16:03
浏览
14收藏

我在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. 流程图

#DAYU200体验官# RK3568三色灯点灯流程-鸿蒙开发者社区
【附件有原始大图】

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灯,应该是如下图所示:
#DAYU200体验官# RK3568三色灯点灯流程-鸿蒙开发者社区

在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开发板做了一下兼容,重新写了一个更简单的示例程序,方便大家学习。

源代码开放在码云上了:

OhosLedRGBhttps://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这个点灯序列后退出。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
LightFlowOnDAYU200.rar 809.75K 379次下载
led_rgb.rar 55.53K 271次下载
已于2022-12-14 17:41:18修改
18
收藏 14
回复
举报
16条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

录制视频楼主可以先放在极客show中:https://ost.51cto.com/show

已于2022-4-19 16:23:42修改
回复
2022-4-19 16:23:33
红叶亦知秋
红叶亦知秋

贴一下楼主视频链接:https://ost.51cto.com/show/11590

回复
2022-4-19 17:37:48
liangkz_梁开祝
liangkz_梁开祝

感谢。

回复
2022-4-19 18:10:38
Soon_L
Soon_L

感谢梁老师解惑

回复
2022-4-19 19:20:48
贺婷婷
贺婷婷

非常想玩一下这个

回复
2022-4-20 12:35:01
红叶亦知秋
红叶亦知秋

突然发现大佬文章附件更新了

回复
2022-4-26 14:59:24
jiaxin9681
jiaxin9681

感谢分享

回复
2022-5-5 16:46:29
小强鼓掌
小强鼓掌

非常棒的分享

回复
2022-5-7 17:35:41
wx5d176913e518c
wx5d176913e518c

你的书啥时候出版

回复
2022-5-9 22:13:42
liangkz_梁开祝
liangkz_梁开祝 回复了 wx5d176913e518c
你的书啥时候出版

感谢关注,出版社消息,预计7月份可上市。

回复
2022-5-10 07:26:51
haloki
haloki

请问如何将lex推送到平台?我因为权限问题无法使用file send方式将lex推送到开发板。

回复
2022-6-16 15:58:04
liangkz_梁开祝
liangkz_梁开祝 回复了 haloki
请问如何将lex推送到平台?我因为权限问题无法使用file send方式将lex推送到开发板。

确保平台上的hdc版本与pc或linux上的hdc版本一致,然后在pc上连接上平台后,执行一下:

hdc shell mount -o rw,remount /

重新挂载根目录,带rw权限,再去执行file send就可以了。

2
回复
2022-6-16 16:10:09
Whyalone
Whyalone

来顶一下,昨天被连志安老师称赞的帖子

回复
2022-6-16 16:28:42
liangkz_梁开祝
liangkz_梁开祝 回复了 Whyalone
来顶一下,昨天被连志安老师称赞的帖子

 

回复
2022-6-16 16:31:16
wx654f07925aaee
wx654f07925aaee

梁老师,这个GPIO的管脚为什么定义成146/147/149呢?他跟GPIO4_C2是什么样的转换关系啊?

如果我要驱动别的GPIO该怎么把GPIO号转换成具体的类似于146这样的数呢?

回复
2023-12-18 17:02:10
liangkz_梁开祝
liangkz_梁开祝 回复了 wx654f07925aaee
梁老师,这个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的原理图,那就直接去

//vendor/hihope/rk3568/hdf_config/khdf/light/light_config.hcs

 这个文件查看LED灯对应的管脚,这也是需要对OH的代码结构以及驱动框架有所理解才比较容易找到这个文件。


1
回复
2023-12-20 17:53:26
回复
    相关推荐