梅科尔工作室-#14天鸿蒙设备开发实战#快速入门笔记 原创 精华

zzuliGjq
发布于 2022-7-23 21:33
浏览
0收藏

@toc

HarmonyOS快速入门

Hello World

编写Hello World程序

添加Hello World源码文件

下载源码的方法可参考梅科尔工作室-#14天鸿蒙设备开发实战#环境搭建笔记-开源基础软件社区-51CTO.COM,部署环境->简易步骤中的在Ubuntu上获取源码相应步骤,此处使用其中的第一种方法,将代码下载到code3中。

梅科尔工作室-#14天鸿蒙设备开发实战#快速入门笔记-鸿蒙开发者社区

  • 将Ubuntu的文件远程映射到Windows文件夹中后,将下载的源码文件使用VS Code打开(直接拖到VS Code就可以)

  • 新增my_app文件夹

    在./applications/BearPi/BearPi-HM_Nano/sample路径下新建一个my_app目录,用于存放业务源码文件

  • 新增hello_world.c文件

    在./applications/BearPi/BearPi-HM_Nano/sample/my_app路径下新建一个hello_world.c文件,该文件为业务源码文件。

  • 新增BUILD.gn文件

    在./applications/BearPi/BearPi-HM_Nano/sample/my_app路径下新建一个BUILD.gn文件,该文件为业务源码编译脚本。

编写Hello World业务代码

在hello_world.c中新建业务入口函数Hello_World,并实现业务逻辑。并在代码最下方,使用HarmonyOS启动恢复模块接口APP_FEATURE_INIT()启动业务。(printf定义在stdio.h文件中,APP_FEATURE_INIT定义在ohos_init.h文件中)
源码如下:

#include <stdio.h>  // 引入头文件
#include "ohos_init.h"  // 引入头文件
// <>和""寻找路径不一样,<>从系统库开始查找,""从用户目录开始找,若未找到才到系统库中去查找

void Hello_World(void)
{
    printf("Hello World!\r\n");  // 打印,\r是回车,\n是换行
}

APP_FEATURE_INIT(Hello_World);  // app函数入口,启动Hello_World

编写编译构建文件BUILD.gn

在./applications/BearPi/BearPi-HM/sample/my_app下的BUILD.gn文件中添加如下代码。

# static_library中指定业务模块的编译结果,为静态库文件libmyapp.a,开发者根据实际情况完成填写。
static_library("myapp") {  # 此处参数填xxx,静态库文件就是libxxx.a
    # sources中指定静态库.a所依赖的.c文件及其路径,若路径中包含"//"则表示绝对路径(此处为代码根路径),若不包含"//"则表示相对路径。
    sources = [
        "hello_world.c"
    ]
    # include_dirs中指定source所需要依赖的.h文件路径。
    include_dirs = [
        "//utils/native/lite/include"  # ohos_init.h
    ]
}
  • static_library中指定业务模块的编译结果,为静态库文件libmyapp.a,开发者根据实际情况完成填写。
  • sources中指定静态库.a所依赖的.c文件及其路径,若路径中包含"//“则表示绝对路径(此处为代码根路径),若不包含”//" 则表示相对路径。
  • include_dirs中指定source所需要依赖的.h文件路径。

编写模块BUILD.gn文件,指定需参与构建的特性模块。

在./applications/BearPi/BearPi-HM/sample下的BUILD.gn文件中添加如下代码(可以将features中原有的模块注释掉,添加上"my_app:myapp",

import("//build/lite/config/component/lite_component.gni")

lite_component("app") {
	features = [
    	# 指定需参与构建的特性模块
		"my_app:myapp",
	]
}
  • my_app是相对路径,指向./applications/BearPi/BearPi-HM/sample/my_app/BUILD.gn。
  • myapp是目标,指向./applications/BearPi/BearPi-HM/sample/my_app/BUILD.gn中的static_library(“myapp”)。

编译烧录Hello World程序

  • 首先打开MobaXterm工具,登录服务器后,进入源码目录code3下

  • 输入hpm dist,开始编译源码,如果出现BUILD SUCCESS字样,说明编译成功
    梅科尔工作室-#14天鸿蒙设备开发实战#快速入门笔记-鸿蒙开发者社区

  • 使用HiBurn工具烧录源码(先将电脑与开发板连接起来,通过设备管理器->端口查看端口)

  • COM:端口的选择要和设备管理器中显示的端口一致

  • 波特率选择921600,左上角setting->Com setting->Baud

  • Select File:烧录文件选择刚才生成的bin文件(\home\bearpi\code\code3\out\BearPi-HM_Nano路径下Hi3861_wifiiot_app_allinone.bin)

    梅科尔工作室-#14天鸿蒙设备开发实战#快速入门笔记-鸿蒙开发者社区

  • Auto burn:前面打勾

  • 点击Connect,下方显示Connecting…时,再按一下开发板复位按键,此时Connect按钮变成Disconnect

  • 等待烧录,烧录成功后,下方重新显示Connecting…(如果再按复位按键,代码又会重新烧录),此时点击Disconnect,Disconnect按钮又变回Connect

  • 使用MobaXterm中的串口工具查看日志

    • 左上角->Session->Serial

      梅科尔工作室-#14天鸿蒙设备开发实战#快速入门笔记-鸿蒙开发者社区

    • Serial port:选择端口号,与设备管理器中显示的端口一致

    • Speed(bps):波特率设置为115200

    • 点击OK

    • 再次点击开发板复位按键,日志就会被打印出来,可以看到打印出来Hello World!

      梅科尔工作室-#14天鸿蒙设备开发实战#快速入门笔记-鸿蒙开发者社区

点亮LED灯

如何编写点亮LED灯程序

添加点亮LED灯源码文件

  • 新增my_led文件夹

    在./applications/BearPi/BearPi-HM_Nano/sample路径下新建一个my_led目录,用于存放业务源码文件。

  • 新增led_example.c文件

    在./applications/BearPi/BearPi-HM_Nano/sample/my_led路径下新建一个led_example.c文件,该文件为业务源码文件。

  • 新增BUILD.gn文件

    在./applications/BearPi/BearPi-HM_Nano/sample/my_led路径下新建一个BUILD.gn文件,该文件为业务源码编译脚本。

编写点亮LED灯业务代码

在led_example.c中新建业务入口函数led_example,并实现业务逻辑。并在代码最下方,使用HarmonyOS启动恢复模块接口APP_FEATURE_INIT()启动业务。
源码如下:

#include "ohos_init.h"  // 引入头文件
#include "wifiiot_gpio.h"
#include "wifiiot_gpio_ex.h"

void led_example(void)
{
    GpioInit();  // 初始化Gpio
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_2, WIFI_IOT_IO_FUNC_GPIO_2_GPIO);  // 设置管脚复用功能,第一个参数是LED灯接在芯片上的引脚号,第二个参数将该GPIO设置为普通GPIO
    GpioSetDir(WIFI_IOT_IO_NAME_GPIO_2, WIFI_IOT_GPIO_DIR_OUT);  // 设置WIFI_IOT_IO_NAME_GPIO_2为输出模式

    GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_2, 1);  // 设置WIFI_IOT_IO_NAME_GPIO_2的高低电平,1为高电平,0为低电平
}

APP_FEATURE_INIT(led_example);  // app函数入口,启动led_example

编写编译构建文件BUILD.gn

在./applications/BearPi/BearPi-HM/sample/my_led下的BUILD.gn文件中添加如下代码。

# static_library中指定业务模块的编译结果,为静态库文件libmyled.a,开发者根据实际情况完成填写。
static_library("myled") {  # 此处参数填xxx,静态库文件就是libxxx.a
    # sources中指定静态库.a所依赖的.c文件及其路径,若路径中包含"//"则表示绝对路径(此处为代码根路径),若不包含"//"则表示相对路径。
    sources = [
        "led_example.c"
    ]
    # include_dirs中指定source所需要依赖的.h文件路径。
    include_dirs = [
        "//utils/native/lite/include",  # ohos_init.h
        "//base/iot_hardware/interfaces/kits/wifiiot_lite"  # "wifiiot_gpio.h"与"wifiiot_gpio_ex.h"
    ]
}
  • static_library中指定业务模块的编译结果,为静态库文件libmyled.a,开发者根据实际情况完成填写。
  • sources中指定静态库.a所依赖的.c文件及其路径,若路径中包含"//“则表示绝对路径(此处为代码根路径),若不包含”//" 则表示相对路径。
  • include_dirs中指定source所需要依赖的.h文件路径。

编写模块BUILD.gn文件,指定需参与构建的特性模块。

在./applications/BearPi/BearPi-HM/sample下的BUILD.gn文件中添加如下代码(可以将features中原有的模块注释掉,添加上"my_app:myapp",

如何编译烧录点亮LED灯程序

  • 首先打开MobaXterm工具,登录服务器后,进入源码目录code3下
  • 输入hpm dist,开始编译源码,如果出现BUILD SUCCESS字样,说明编译成功
  • 使用HiBurn工具烧录源码(先将电脑与开发板连接起来,通过设备管理器->端口查看端口)
  • COM:端口的选择要和设备管理器中显示的端口一致
  • 波特率选择921600,左上角setting->Com setting->Baud
  • Select File:烧录文件选择刚才生成的bin文件(\home\bearpi\code\code3\out\BearPi-HM_Nano路径下Hi3861_wifiiot_app_allinone.bin)
  • Auto burn:前面打勾
  • 点击Connect,下方显示Connecting…时,再按一下开发板复位按键,此时Connect按钮变成Disconnect
  • 等待烧录,烧录成功后,下方重新显示Connecting…(如果再按复位按键,代码又会重新烧录),此时点击Disconnect,Disconnect按钮又变回Connect
  • 点击复位按键,LED灯被点亮

更改源代码,LED灯闪烁

更改LED灯源码文件

  • 首先添加unistd.h头文件,需要使用其中的usleep函数,之后在for循环中使用,实现LED闪烁
#include "ohos_init.h"  // 引入头文件
#include "unistd.h"
#include "wifiiot_gpio.h"
#include "wifiiot_gpio_ex.h"

void led_example(void)
{
    GpioInit();  // 初始化Gpio
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_2, WIFI_IOT_IO_FUNC_GPIO_2_GPIO);  // 设置管脚复用功能,第一个参数是LED灯接在芯片上的引脚号,第二个参数将该GPIO设置为普通GPIO
    GpioSetDir(WIFI_IOT_IO_NAME_GPIO_2, WIFI_IOT_GPIO_DIR_OUT);  // 设置WIFI_IOT_IO_NAME_GPIO_2为输出模式

    // LED灯闪烁10次
    for (int i = 0; i < 10; i++)
    {
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_2, 1);  // 设置WIFI_IOT_IO_NAME_GPIO_2的高低电平,1为高电平,0为低电平
        usleep(1000000);  // 延时1000000微秒
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_2, 0);  // 设置WIFI_IOT_IO_NAME_GPIO_2的高低电平,0为高电平,0为低电平
        usleep(1000000);  // 延时1000000微秒
    }
    
    GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_2, 1);  // 设置WIFI_IOT_IO_NAME_GPIO_2的高低电平,1为高电平,0为低电平
}

APP_FEATURE_INIT(led_example);  // app函数入口,启动led_example

**疑惑:**新增了unistd.h头文件,没有在BUILD.gn中添加新依赖的.h文件路径,但是没有报错

重新烧录

  • 点击Connect,下方显示Connecting…时,再按一下开发板复位按键,此时Connect按钮变成Disconnect
  • 等待烧录,烧录成功后,下方重新显示Connecting…(如果再按复位按键,代码又会重新烧录),此时点击Disconnect,Disconnect按钮又变回Connect
  • 点击复位按键,LED灯闪烁10次后常亮

HarmonyOS编译框架介绍

ninja编译工具

简介

在Unix/Linux下通常使用Makefile来控制代码的编译,但是Makefile对于比较大的项目有时候会比较慢,代码在编译都变成了程序员放松的借口了。所以这个Google的程序员在开发Chrome的时候因为忍受不了Makefile的速度,自己重新开发出来一套新的控制编译的工具叫作Ninja,Ninja相对于Makefile这套工具更注重于编译速度。除了Chrome现在还有一些其他的比较大的项目也在开始使用Ninja。

如何编译模块

梅科尔工作室-#14天鸿蒙设备开发实战#快速入门笔记-鸿蒙开发者社区

代码运行逻辑

初始化入口是位于vendor\hisi\hi3861\hi3861\app\wifiiot_app\src路径下的app_main.c,入口函数是app.main,最后执行HOS_SystemInit();,这个函数里面又封装了几个函数,其中如果没有函数SYS_INIT(service);则不会出现相应的结果。

梅科尔工作室-#14天鸿蒙设备开发实战#快速入门笔记-鸿蒙开发者社区

HarmonyOS CMSIS-RTOS2接口简介

参考:【鸿蒙2.0设备开发教程】小熊派HarmonyOS 鸿蒙·季 开发教程_哔哩哔哩_bilibili

什么是CMSIS-RTOS2接口

CMSIS-RTOS2接口简介

CMSIS是Cortex微控制器软件接口标准(Cortex Microcontroller Software Interface Standard)是ARM和一些编译器厂家以及半导体厂家共同遵循的一套标准,是由ARM专门针对Cortex-M系列提出的标准。在该标准的约定下,ARM和芯片厂商会提供一些通用的API接口来访问Cortex内核以及一些专用外设,以减少更换芯片以及开发工具等移植工作所带来的金钱以及时间上的消耗。

CMSIS-RTOS2(CMSIS-RTOS API Version 2)是Arm® Cortex®-M 处理器的通用的RTOS接口。为需要RTOS功能的软件组件提供了标准化的API。

CMSIS-RTOS2是一个通用的API,它与底层的RTOS内核无关,写应用程序的程序员在用户代码中调用CMSIS-RTOS2 API函数,可以更方便地将应用程序从一个RTOS到另一个RTOS,使用CMSIS-RTOS2 API的中间件也可以避免很多不必要的移植工作。

鸿蒙是如何封装CMSIS-RTOS2接口

鸿蒙与CMSIS-RTOS2接口联系

鸿蒙在CMSIS-RTOS2接口中封装了LiteOS-m的内核代码

路径位于kernel\liteos_m\components\cmsis\2.0\cmsis_liteos2.c

上层应用或中间件如果要使用LiteOS-m内核,需要通过调用CMSIS-RTOS API 2.0的接口,之后实现内核的一些功能调用

梅科尔工作室-#14天鸿蒙设备开发实战#快速入门笔记-鸿蒙开发者社区

如何使用CMSIS-RTOS2接口

如何使用CMSIS-RTOS2接口

  • 在业务代码中包含"cmsis_os2.h"

  • 通过调用“cmsis_os2.h”中的API函数使用系统相关功能

    梅科尔工作室-#14天鸿蒙设备开发实战#快速入门笔记-鸿蒙开发者社区

更多API介绍可参考:Main Page (arm-software.github.io),以后用到相关接口可在此网站查看

感悟

前面hello world程序与led程序都不是太难,但是在HarmonyOS编译框架介绍这些比较底层的地方听迷糊了,感觉函数之间层层嵌套,不好把握,可能本身就比较晦涩难懂,不过有些地方对我这个初学者来说并不准备深入探究,否则会占用太多的时间,以后更加熟悉之后再进行二刷,效果会更好,现在只需要了解其中的大致流程就可以了,后面如果用到再回头来看。话不多说,继续肝。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
已于2022-8-3 13:57:36修改
1
收藏
回复
举报
回复
    相关推荐