HarmonyOS(LiteOs_m) 官方常式移植到STM32初體驗
HarmonyOS(LiteOs_m) 官方常式移植到STM32初體驗
硬體平台
基於正點原子戰艦V3開發板
MCU:STM32F103ZET6
片上SRAM大小:64KBytes
片上FLASH大小:512KBytes
移植準備
IDE軟體:Keil MDK5
串口調試助手
源碼下載
HarmonyOS源碼開源在gitee上
LiteOS_m的源碼倉庫
源碼結構
根文件夾下的arch_spec.md文件內容即源碼結構樹,但該結構樹不是最新,可以看到當前targers文件夾下已經添加了對STM32F1單片機的常式,但該結構樹中並未列出
.
├── components --- 可選組件,可裁剪,依賴kernel
│ ├── cppsupport --- C++支援
│ └── cpup --- CPUP功能
├── kal --- 內核抽象層
│ ├── cmsis --- cmsis標準支援
│ └── posix --- posix標準支援
├── kernel --- 內核最小功能集支援
│ ├── arch --- 硬體架構相關
│ │ ├── arm --- arm32架構
│ │ │ └── cortex-m4 --- cortex-m4架構
│ │ │ └── iar ---
│ │ │ ├── los_atomic.h
│ │ │ ├── los_context.h
│ │ │ ├── los_interrupt.h
│ │ │ └── los_mpu.h
│ │ └── include
│ │ ├── los_arch_atomic.h --- 定義通用arch的原子操作
│ │ ├── los_arch_context.h --- 定義通用arch的上下文切換
│ │ ├── los_arch.h --- 定義通用arch初始化
│ │ └── los_arch_interrupt.h --- 定義通用arch中斷
│ ├── include
│ │ ├── los_config.h --- 功能開關和配置參數
│ │ ├── los_event.h --- 事件
│ │ ├── los_liteos.h --- liteos最小功能集對外提供的頭文件
│ │ ├── los_memory.h --- 堆記憶體管理
│ │ ├── los_mutex.h --- 互斥鎖
│ │ ├── los_queue.h --- 隊列
│ │ ├── los_scheduler.h --- 調度演算法
│ │ ├── los_sem.h --- 訊號量
│ │ ├── los_task.h --- 任務
│ │ └── los_timer.h --- 定時器
│ └── src
├── targets
│ └── targets
│ └── cortex-m4_stm32f429ig_fire-challenger_iar
│ ├── board
│ ├── dprintf.c
│ ├── Libraries
│ ├── main.c
│ ├── project
│ ├── target_config.h --- 板級配置功能開關和配置參數
│ └── Utilities
└── utils
├── include
│ ├── los_compiler.h --- 編譯工具配置,類型定義
│ ├── los_debug.h --- debug,printf相關
│ ├── los_error.h --- 錯誤定義
│ └── los_list.h
└── src
啟動流程
在\targets\cortex-m3_stm32f103_simulator_keil\project文件夾下打開工程文件(los_demo.uvproj)
工程下有三個文件夾:liteos-m、main、component
程式載入時,首先進入liteos-m下的los_startup.s文件,內容如下
PRESERVE8
AREA RESET, CODE, READONLY
THUMB
IMPORT ||Image$$ARM_LIB_STACKHEAP$$ZI$$Limit||
IMPORT HalHwiDefaultHandler
EXPORT _BootVectors
EXPORT Reset_Handler
_BootVectors
DCD ||Image$$ARM_LIB_STACKHEAP$$ZI$$Limit||
DCD Reset_Handler
DCD HalHwiDefaultHandler
DCD HalHwiDefaultHandler
Reset_Handler
CPSID I
IMPORT LOS_HardBootInit
BL LOS_HardBootInit
IMPORT __main
LDR R0, =__main
BX R0
ALIGN
END
可以看出,啟動文件只定義了啟動向量和reset向量,其他的向量在los_interrupt.c中動態載入
通過LOS_HardBootInit跳轉到系統硬體初始化程式碼,對Uart進行初始化(該常式只用到了串口)
void LOS_HardBootInit()
{
UINT32 uwRet = LOS_OK;
uwRet = LOS_UartBaseInit();
if (uwRet != LOS_OK)
{
return ;
}
return ;
}
初始化後回到啟動文件並跳轉到main函數:
LITE_OS_SEC_TEXT_INIT int main(void)
{
unsigned int ret;
//USART_Config();
printf("\n\rhello world!!\n\r");
ret = LOS_KernelInit();
taskSample();
if (ret == LOS_OK) {
LOS_Start();
}
while (1) {
__asm volatile("wfi");
}
}
main函數開始進行了hello world列印,並進行了內核的初始化,最後進行進程測試,創建並運行兩個進程
移植需要的修改
工程中使用自定義.sct文件對各個區進行分散載入,詳細載入文件見\targets\cortex-m3_stm32f103_simulator_keil\project\los_demo.sct(注意路徑,不是output文件夾下的.sct文件,keil在編譯過程中也會產生一個.sct文件),詳細內容如下:
LR_IROM1 0x08000000 0x00200000 { ; load region size_region
ER_IROM1 0x08000000 0x00200000 { ; load address = execution address
los_startup.o (RESET, +First)
*(InRoot$$Sections)
* (+RO)
}
RW_IRAM1 0x20000000 0x00200000 { ; RW data
* (.data, .bss, .data.init)
}
VECTOR 0x20200000 0x400 ; Vector
{
* (.vector)
}
ARM_LIB_STACKHEAP 0x08100000 EMPTY 0x1000
{
}
}
由於片內SRAM和FLASH大小等因素,各段映射地址需要進行相應調整,我修改的映射地址如下(個人習慣):
LR_IROM1 0x08000000 0x00080000 { ; 載入域FLASH起始地址0x08000000 大小0x00080000(512KBytes)
ER_IROM1 0x08000000 0x00080000 { ; 從FLASH中載入程式,所以將程式啟動文件定向到FLASH首地址,其它只讀欄位也定位到這裡
los_startup.o (RESET, +First)
*(InRoot$$Sections)
* (+RO)
}
RW_IRAM1 0x20000000 0x00010000 { ; SRAM起始地址0x20000000 大小0x00010000(64KBytes),其它讀寫段和未初始化變數均定位到SRAM中
* (.data, .bss, .data.init)
}
VECTOR 0x2000E000 0x1000 ; 向量表地址
{
* (.vector)
}
ARM_LIB_STACKHEAP 0x20010000 EMPTY -0x1000 ;堆棧空間,存放在記憶體的高地址向下的一段空間,大小0x1000(4KBytes)
{
}
}
由於SRAM記憶體限制,需要修改OS記憶體池大小
修改位置為\targets\cortex-m3_stm32f103_simulator_keil\target_config.h文件中的OS_SYS_MEM_SIZE宏定義,將記憶體池大小減小,我將其修改為了0x00000D000(52KBytes)
編譯運行
將輸出文件下載進MCU,連接串口波特率設置115200即可輸出helloworld資訊和進程運行資訊