野火Linux开发板接入华为云,Huawei_LiteOS——STM32F1移植(野火开发板)
軟件環(huán)境:Keil 5
Huawei_LiteOS Version:2018.11.21
源代碼下載地址:
移植代碼分享(包含源碼):
1.? 源碼文件及目錄介紹
如圖所示,源碼共有6個(gè)目錄,移植需要使用到的代碼在下面用紅色標(biāo)記:
/arch /arm /arm-mM核中斷、調(diào)度、tick相關(guān)代碼
/common? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?arm核公用的cmsis core接口(這個(gè)可以在keil直接設(shè)置)
/components /cmsisLiteOS提供的cmsis os接口實(shí)現(xiàn)
/connectivity /agent_tiny? ? ? ? ? ? ? ? ? agent_tiny端云互通組件
/lwm2m? ? ? ? ? ? ? ? ? ? ? ?lwm2m協(xié)議實(shí)現(xiàn)
/net /lwip_port? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? lwip驅(qū)動(dòng)及OS適配代碼
/lwip-2.0.3? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?lwip協(xié)議實(shí)現(xiàn)
/security /mbedtls /mbedtls_port? ? ?MBEDTLS的OS適配代碼
/mbedtl-2.6.0? ? ? MBEDTLS協(xié)議實(shí)現(xiàn)
/doc? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 此目錄存放的是LiteOS的使用文檔和API說(shuō)明等文檔
/examples供開(kāi)發(fā)者測(cè)試LiteOS內(nèi)核的demo示例,此目錄存放的是內(nèi)核功能測(cè)試用的相關(guān)用例的代碼
/kernel /base /coreLiteOS基礎(chǔ)內(nèi)核代碼,包括隊(duì)列、task調(diào)度、軟timer、時(shí)間片計(jì)算等功能
/om與錯(cuò)誤處理相關(guān)的文件
/includeLiteOS內(nèi)核內(nèi)部使用的頭文件
/ipcLiteOS中task間通訊的相關(guān)接口,包括事件、信號(hào)量、消息隊(duì)列、互斥鎖等
/memLiteOS中的內(nèi)核內(nèi)存管理的相關(guān)代碼
/misc內(nèi)存對(duì)齊功能以及毫秒級(jí)休眠sleep功能
/extended /tickless低功耗框架代碼
/includeLiteOS開(kāi)源內(nèi)核頭文件
/targets? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 不同內(nèi)核的板端工程代碼(含原廠芯片驅(qū)動(dòng))
由于這里移植的是stm32f1,系統(tǒng)中需要使用到配置文件,在移植時(shí)需要復(fù)制以下目錄中的三個(gè)頭文件:
/targets/STM32F103RB_NUCLEO/OS_CONFIG/(los_builddef.h, los_printf.h,?target_config.h)
/targets/STM32F103RB_NUCLEO也將作為的例程工程進(jìn)行移植的參考和學(xué)習(xí)。
2.? 建立工程
工程可分為三個(gè)文件夾Libraries,Project和User。Libraries存放的是stm32的庫(kù)文件,包括源文件和頭文件;
Project存放的是工程相關(guān)的文件;
User文件夾下包括了main.c,自己寫(xiě)的bsp,以及移植系統(tǒng)需要用到的源碼文件。
若使用到stm32的庫(kù)函數(shù),則需要添加"stm32f10x_conf.h"這一頭文件,并在工程中定義宏“USE_STDPERIPH_DRIVER”和"STM32F10X_HD"。
main.c文件中的main()函數(shù)暫時(shí)先不做任何工作。最后在工程中添加所有使用到的頭文件的目錄。
工程選項(xiàng)中勾選C99mode,否則有些語(yǔ)法編譯時(shí)無(wú)法通過(guò)。
target_config.h文件的頭文件中,將#include "stm32f1xx.h"更改為#include "stm32f10x.h"。
在完成上面的工作后,編譯會(huì)生成兩個(gè)錯(cuò)誤:
值得一提的是,對(duì)例程工程進(jìn)行編譯,發(fā)現(xiàn)例程中的工程編譯后是0警告,而自己移植后的工程編譯出現(xiàn)了8個(gè)警告,明明是相同的文件,怎么會(huì)這樣呢?參考:keil中忽略特定警告的方法,例程工程將警告全部忽略掉了。
3.? 修改啟動(dòng)文件和.sct文件
移植中的啟動(dòng)文件和sct文件對(duì)比源碼的例程工程并沒(méi)有進(jìn)行大幅度的修改簡(jiǎn)化,保證程序運(yùn)行的穩(wěn)定性。但是這兩個(gè)文件相比較于裸機(jī)工程修改的幅度還是很大的,sct文件添加了若干個(gè)加載域進(jìn)行分散加載,啟動(dòng)文件也進(jìn)行了大規(guī)模的修改,以后有機(jī)會(huì)進(jìn)行深入的分析,在本文中則不進(jìn)行討論,因?yàn)樯婕暗降闹R(shí)范圍太大了。本文側(cè)重于移植的有效性。
(之前我也嘗試過(guò)不使用例程工程給的這兩個(gè)文件,自己來(lái)編寫(xiě),能力有限,實(shí)在是辦不到,浪費(fèi)了很多時(shí)間,太打擊了)
在例程工程中的啟動(dòng)文件中,與裸機(jī)的啟動(dòng)文件不同,使用符號(hào)"Image$$ARM_LIB_STACKHEAP$$Base",合并的堆棧/堆區(qū)的方法,對(duì)堆棧進(jìn)行劃分,并定義了了LOS_HEAP_ADDR_END和LOS_HEAP_ADDR_START兩個(gè)地址變量。而原來(lái)的啟動(dòng)文件是將堆棧分開(kāi)進(jìn)行設(shè)置的。另外,例程工程中的啟動(dòng)文件將中斷向量表省略,改成了"boot向量表",縮減了很多,只存有棧指針和Reset_Handler,而將其他的中斷向量成員的定義工作完成在"los_hwi.c"文件中,因此sct也隨之變動(dòng)。本人覺(jué)得這里相比于ucos實(shí)在是麻煩的多,不知道為什么要這么修改。
啟動(dòng)文件的代碼如下:Heap_Size????????????EQU?????0x00000400
AREA????LOS_HEAP,?NOINIT,?READWRITE,?ALIGN=3
__heap_base
Heap_Mem????????????SPACE???Heap_Size
__heap_limit
AREA????LOS_HEAP_INFO,?DATA,?READONLY,?ALIGN=2
IMPORT??|Image$$ARM_LIB_STACKHEAP$$ZI$$Base|
EXPORT??__LOS_HEAP_ADDR_START__
EXPORT??__LOS_HEAP_ADDR_END__
__LOS_HEAP_ADDR_START__
DCD?????__heap_base
__LOS_HEAP_ADDR_END__
DCD?????|Image$$ARM_LIB_STACKHEAP$$ZI$$Base|?-?1
PRESERVE8
THUMB
AREA????RESET,?CODE,?READONLY
IMPORT??||Image$$ARM_LIB_STACKHEAP$$ZI$$Limit||
IMPORT??osPendSV
EXPORT??_BootVectors
EXPORT??Reset_Handler
_BootVectors??????????DCD?????||Image$$ARM_LIB_STACKHEAP$$ZI$$Limit||???????????????;?Top?of?Stack
DCD?????Reset_Handler?????????????????????????????????????????;?Reset?Handler
;?Reset?handler
Reset_Handler
IMPORT??__main
IMPORT??SystemInit
LDR?????R0,?=SystemInit
BLX?????R0
LDR?????R0,?=__main
BX??????R0
ALIGN
END
sct文件對(duì)應(yīng)啟動(dòng)文件的改變主要增加了兩個(gè)加載域:VECTOR和ARM_LIB_STACKHEAP
sct文件代碼如下(地址對(duì)應(yīng)自己的芯片做了修改):LR_IROM1?0x08000000?0x00080000??{????;?load?region?size_region
ER_IROM1?0x08000000?0x00080000??{??;?load?address?=?execution?address
*.o?(RESET,?+First)
*(InRoot$$Sections)
.ANY?(+RO)
*?(LOS_HEAP_INFO)
}
VECTOR?0x20000000?0x400??{????;?Vector
*?(.data.vector)
}
RW_IRAM1?0x20000400?0x0000F800??{??;?RW?data
*?(.data,?.bss)
*?(LOS_HEAP)
}
ARM_LIB_STACKHEAP?0x2000FC00?EMPTY?0x400??{????;LiteOS?MSP
}
}
5.? 完善main()函數(shù)
內(nèi)核代碼移植完畢后,main()函數(shù)就可以跑起來(lái)了。貼出用來(lái)測(cè)試的main()函數(shù)的代碼及相應(yīng)的解釋:int?main(void){
UINT32?uwRet?=?LOS_OK;
LED_Init();???????????????????????//硬件驅(qū)動(dòng)初始化
uwRet?=?LOS_KernelInit();?????????//OS內(nèi)核初始化
if?(uwRet?!=?LOS_OK)
{????????return?LOS_NOK;
}
uwRet?=?create_task1();???????????//創(chuàng)建任務(wù)
if?(uwRet?!=?LOS_OK)
{????????return?LOS_NOK;
}
LOS_Start();??????????????????????//啟動(dòng)OS
}
其中,create_task1()如下所示,主要是填滿TSK_INIT_PARAM_S類型結(jié)構(gòu)體,調(diào)用LOS_TaskCreate函數(shù)進(jìn)行創(chuàng)建:UINT32?create_task1(void){
UINT32?uwRet?=?LOS_OK;
TSK_INIT_PARAM_S?task_init_param;
task_init_param.usTaskPrio?=?1;//任務(wù)優(yōu)先級(jí)
task_init_param.pcName?=?"task1";//任務(wù)名
task_init_param.pfnTaskEntry?=?(TSK_ENTRY_FUNC)task1;//指定任務(wù)入口函數(shù)
task_init_param.uwStackSize?=?LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;//設(shè)置任務(wù)堆棧大小
uwRet?=?LOS_TaskCreate(&g_TestTskHandle,&task_init_param);//調(diào)用任務(wù)創(chuàng)建函數(shù)
if(uwRet?!=LOS_OK)
{????????return?uwRet;
}????return?uwRet;
}
task1主要做的工作是指示燈的狀態(tài)切換:VOID?task1(void){
UINT32?uwRet?=?LOS_OK;
while(1)
{
macLED1_TOGGLE();
uwRet?=?LOS_TaskDelay(1000);//操作系統(tǒng)延時(shí)
if(uwRet?!=LOS_OK)????????return;
}
}
實(shí)驗(yàn)結(jié)果可以看到燈blingbling的閃,閃~閃~閃~
至此,移植工作及測(cè)試全部結(jié)束。
總結(jié)
以上是生活随笔為你收集整理的野火Linux开发板接入华为云,Huawei_LiteOS——STM32F1移植(野火开发板)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: c语言坐标输出图片,tc 如何在指定坐标
- 下一篇: linux dev urandom,Li