【LiteOS】Liteos移植篇



前言

OpenHarmony來勢洶洶,第一次開源,僅支持LiteOS-a,所以,在此有必要學習一下LiteOS。或許工作上用不上Harmony,但是,星星之火可以燎原,助力完善 lot 生態應該可以。那就從 MCU 開始吧,移植 LiteOS。

鏈接

參考

  • 野火
  • 上面鏈接

筆錄草稿

  • los_init.c中的大部分內容已經移到了los_config.c里面了,可以看那里面的內容
  • 使用軟件定時器則必須要使用消息隊列,否則不會使用軟件定時器。

移植(2018)

  • 在移植的時候暫時不建議獲取最新(不要使用202003)后推送的版本)的版本默認只支持 GCC ,且 MDK 官方移植教程未出。所以只能在 github 獲取源碼來移植 LiteRTOS。(時間截止於 20200922*)

  • 移植方案分為兩種:

    • 硬中斷接管方案
    • 不接管中斷方案
  • 由於硬中斷接管方案移植難度比不接管中斷方案大,所以,本次筆記記錄不接管中斷方案。

移植獲取 (Cortex-M 內核

* RAM 大於 8K
* ROM 大於 20K
  • 裸機空工程
    • 能正常運行 main 函數
    • 本次移植基於 STM32F103VCT6
  • LiteOS 源碼
    • 時間截止於 20200922 ,不推薦獲取官方最新推送的源碼,因為最新版本默認只支持 GCC ,且 MDK 官方移植教程未出。(可嘗試獲取最新版本+舊版本補全
    • 建議獲取 2018 年左右推送的版本。
  • 本教程源碼源於2018年版本,也會對比新版本做說明。

主要文件夾分析

官方代碼導讀 *該鏈接為最新版本的文件分析,與下面的會有所不同,具體按照實際下載版本導讀 *

  • arch
    • arm
      • arm-m:M 核中斷、調度、tick 相關代碼
      • common:arm 核公用的 cmsis core 接口
  • components
    • cmsis:LiteOS 提供的 cmsis os 接口實現
  • kernel
    • base
      • core:LiteOS 基礎內核代碼文件,包括隊列、task 調度、軟 timer、時間片等功能
      • OM:與錯誤處理相關的文件
      • include:LiteOS 內核內部使用的頭文件
      • ipc:LiteOS 中 ipc 通訊相關的代碼文件,包括事件、信號量、消息隊列、互斥量等
      • mem:LiteOS 中的內核內存管理的相關代碼
      • misc:內存對齊功能以及毫秒級休眠 sleep 功能
    • include:LiteOS 開源內核頭文件
    • extenden
      • ticless:低功耗框架代碼

移植過程

1. 拷貝文件

  • 在工程路徑上創建 LiteOS 文件夾
  • 拷貝 LiteOS 源碼中的 arch、cmsisLiteOS 提供的 cmsis os 接口實現
    kernel 三個文件夾到 工程 LiteOS 文件夾中。
  • 拷貝 LiteOS源碼下對應 demosOS_CONFIG 文件夾到上述路徑。
    • OS_CONFIG 該文件夾主要配置文件,用於內核配置和裁剪。
  • 拷貝 keil 安裝目錄下的一個文件夾到工程 工程\Libraries\CMSIS
    • 安裝路徑目錄下的一個文件夾,其參考路徑為:D:\Keil_v5\ARM\Pack\ARM\CMSIS\4.2.0\CMSIS\Include
    • 移植理由
      • 避免其它電腦在移植過程中沒有相關頭文件而引起的編譯錯誤。

2. 創建工程分組

新建 4 個工程分組:

  • LiteOS/cmsis
    • 添加 cmsis_LiteOS.c 文件
  • LiteOS/kernel所有需要用到的 .c 文件
    • \LiteOS\kernel\base\core 所有.c 文件
    • \LiteOS\kernel\base\ipc 所有.c 文件
    • \LiteOS\kernel\base\mem\bestfit_little 所有.c 文件
    • \LiteOS\kernel\base\mem\common 所有.c 文件
    • \LiteOS\kernel\base\mem\membox 所有.c 文件
    • \LiteOS\kernel\base\misc 所有.c 文件
    • \LiteOS\kernel\base\om 所有.c 文件
    • \LiteOS\kernel\extended\tickless 所有.c 文件
    • \LiteOS\kernel los_init.c
  • LiteOS/arch
    • \LiteOS\arch\arm\arm-m\src 所有.c 文件
    • \LiteOS\arch\arm\arm-m\cortex-m?\keil los_dispatch_keil.S
      • ?:代表當前需要移植到哪一種內核的chip上。如cortex-m3。
  • LiteOS/config
    • \LiteOS\OS_CONFIG
      • los_builddef.h(可選
      • los_printf.h(可選
      • target_config.h

3. 添加頭文件路徑

參考圖片:

4. 兼容 C99 模式

  • 在 target->C/C++->Language/Code Generation 中勾選 C99 Mode
  • 在 target->C/C++->MiscControls 框中輸入 --diag_suppress=1,47,177,186,223,1295
    • 意思是忽略這些編號的警號

5. 內核配置與裁剪(非接管中斷的stm32f103vct6)

  • 主要在 target_config.h 文件上配置,具體內容直接看源碼,這里列出幾個主要的點:
    • 修改頭文件 #include "stm32f1xx.h"#include "stm32f10x.h"
    • OS_SYS_CLOCK
      • 表示 CPU 主頻
      • 如STM32VCT6 配置為 72MHz,即是 72000000
    • LOSCFG_BASE_CORE_TICK_PER_SECOND
      • RTOS 心跳
        • 對於 STM32F10x,一般設置 1ms-10ms,如設置為 1ms,則配置為 1000UL
    • 內存地址
      • BOARD_SRAM_START_ADDR

        • 根據編譯器中 RAM 配置的其實地址設置,這里為 0x20000000。
      • BOARD_SRAM_SIZE_KB

        • 分配給系統使用的內存,即是RTOS管理的總堆棧。這里設置為 20。

6. 屏蔽裸機中的兩個中斷

在 stm32fxxx_it.c 文件中注釋掉 PendSVSysTick 中斷即可。

  • SysTick
    • 主要提供心跳
  • PendSV
    • 該異常可以進入任務調度檢測並進行調度。

7. 完善代碼

本工程基於本人編寫的裸機框架,需要的可以參考。

  • 在 LssAppConfig.h 文件中添加以下頭文件:
/*
*********************************************************************************************************
*                                                 OS
*********************************************************************************************************
*/
#include "target_config.h" 
#include "los_sys.h"
#include "los_typedef.h"
#include "los_task.ph" 
#include "los_sem.h" 
  • 不廢話,直接上寫好的 main.c 文件(看源碼比文字教程方便多了)
    • 主要參考源碼中的
      • 任務創建函數
      • 啟動流程
    • 該源碼的啟動流程采用的是 任務創建任務 的方案。
/**
 ******************************************************************************
 * @file    main.c
 * @author  lss
 * @version V1.0
 * @date    2020-xx-xx
 * @brief  主函數文件
 ******************************************************************************
 * @attention 
 *
 * 實驗平台:LZM
 * Wechat:qabc132321
 ******************************************************************************
 */
  
/*
*********************************************************************************************************
*                                          INCLUDE  
*********************************************************************************************************
*/
/* APP Config File */
#include "LssAppConfig.h"
/* prv */
#include "userMemoryConfig.h"

/* task */
#include "LedTask.h"
/***********************************************************************************************************
*                               板子信息 [注]實時修改
***********************************************************************************************************/
BoardInfo_t BoardInfo = {    .name = "LSS TEST",
                                        .boardType = 0,
                                        .boardNum = 0,
                                        };

/***********************************************************************************************************
*                               固件版本
***********************************************************************************************************/
#if defined(__CC_ARM) // 編譯器相關
const unsigned MCU_VERSION1_ENTRY __attribute__((at(ParameterSectionVEntry))) = SystemProgramAddressEntry;
const unsigned MCU_VERSION1_SIZE     __attribute__((at(ParameterSectionVEntry+0X04))) = SystemProgramAddressSize;
const unsigned CRP_VERSION1_NUM     __attribute__((at(ParameterSectionVEntry+0X08))) = (0x01000000);
#endif

/***********************************************************************************************************
*                               函數聲明
***********************************************************************************************************/
void vStartTask (void );
                                        
/*
**********************************************************************************************************
							句柄變量聲明
**********************************************************************************************************
*/
static UINT32 xStartTask_Handle           = NULL;
UINT32 xLedTask_Handle                      = NULL;  //LED任務


/**
* @brief  創建vStartTask任務
* @param 
* @retval 
* @author lzm
*/
static UINT32 Creat_vStartTask_Task()
{
	//定義一個創建任務的返回類型,初始化為創建成功的返回值
	UINT32 uwRet = LOS_OK;			
	//定義一個用於創建任務的參數結構體
	TSK_INIT_PARAM_S task_init_param;	

	task_init_param.usTaskPrio = lssConfigvStartTaskPRIO;	/* 任務優先級,數值越小,優先級越高 */
	task_init_param.pcName = "Start_Task";/* 任務名 */
	task_init_param.pfnTaskEntry = (TSK_ENTRY_FUNC)vStartTask;/* 任務函數入口 */
	task_init_param.uwStackSize = lssConfigvStartTaskSIZE;		/* 堆棧大小 */

	uwRet = LOS_TaskCreate(&xStartTask_Handle, &task_init_param);/* 創建任務 */
	return uwRet;
}
                                        
/**
* @brief  創建vLedTask任務
* @param 
* @retval 
* @author lzm
*/
static UINT32 Creat_vLedTask_Task()
{{
	//定義一個創建任務的返回類型,初始化為創建成功的返回值
	UINT32 uwRet = LOS_OK;			
	
	TSK_INIT_PARAM_S task_init_param;	

	task_init_param.usTaskPrio = lssConfigvLedTaskPRIO;
	task_init_param.pcName = "Led Task";
	task_init_param.pfnTaskEntry = (TSK_ENTRY_FUNC)vLedTask;
	task_init_param.uwStackSize = lssConfigvLedTaskSIZE;

	uwRet = LOS_TaskCreate(&xLedTask_Handle, &task_init_param);
	return uwRet;
}
                                        
/**
* @brief  創建應用任務
* @param 
* @retval 
* @author lzm
*/
void vStartTask (void )
{
    UINT32 uwRet = LOS_OK;
    UINTPTR uvIntSave;    
    // 進入臨界
    taskENTER_CRITICAL(uvIntSave);   
    uwRet = Creat_vLedTask_Task();
	if (uwRet != LOS_OK)
    {
        ;
    }   
    // 刪除本任務
    LOS_TaskDelete(xStartTask_Handle);     
    // 退出臨界
    taskEXIT_CRITICAL(uvIntSave);    
}
                                        
                                                                       
                                        
/**
* @brief  mian函數
* @param 
* @retval 
* @author lzm
*/
int main(void)
{	
    uint32_t uwRet = LOS_OK;  //定義一個任務創建的返回值,默認為創建成功
    
	//bsp初始化
	bspInit();	
    
    /* LiteOS 內核初始化 */
	uwRet = LOS_KernelInit();
    if (uwRet != LOS_OK)
    {
        ;
    }
    
	/* 創建創建任務 */
    uwRet = Creat_vStartTask_Task();
    if (uwRet != LOS_OK)
    {
        ;
    }
        
    /* 開啟LiteOS任務調度 */
    LOS_Start();
    
	while(1);
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM