HarmonyOS技术社区 · 2021年04月27日

Hi3861_WiFi IoT工程:理解IoT外设控制模块

<span class="size" style="font-size:36px">Hi3861 WiFi IoT工程的一点理解</span>

作者:liangkz  更新时间:2021.04.25  版本:v1.5

目录

1.关于工程本身 
2.ohos\_bundles 
3.工程的目录结构 
4.理解IoT外设控制模块 
      4.1  BUILD.gn 的展开 
      4.2  led\_example.c 的展开 
      4.3  IoT外设控制模块的整体理解 

更新记录:

2021.04.23v1.0初始版本,前3节。
2021.04.25v1.5增加第4节,理解IoT外设控制模块。
说明:本文是 "Hi3861\_WiFi IoT工程的一点理解" 的新增章节,版本升级到v1.5.

<span class="size" style="font-size:24px">4.理解IoT外设控制模块</span>
Hi3861开发板,最主要的功能,就是利用<span class="colour" style="color:rgb(224, 62, 45)">IoT外设控制模块</span>提供对外围设备的操作能力,对外围设备操作接口包括了GPIO, I2C, I2S等等,详情见README。

这一节我们就从上到下看一下是怎么实现这些控制的。

我们先看一下官方提供的应用示例程序:

applications\sample\wifi-iot\app\iothardware\ <span class="colour" style="color:rgb(224, 62, 45)">BUILD.gn</span> + <span class="colour" style="color:rgb(224, 62, 45)">led\_example.c</span>

<span class="size" style="font-size:18px">4.1  BUILD.gn 的展开</span>
.c 文件等下再看,先看BUILD.gn:

include\_dirs = [
        "//utils/native/lite/include",                                   <span class="colour" style="color:rgb(224, 62, 45)"> # A</span>
        "//kernel/liteos\_m/components/cmsis/2.0",          <span class="colour" style="color:rgb(224, 62, 45)">** # B**</span>
        "//base/iot\_hardware/interfaces/kits/wifiiot\_lite",  <span class="colour" style="color:rgb(224, 62, 45)">\# C</span>
    ]
  • #A:进到 //utils/native/lite目录,先看readme。
<span class="highlight" style="background-color:rgb(236, 240, 241)"><span class="size" style="font-size:14px">公共基础库存放OpenHarmony通用的基础组件。这些基础组件可被OpenHarmony各业务子系统及上层应用所使用。</span></span><span class="highlight" style="background-color:rgb(236, 240, 241)"><span class="size" style="font-size:14px">公共基础库在不同平台上提供的能力:</span></span><span class="highlight" style="background-color:rgb(236, 240, 241)"><span class="size" style="font-size:14px">LiteOS-M内核(Hi3861平台):KV存储、文件操作、IoT外设控制、Dump系统属性。</span></span><span class="highlight" style="background-color:rgb(236, 240, 241)"><span class="size" style="font-size:14px">LiteOS-A内核(Hi3516、Hi3518平台):KV存储、定时器、数据和文件存储的JS API、Dump系统属性。</span></span>

Hi3861_WiFi IoT工程:理解IoT外设控制模块

include目录包含了很重要的头文件,应用开发或者鸿蒙系统内部其他模块,要调用这个公用基础库提供的功能时,都需要包含这个路径的头文件,其中:

1. hos\_init.h/ohos\_init.h 就定义了 SYS\_RUN()
这一组宏,也就是下面led\_example.c中使用到的SYS\_RUN(LedExampleEntry);
按这里的定义一路展开,最终会在通过.zinitcall.run2.init 段中的 \_\_zinitcall\_run\_app\_entry 去执行
LedExampleEntry()。

唐佐林老师的《SYS\_RUN()和MODULE\_INIT()之间的那些事》有非常详细的分析,请去看原文。

2. utils\_file.h 定义了经过Utils封装的文件操作接口,UtilsFileXxx() 的实现,就在上一级的file/ 目录下,

UtilsFileXxx()
{
    return HalFileXxx();
}

而这个HalFileXxx() 硬件抽象层的接口,就是下图的 KAL 这个位置,也见 #B 的截图:

Hi3861_WiFi IoT工程:理解IoT外设控制模块

HalFileXxx() 再下去就到了LiteOS\_M内核提供的文件操作接口hi\_xxx()了见 #B的截图。

3. utils\_list.h 定义和实现了一个双向链表结构,这个结构非常重要。

刚好我这两天看到《v01.10鸿蒙内核源码分析(双向链表篇)》,也推荐去看原文。

公用基础库的目录结构如上图,细节就不继续展开了,请自行阅读理解。

  • #B:进入//kernel/liteos\_m/目录,先看readme。

下面这张“LiteOS-M核内核架构图”,结合 #A上面的截图(或者完整的鸿蒙系统架构图),要深入理解一下:Hi3861_WiFi IoT工程:理解IoT外设控制模块

KAL(Kernel Abstract Layer,内核抽象层),是鸿蒙系统框架层(Framework)与内核(LiteOS\_M、LiteOS\_A、Linux内核) 之间的接口,鸿蒙系统框架层与内核层是通过KAL接口进行隔离和解耦的。

KAL可以按照cmsis标准或者posix标准来实现Framework和kernel的对接,目前代码看到的是按cmsis-rtos v2 标准来实现的。

【这里要注意,鸿蒙系统完整代码下的kernel/liteos\_m/ 与本项目的kernel/liteos\_m/ 目录,结构上存在一些差异,但基本上不影响理解,我是两者同时对比着看的,鸿蒙系统完整代码的目录结构(如下)明显更加合理:Hi3861_WiFi IoT工程:理解IoT外设控制模块

详见 README。

但在本工程Hi3861\_Wifiiot里,还是按照工程的实际目录来分析。】

进入components目录:

<span class="colour" style="color:rgb(224, 62, 45)">kal 子目录</span>,看上去实现了一组KalXxx()接口,主要是timer相关的,都是调用了内核的 LOS\_Xxx()来实现的。

<span class="colour" style="color:rgb(224, 62, 45)">cmsis子目录</span>,这就是按照cmsis-rtos v2标准来实现的一组接口,进去看一下,主要是获取内核信息、线程管理、timer管理的。我们在led\_example.c中调用的创建线程的接口osThreadNew()就是在这里实现的。

关于cmsis-rtos v2标准及相关接口,建议看官网的Reference:

https://www.keil.com/pack/doc/cmsis/rtos2/html/group\_\_CMSIS\_\_RTOS.html

CSDN上XinLiBK将其翻译成中文了:

https://blog.csdn.net/u012325601/category\_9274156.html

我在《鸿蒙系统的启动流程v3.0》一文中提到,我验证确认了Hi3861\_Wifiiot\kernel\liteos\_m\目录下的kernel 虽然没有编译,但是**<span class="colour" style="color:rgb(224, 62, 45)">components</span>**是有编译的,可以在里面加log,跑起来可以打印log。

  • #C:进入//base/iot\_hardware/目录,先看readme。
<span class="highlight" style="background-color:rgb(236, 240, 241)"><span class="size" style="font-size:14px">IoT外设控制模块提供对外围设备的操作能力。</span></span><span class="highlight" style="background-color:rgb(236, 240, 241)"><span class="size" style="font-size:14px">本模块提供如下外围设备操作接口:ADC, AT, FLASH, GPIO, I2C, I2S, PARTITION, PWM, SDIO, UART, WATCHDOG等。</span></span><span class="highlight" style="background-color:rgb(236, 240, 241)"><span class="size" style="font-size:14px">IoT外设控制模块使用C语言编写,目前仅支持Hi3861开发板。</span></span>

源代码目录结构不够详细,看我再来个稍微完整的表格,再理一下他们之间的调用关系:Hi3861_WiFi IoT工程:理解IoT外设控制模块

这里 include 的 //base/iot\_hardware/interfaces/kits/wifiiot\_lite 就是上表中“B的声明”,上下层之间的调用关系见最右边一列。

<span class="size" style="font-size:18px">4.2  led\_example.c 的展开</span>
好像把上面 4.1 小结理解透了,led\_example.c 也就自然理解了,这里就一笔带过。

<u><span class="colour" style="color:rgb(224, 62, 45)"><u>开始:</u></span></u>


#include 公用基础库头文件

#include  KAL层提供的cmsis线程管理相关头文件

#include 框架层封装的IoT控制模块头文件

1. 通过公用基础库提供的宏SYS\_RUN(LedExampleEntry)引导进入LedExampleEntry;

2. LedExampleEntry不能做堵塞类事情,因为会影响其他应用的启动,调用cmsis接口创建一个线程LedTask,专门处理控制Led灯开关的事情。

3. LedTask调用框架层IoT控制相关接口(上图中最右列的调用B这一步),然后逐层向下调用,最终实现LED灯的开关控制。

<u><span class="colour" style="color:rgb(224, 62, 45)"><u>结束。</u></span></u>



<span class="size" style="font-size:18px">4.3  IoT外设控制模块的整体理解</span>
官方提供的上述示例程序,仅仅展示了如何通过GPIO去控制Hi3861 WLAN主板上的一颗LED灯。

整套开发板还有其他的扩展板,包括通用底板、显示屏板、NFC板、智能三色灯板等等(官方资料包中还提供了更多的扩展硬件功能的指导说明),板子上不同的硬件分别可以通过不同的接口去进行控制。

要调试某个板子的硬件,需要先去 <span class="colour" style="color:rgb(224, 62, 45)">//vendor/hisi/hi3861/hi3861/build/config/usr\_config.mk </span>打开对应的SUPPORT宏:

# BSP Settings
#
# CONFIG_I2C_SUPPORT is not set
# CONFIG_I2S_SUPPORT is not set
# CONFIG_SPI_SUPPORT is not set
# CONFIG_DMA_SUPPORT is not set
# CONFIG_SDIO_SUPPORT is not set
# CONFIG_SPI_DMA_SUPPORT is not set
# CONFIG_UART_DMA_SUPPORT is not set
# CONFIG_PWM_SUPPORT is not set
# CONFIG_PWM_HOLD_AFTER_REBOOT is not set
CONFIG_AT_SUPPORT=y
CONFIG_FILE_SYSTEM_SUPPORT=y
CONFIG_UART0_SUPPORT=y
CONFIG_UART1_SUPPORT=y
# CONFIG_UART2_SUPPORT is not set
# end of BSP Settings

这些宏会在系统启动app\_main()的peripheral\_init()外围设备初始化阶段,对相关控制接口和数据接口做初始化,之后就可以进行调试了,调试套路和相关控制流程,与上面LED灯的控制大同小异。

整套开发板的的详细资料,可以去润和官网去下载:

http://www.hihope.org/download/download.aspx?mtt=8

资料中包含了硬件的数据手册、原理图、demo code以及更多的扩展说明,看起来可玩性还是蛮高的。

<span class="size" style="font-size:18px">总结:</span>

总的来说,Hi3861\_WiFiIot开发板+工程项目,还是非常适合新手入门学习鸿蒙系统的设备开发的,从简单的东西入手,可以逐步渐进,把系统架构图中的:上下层次关系、模块组件关系等各种流程都理一遍,不至于一步踏进完整鸿蒙系统的汪洋大海中,举足难进。

下一步的学习,还是先以这个工程为主,结合完整鸿蒙的代码,其他还没有涉足的模块/组件都去了解一下,把板子玩熟,把设备开发的整体通路打通,形成自己的理解体系,多做总结进行分享,为鸿蒙生态贡献微薄之力。

以上,也算是我对前一阶段自己学习的所得的一点总结吧。

写到这里,我想喊一句口号,类似“迈出第一小步,梦想是星辰大海”之类的,突然想起hb set的产品类别名称:<span class="colour" style="color:rgb(186, 55, 42)">wifiiot\_hispark\_pegasus</span>,说的不就是这个意思吗,从spark到pegasus,从星星之火到星辰大海。

作者:liangkz
想了解更多内容,请访问51CTO和华为合作共建的鸿蒙社区:https://harmonyos.51cto.com

21_9.jpg

推荐阅读
关注数
3010
内容数
446
华为鸿蒙相关技术,活动及资讯,欢迎关注及加入创作
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息