OpenHarmony轻量系统开发【4】编写第一个程序、启动流程分析

server/2024/9/24 15:17:12/

摘要:本文简单介绍如何编写第一个hello world程序,以及程序是被执行的

适合群体:适用于Hi3861开发板,启动流程分析

4.1编写第一个程序

编写一个hello world程序比较简单,可以参考官网:

https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/quick-start/quickstart-lite-steps-hi3861-application-framework.md

本文在这里做下总结:

(1)确定目录结构。

开发者编写业务时,务必先在./applications/sample/wifi-iot/app路径下新建一个目录(或一套目录结构),用于存放业务源码文件。

例如:在app下新增业务my_first_app,其中hello_world.c为业务代码,BUILD.gn为编译脚本,具体规划目录结构如下:

.
└── applications└── sample└── wifi-iot└── app│── my_first_app│  │── hello_world.c│  └── BUILD.gn└── BUILD.gn

(2)编写业务代码。

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

#include <stdio.h>
#include "ohos_init.h"
#include "ohos_types.h"void HelloWorld(void)
{printf("___________>>>>>>>>>>>>>>>>>>>> [DEMO] Hello world.\n");
}
SYS_RUN(HelloWorld);

(3)编写用于将业务构建成静态库的BUILD.gn文件。

如步骤1所述,BUILD.gn文件由三部分内容(目标、源文件、头文件路径)构成,需由开发者完成填写。以my_first_app为例,需要创建./applications/sample/wifi-iot/app/my_first_app/BUILD.gn,并完如下配置。

static_library("myapp") {sources = ["hello_world.c"]include_dirs = ["//utils/native/lite/include"]
}

static_library中指定业务模块的编译结果,为静态库文件libmyapp.a,开发者根据实际情况完成填写。

sources中指定静态库.a所依赖的.c文件及其路径,若路径中包含"//“则表示绝对路径(此处为代码根路径),若不包含”//"则表示相对路径。

include_dirs中指定source所需要依赖的.h文件路径。

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

配置./applications/sample/wifi-iot/app/BUILD.gn文件,在features字段中增加索引,使目标模块参与编译。features字段指定业务模块的路径和目标,以my_first_app举例,features字段配置如下。

import("//build/lite/config/component/lite_component.gni")lite_component("app") {features = ["my_first_app:myapp",]}

my_first_app是相对路径,指向./applications/sample/wifi-iot/app/my_first_app/BUILD.gn。

myapp是目标,指向./applications/sample/wifi-iot/app/my_first_app/BUILD.gn中的static_library(“myapp”)。

4.2 Hi3861相关代码结构

目前hi3861用的是liteos-m内核,但是目前hi3681的liteos-m被芯片rom化了,固化在芯片内部了。所以在harmonyOS代码是找不到hi3861的内核部分。

但是这样不妨碍我们去理清hi3861的其他代码结构。

hi3861平台配置文件位于:

vendor\hisilicon\hispark_pegasus\config.json

可以看到该配置文件有很多内容,

第一段这里指定了产品名称、版本、使用的内核类型

下面这里都是子系统:

其中我们重点关注这几个模块:

(1)applications:应用子系统

路径:applications/sample/wifi-iot/app

作用:这个路径下存放了hi3681编写的应用程序代码,例如我们刚刚写得hello world 代码就放在这个路径下。

(2)iot_hardware:硬件驱动子系统

头文件路径: base\iot_hardware\peripheral\interfaces\kits

具体代码路径,由device\board\hisilicon\hispark_pegasus\liteos_m\config.gni文件中指定:

config.gni文件内容较多,后续会一一解读

作用:存放了 hi3681 芯片相关的驱动、例如spi、gpio、uart等。

(3)xts:xts测试子系统。

这里我们先不要xts子系统,不然每次开机后,系统都要跑xts认证程序,影响我们后面测试,我们先注删除,如下:

4.3 Hi3861启动流程

由于hi3681的liteos-m被芯片rom化了,固化在芯片内部了。所以我们主要看内核启动后的第一个入口函数。

代码路径:

device\soc\hisilicon\hi3861v100\sdk_liteos\app\wifiiot_app\src\app_main.c

hi_void app_main(hi_void)
{
#ifdef CONFIG_FACTORY_TEST_MODEprintf("factory test mode!\r\n");
#endifconst hi_char* sdk_ver = hi_get_sdk_version();printf("sdk ver:%s\r\n", sdk_ver);printf("_____>>>>>>> lza %s %d\r\n", __FILE__, __LINE__);hi_flash_partition_table *ptable = HI_NULL;peripheral_init();peripheral_init_no_sleep();#ifndef CONFIG_FACTORY_TEST_MODEhi_lpc_register_wakeup_entry(peripheral_init);
#endifhi_u32 ret = hi_factory_nv_init(HI_FNV_DEFAULT_ADDR, HI_NV_DEFAULT_TOTAL_SIZE, HI_NV_DEFAULT_BLOCK_SIZE);if (ret != HI_ERR_SUCCESS) {printf("factory nv init fail\r\n");}/* partion table should init after factory nv init. */ret = hi_flash_partition_init();if (ret != HI_ERR_SUCCESS) {printf("flash partition table init fail:0x%x \r\n", ret);}ptable = hi_get_partition_table();ret = hi_nv_init(ptable->table[HI_FLASH_PARTITON_NORMAL_NV].addr, ptable->table[HI_FLASH_PARTITON_NORMAL_NV].size,HI_NV_DEFAULT_BLOCK_SIZE);if (ret != HI_ERR_SUCCESS) {printf("nv init fail\r\n");}#ifndef CONFIG_FACTORY_TEST_MODEhi_upg_init();
#endif/* if not use file system, there is no need init it */hi_fs_init();(hi_void)hi_event_init(APP_INIT_EVENT_NUM, HI_NULL);hi_sal_init();/* 此处设为TRUE后中断中看门狗复位会显示复位时PC值,但有复位不完全风险,量产版本请务必设为FALSE */hi_syserr_watchdog_debug(HI_FALSE);/* 默认记录宕机信息到FLASH,根据应用场景,可不记录,避免频繁异常宕机情况损耗FLASH寿命 */hi_syserr_record_crash_info(HI_TRUE);hi_lpc_init();hi_lpc_register_hw_handler(config_before_sleep, config_after_sleep);#if defined(CONFIG_AT_COMMAND) || defined(CONFIG_FACTORY_TEST_MODE)ret = hi_at_init();if (ret == HI_ERR_SUCCESS) {hi_at_sys_cmd_register();}
#endif/* 如果不需要使用Histudio查看WIFI驱动运行日志等,无需初始化diag *//* if not use histudio for diagnostic, diag initialization is unnecessary *//* Shell and Diag use the same uart port, only one of them can be selected */
#ifndef CONFIG_FACTORY_TEST_MODE#ifndef ENABLE_SHELL_DEBUG
#ifdef CONFIG_DIAG_SUPPORT(hi_void)hi_diag_init();
#endif
#else(hi_void)hi_shell_init();
#endiftcpip_init(NULL, NULL);
#endifret = hi_wifi_init(APP_INIT_VAP_NUM, APP_INIT_USR_NUM);if (ret != HISI_OK) {printf("wifi init failed!\n");} else {printf("wifi init success!\n");}app_demo_task_release_mem(); /* 释放系统栈内存所使用任务 */#ifndef CONFIG_FACTORY_TEST_MODEapp_demo_upg_init();
#ifdef CONFIG_HILINKret = hilink_main();if (ret != HISI_OK) {printf("hilink init failed!\n");} else {printf("hilink init success!\n");}
#endif
#endifOHOS_Main();
}

app_main一开始打印了 SDK版本号,中间还会有一些初始化动作,最后一行会调用OHOS_Main();

该函数原型如下:

void OHOS_Main()
{
#if defined(CONFIG_AT_COMMAND) || defined(CONFIG_FACTORY_TEST_MODE)hi_u32 ret;ret = hi_at_init();if (ret == HI_ERR_SUCCESS) {hi_u32 ret2 = hi_at_register_cmd(G_OHOS_AT_FUNC_TBL, OHOS_AT_FUNC_NUM);if (ret2 != HI_ERR_SUCCESS) {printf("Register ohos failed!\n");}}
#endifOHOS_SystemInit();
}

最后,OHOS_SystemInit函数进行鸿蒙系统的初始化。我们进去看下初始化做了哪些动作。

路径:base\startup\bootstrap_lite\services\source\system_init.c

void OHOS_SystemInit(void)
{MODULE_INIT(bsp);MODULE_INIT(device);MODULE_INIT(core);SYS_INIT(service);SYS_INIT(feature);MODULE_INIT(run);SAMGR_Bootstrap();} 

我们可以看到主要是初始化了 一些相关模块、系统,包括有bsp、device(设备)。其中最终的是MODULE_INIT(run);

它负责调用了,所有run段的代码,那么run段的代码是哪些呢?

事实上就是我们前面application中使用SYS_RUN() 宏设置的函数名。

还记得我们前面写的hello world应用程序吗?

#include "ohos_init.h"
#include "ohos_types.h"void HelloWorld(void)
{printf("[DEMO] Hello world.\n");
}SYS_RUN(HelloWorld);

也就是说所有用SYS_RUN() 宏设置的函数都会在使用MODULE_INIT(run); 的时候被调用。

为了验证这一点,我们可以加一些打印信息,如下:

我们重新编译后烧录。打开串口查看打印信息,如下:

可以看到在27行之后,就打印 hello world的信息。符合预期。

为了能让大家更好的学习鸿蒙(HarmonyOS NEXT)开发技术,这边特意整理了《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

鸿蒙开发学习手册》:

如何快速入门:https://qr21.cn/FV7h05

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. ……

开发基础知识:https://qr21.cn/FV7h05

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

基于ArkTS 开发:https://qr21.cn/FV7h05

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. ……

鸿蒙开发面试真题(含参考答案):https://qr18.cn/F781PH

鸿蒙开发面试大盘集篇(共计319页):https://qr18.cn/F781PH

1.项目开发必备面试题
2.性能优化方向
3.架构方向
4.
鸿蒙开发系统底层方向
5.鸿蒙音视频开发方向
6.鸿蒙车载开发方向
7.鸿蒙南向开发方向


http://www.ppmy.cn/server/6977.html

相关文章

K8s ingress-controller中nginx文件上传大小的限制

# 20、K8s ingress-controller中nginx文件上传大小的限制 问题&#xff1a;1.应用程序中上传文件文件出错&#xff0c;页面提示“您上传的文件太大了&#xff0c;请压缩图片后重试。” 2.通过F12 可以看到&#xff0c;后台提示 403错误&#xff0c;可以看到出错是由于nginx的限…

Linux发行版

Linux发行版&#xff08;Linux Distribution&#xff0c;简称“distro”&#xff09;是基于Linux内核的操作系统&#xff0c;它包括了Linux内核以及一套预选的应用程序/软件、图形用户界面&#xff08;GUI&#xff09;、管理工具、安装程序、文档以及支持服务。Linux发行版旨在…

【华为OD机试】虚拟理财游戏【C卷|100分】

【华为OD机试】-真题 !!点这里!! 【华为OD机试】真题考点分类 !!点这里 !! 题目描述 在一款虚拟游戏中生活,你必须进行投资以增强在虚拟游戏中的资产以免被淘汰出局。 现有一家Bank,它提供有若干理财产品 m 个,风险及投资回报不同,你有 N(元)进行投资,能接收的总风险…

spring-core:注解合成(AnnotationUtils.synthesizeAnnotation)的使用示例

spring-core提供的AnnotationUtils工具功能很强大&#xff0c;也很灵活&#xff0c;其中的synthesizeAnnotation方法我一起没搞明白它的使用场景&#xff0c;直到今天我的工作用上了它&#xff0c;学会它的使用。 synthesizeAnnotation方法说明&#xff1a; 通过将包含了注解字…

python爬虫笔记1

1 爬虫介绍 爬虫概述&#xff1a; 获取网页并提取和保存信息的自动化程序 1.获取网页 2.提取信息 css选择器 xpath 3.保存数据&#xff08;大数据时代&#xff09; 4.自动化 爬虫&#xff08;资产收集&#xff0c;信息收集&#xff09; 漏扫&#xff08;帮我发现漏洞&#xff…

关于Android绘制这一遍就够了

Android绘制基础 Android平台提供了一套完整的UI框架&#xff0c;其中包括了绘制组件和绘制API。在Android中&#xff0c;绘制主要涉及到两个核心概念&#xff1a;Canvas和Paint。 Canvas Canvas是Android中的一个类&#xff0c;它代表了绘图的画布。你可以在这个画布上进行…

大模型入门相关文章

1.了解国内外大模型发展现状188个大模型和20个开源基础模型&#xff0c;《2023大模型产业发展白皮书》全面解析国内外大模型发展情况 - 知乎 (zhihu.com) 2.垂直领域&#xff0c;美妆大模型 关于懂美学的视觉大模型&#xff0c;我们问了美图 21 个问题 - 知乎 (zhihu.com) 3…

【linux运维】系统常见管理命令

系列综述&#xff1a; &#x1f49e;目的&#xff1a;本系列是个人整理为了学习基本的shell编程和linux命令&#xff0c;整理期间苛求每个知识点&#xff0c;平衡理解简易度与深入程度。 &#x1f970;来源&#xff1a;材料主要源于b站大学——linux运维课程进行的&#xff0c;…