成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

OpenHarmony南向設備應用程序啟動流程分析

系統 OpenHarmony
本文采用倒序的方式,初步梳理了從Hi3861芯片上電到OpenHarmony應用程序啟動運行的流程。

??想了解更多關于開源的內容,請訪問:??

??51CTO 開源基礎軟件社區??

??https://ost.51cto.com??

一、用戶程序示例

以qihang開發板gpio_led程序為例,為何單板上電后LedTask()會自動運行,SYS_RUN宏在背后是如何起作用的?

static void LedTask(void)
{
while (1)
{
IoTGpioSetOutputVal(LED_TASK_GPIO2,1);
usleep(500*1000);
IoTGpioSetOutputVal(LED_TASK_GPIO2,0);
usleep(500*1000);
}
}
static void LedExampleEntry(void)
{
osThreadAttr_t attr;
IoTGpioInit(LED_TASK_GPIO2);
IoTGpioSetDir(LED_TASK_GPIO2,IOT_GPIO_DIR_OUT);
attr.name = "LedTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = LED_TASK_STACK_SIZE;
attr.priority = LED_TASK_PRIO;
if (osThreadNew((osThreadFunc_t)LedTask1, NULL, &attr) == NULL) {
printf("Falied to create LedTask!\n");
}
}
SYS_RUN(LedExampleEntry);

二、第二階段(應用)啟動流程

在上一篇文章中"OpenHarmony南向設備開發建構編譯分析",有提到qihang板產品配置文件中相關子系統及組件如下:

vendor/isoftstone/qihang/config.json。

......
{
"subsystem": "distributedschedule", #分布式任務調度子系統
"components": [
{ "component": "samgr_lite", "features":[] }
]
},
{
"subsystem": "startup",
"components": [
{ "component": "bootstrap_lite", "features":[] }, #bootstrap啟動引導
{ "component": "syspara_lite", "features": #提供系統屬性讀寫接口
[
"enable_ohos_startup_syspara_lite_use_thirdparty_mbedtls = false"
]
}
]
},
......

可以看到,qihang板使用startup子系統中的bootstrap_lite組件和syspara_lite組件。重點看一下bootstrap_lite組件,位于SDK的base/startup/bootstrap_lite目錄。引用該組件的readme文件說明如下:

bootstrap啟動引導組件,提供了各服務和功能的啟動入口標識。在SAMGR啟動時,會調用boostrap標識的入口函數,并啟動系統服務。

samgr_lite組件是針對Hi3861這類硬件資源有限的輕量化系統服務框架,代碼位于foundation/distributedschedule/samgr_lite目錄。該組件的功能引用如下:

系統服務框架基于面向服務的架構,提供了服務開發、服務的子功能開發、對外接口的開發、以及多服務共進程的開發框架。

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

hi_void app_main(hi_void)
{
hi_flash_partition_table *ptable = HI_NULL;
peripheral_init();
peripheral_init_no_sleep();
hi_u32 ret = hi_factory_nv_init(HI_FNV_DEFAULT_ADDR, HI_NV_DEFAULT_TOTAL_SIZE, HI_NV_DEFAULT_BLOCK_SIZE);
hi_flash_partition_init();
ptable = hi_get_partition_table();
hi_nv_init(ptable->table[HI_FLASH_PARTITON_NORMAL_NV].addr, ptable->table[HI_FLASH_PARTITON_NORMAL_NV].size,
HI_NV_DEFAULT_BLOCK_SIZE);
hi_fs_init();
(hi_void)hi_event_init(APP_INIT_EVENT_NUM, HI_NULL);
hi_sal_init();
hi_syserr_watchdog_debug(HI_FALSE);
hi_syserr_record_crash_info(HI_TRUE);
hi_lpc_init();
hi_lpc_register_hw_handler(config_before_sleep, config_after_sleep);
hi_at_init();
tcpip_init(NULL, NULL);
hi_wifi_init(APP_INIT_VAP_NUM, APP_INIT_USR_NUM);
app_demo_task_release_mem(); /* 釋放系統棧內存所使用任務 */
hilink_main();
OHOS_Main();
}

device/soc/hisilicon/hi3861v100/sdk_liteos/app/wifiiot_app/src/ohos_main.c。

void OHOS_Main()
{
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();
}
#define SYS_INIT(name) \
do { \
SYS_CALL(name, 0); \
} while (0)
#define SYS_CALL(name, step) \
do { \
InitCall *initcall = (InitCall *)(SYS_BEGIN(name, step)); \
InitCall *initend = (InitCall *)(SYS_END(name, step)); \
for (; initcall < initend; initcall++) { \
(*initcall)(); \
} \
} while (0)
#define SYS_BEGIN(name, step) \
({ extern InitCall __zinitcall_sys_##name##_start; \
InitCall *initCall = &__zinitcall_sys_##name##_start; \
(initCall); \
})
#define SYS_END(name, step) \
({ extern InitCall __zinitcall_sys_##name##_end; \
InitCall *initCall = &__zinitcall_sys_##name##_end; \
(initCall); \
})
#define MODULE_INIT(name) \
do { \
MODULE_CALL(name, 0); \
} while (0)
#define MODULE_CALL(name, step) \
do { \
InitCall *initcall = (InitCall *)(MODULE_BEGIN(name, step)); \
InitCall *initend = (InitCall *)(MODULE_END(name, step)); \
for (; initcall < initend; initcall++) { \
(*initcall)(); \
} \
} while (0)
#define MODULE_BEGIN(name, step) \
({ extern InitCall __zinitcall_##name##_start; \
InitCall *initCall = &__zinitcall_##name##_start; \
(initCall); \
})
#define MODULE_END(name, step) \
({ extern InitCall __zinitcall_##name##_end; \
InitCall *initCall = &__zinitcall_##name##_end; \
(initCall); \
})

foundation/distributedschedule/samgr_lite/samgr/source/samgr_lite.c。

void SAMGR_Bootstrap(void)
{
SamgrLiteImpl *samgr = GetImplement();
WDT_Reset(WDG_SVC_BOOT_TIME);
Vector initServices = VECTOR_Make(NULL, NULL);
MUTEX_Lock(samgr->mutex);
samgr->status = TO_NEXT_STATUS(samgr->status);
int16 size = VECTOR_Size(&(samgr->services));
int16 i;
for (i = 0; i < size; ++i) {
ServiceImpl *serviceImpl = (ServiceImpl *)VECTOR_At(&(samgr->services), i);
VECTOR_Add(&initServices, serviceImpl);
}
MUTEX_Unlock(samgr->mutex);
InitializeAllServices(&initServices);
VECTOR_Clear(&initServices);
InitCompleted();
}

在用戶應用程序組件的代碼中,會包含下述聲明:

APP_FEATURE_INIT(MQTTDemo);
SYS_RUN(LedExampleEntry);

上述宏的說明引用如下:

/**
@brief Identifies the entry for initializing and starting an application-layer service by the
priority 2.
This macro is used to identify the entry called at the priority 2 of the application-layer
service phase of the startup process. \n
@param func Indicates the entry function for initializing and starting an application-layer
service. The type is void (*)(void).
*/
#define APP_SERVICE_INIT(func) LAYER_INITCALL_DEF(func, app_service, “app.service”)
/**
@brief Identifies the entry for initializing and starting a system running phase by the
priority 2.
This macro is used to identify the entry called at the priority 2 in the system startup
phase of the startup process. \n
@param func Indicates the entry function for initializing and starting a system running phase.
The type is void (*)(void).
#define SYS_RUN(func) LAYER_INITCALL_DEF(func, run, “run”)
*/

總結以上分析,程序第二階段啟動流程如下圖圖所示:

OpenHarmony南向設備應用程序啟動流程分析-開源基礎軟件社區

三、第一階段(上電)啟動流程

請參考本文最后延申閱讀第二篇文章的具體介紹,程序加載由3個boot程序前后配合完成:

romboot:

  • 芯片內部自帶的上電引導程序,引導loaderboot。

loaderboot (device/soc/hisilicon/hi3861v100/sdk_liteos/boot/loaderboot):

  • 與HiBurn通訊,下載鏡像到flash。
  • 燒寫EFUSE(芯片配置信息)。
  • 校驗并引導flashboot。

flashboot (device/soc/hisilicon/hi3861v100/sdk_liteos/boot/flashboot):

  • 升級固件。
  • 校驗并引導固件(主程序)。

loaderboot/common/cmd_loop.c 定義了從hiburn接收并處理的操作:

const loader_cmd g_loader_cmdtable[LOADER_CMD_MAX] = {
{ CMD_DL_IMAGE, loader_download_image },
{ CMD_BURN_EFUSE, loader_burn_efuse },
{ CMD_UL_DATA, loader_upload_data },
{ CMD_READ_EFUSE, loader_read_efuse },
{ CMD_FLASH_PROTECT, loader_flash_protect },
{ CMD_RESET, loader_reset },
{ CMD_FACTORY_IMAGE, loader_download_image },
{ CMD_VERSION, loader_burn_version},
};

其中:

loader_download_image就是接收hiburn傳來的升級文件,并燒錄到flash中。

flashboot/startup目錄下有兩個重要文件:

  • riscv_init_flshboot.S 匯編語言格式,RISC-V啟動代碼。
  • main.c。
#define KERNEL_START_ADDR   0x40D3C0
boot_kernel(KERNEL_START_ADDR);
global_reset();
hi_void boot_kernel(uintptr_t kaddr)
{
__asm__ __volatile__("ecall"); /* switch U-MODE -> M-MODE */
hi_void (*entry)(hi_void) = (hi_void*)(kaddr);
entry();
}

在最后build應用生成的map文件,可看到內存布局如下:

Name             Origin             Length             Attributes
BIN 0x000000000040d3c0 0x0000000000200000 xr
ROM_TEXT 0x00000000003b8000 0x00000000000457e0 xr
ROM_DATA0 0x000000000011d7c0 0x0000000000000020 xrw
ROM_DATA1 0x000000000011d7e0 0x00000000000006e8 xrw
ROM_BSS 0x000000000011a9c0 0x0000000000002e00 xrw
STACK 0x00000000001185c0 0x0000000000002400 rw
CHECK_INFO 0x000000000011dfc0 0x0000000000000040 rw
FLASH 0x000000000040d3c0 0x00000000001f2c40 xrw
PATCH_BSS 0x00000000000d8000 0x0000000000000400 xrw
RAM 0x00000000000d8400 0x00000000000401c0 xrw
EXTERN_ROM_DATA1_BSS 0x000000000011dec8 0x00000000000000f8 xrw
*default* 0x0000000000000000 0xffffffffffffffff

.entry.text 0x000000000040d3c0 0x4 build/libs/hi3861/release/no_mesh/liblitekernel_flash.a(los_startup.o)
0x000000000040d3c0 _start
0x000000000040d3e0 . = ALIGN (0x20)

對比可以看到,KERNEL_START_ADDR與應用程序的起始地址一致,基本可推斷flashboot最后操作為調用應用程序。通過ecall指令,實現RISC-V處理器( Hi3861使用 )從User Mode( 禁止不可信代碼執行特權指令 )切換為Machine Mode( 最高特權模式 )。

四、小結

本文采用倒序的方式,初步梳理了從Hi3861芯片上電到OpenHarmony應用程序啟動運行的流程。還有很多內容都沒有涉及,包括芯片安全啟動,Flash的存儲分布等,boot部分說明也比較粗淺。

??想了解更多關于開源的內容,請訪問:??

??51CTO 開源基礎軟件社區??

??https://ost.51cto.com??。

責任編輯:jianghua 來源: 鴻蒙社區
相關推薦

2010-11-23 10:51:45

UI交互設計產品管理

2023-09-19 15:14:59

鴻蒙Watchdog

2023-09-06 15:31:19

GPIO鴻蒙

2023-09-06 15:27:22

ADC鴻蒙

2023-09-19 15:21:33

RTC鴻蒙

2009-10-21 09:38:34

VB QuickSor

2022-08-19 10:54:47

操作系統鴻蒙

2011-08-05 13:49:53

iPhone 應用 開發

2009-09-27 10:37:01

Java應用程序Hibernate

2023-04-03 15:51:47

2021-11-24 09:00:00

云計算開發應用

2010-08-10 15:26:38

Flex應用程序

2014-06-19 14:30:28

Android應用程序進程啟動

2014-06-19 14:54:11

Android應用程序進程啟動

2014-06-19 14:59:40

Android應用程序進程啟動

2014-06-20 11:20:37

Android應用程序進程啟動

2014-06-19 14:25:04

Android應用程序進程啟動

2014-06-20 11:05:56

Android應用程序進程啟動

2014-06-20 11:09:35

Android應用程序進程啟動

2014-06-20 11:24:34

Android應用程序進程啟動
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩精品一区二区三区视频播放 | 99精品久久久久久久 | 成人精品一区二区三区 | 黄色网址在线播放 | 久久亚洲精品久久国产一区二区 | 免费黄色在线观看 | 久久亚洲精品国产精品紫薇 | 精品视频在线观看 | 亚洲成人一区二区三区 | 久久精品色欧美aⅴ一区二区 | 久久久久久久亚洲精品 | 亚洲首页| 久久av一区二区 | 国产精品久久久久久久久免费 | 精品国产乱码 | 九久久 | 中文字幕一区在线观看视频 | av一区二区三区四区 | 久久久久亚洲 | 91国内视频在线 | 美国黄色毛片 | 91麻豆精品国产91久久久资源速度 | 极情综合网| 一区二区三区电影在线观看 | 亚洲精品久久久9婷婷中文字幕 | 日韩激情网 | 在线中文字幕日韩 | 成人国产在线观看 | 日韩成人在线播放 | 精品国产一区二区三区观看不卡 | 欧美日韩精品一区二区天天拍 | 国产欧美日韩一区 | 日韩毛片播放 | 国产一区二区免费电影 | 午夜在线观看视频 | 亚洲男人的天堂网站 | 亚洲欧美激情网 | 欧美综合一区二区三区 | 国产视频精品在线观看 | 日日摸日日碰夜夜爽亚洲精品蜜乳 | 成人小视频在线观看 |