原创 基于STM32F103RCT6移植LiteOS-M-V5.0.2-Release

2025-2-27 08:56 63 0 分类: MCU/ 嵌入式

请移步 gitee 仓库 https://gitee.com/Newcapec_cn/LiteOS-M_V5.0.2-Release_STM32F103_CubeMX/blob/main/Docs/%E5%9F%BA%E4%BA%8ESTM32F103RCT6%E7%A7%BB%E6%A4%8DLiteOS-M-V5.0.2-Release.md


基于STM32F103RCT6移植LiteOS-M-V5.0.2-Release

下载源码

kernel_liteos_m: OpenHarmony-v5.0.2-Release

third_party_bounds_checking_function: OpenHarmony-v5.0.2-Release

third_party_cmsis: OpenHarmony-v5.0.2-Release

进入 gitee 界面后点击 克隆/下载 按钮,下载 ZIP 压缩包后解压缩。下载路径自定义。

使用STM32CubeMX创建工程模板

配置晶振和烧写口

NVIC配置(默认配置,未修改)

晶振配置

系统配置

时钟配置

工程配置

生成路径根据实际情况配置

代码生成配置

生成代码

配置使用Jlink+SWD方式下载程序

  1. 配置 Jlink

  1. 配置 SWD 模式 
  2. 配置烧写成功后复位运行

编译成功

模板添加目录

原有目录结构

增加目录

  1. APP - 应用代码
  2. Config - 配置文件
  3. Lib - 库文件
  4. Middleware - 中间件

现有目录

添加日志库-simplelogger

simplelogger: 一款简易的日库库,主要对接 J-Link RTT 使用 - Gitee.com

下载源文件

  1. 进入 Middleware 文件夹
  2. 使用 Git Base Here 进入 Git 控制台
  3. 执行命令 git clone https://gitee.com/Newcapec_cn/simplelogger.git

添加源文件

  1. 添加 Middleware\simplelogger\src\*.c
  2. 添加 Middleware\simplelogger\port\*.c
  3. 添加 Middleware\simplelogger\rtt\*.c

配置头文件路径

  1. 增加头文件路径 ..\Middleware\simplelogger\inc

增加测试代码

  1. APP 文件夹创建 APP_main.c 文件,文件内容为
#include"slog.h"voidapp_main(void){    slog_test();    while (1) {        ;    }}
  1. 添加 APP_main.c 文件到工程

  1. 在模板 main 函数的 while 循环中添加 app_main 函数
voidapp_main(void);app_main();

完整 main 函数如下

/**
  * @brief  The application entry point.
  * @retval int
  */intmain(void){  /* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */  HAL_Init();  /* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */  SystemClock_Config();  /* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */  MX_GPIO_Init();  /* USER CODE BEGIN 2 *//* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1)  {    voidapp_main(void);    app_main();    /* USER CODE END WHILE *//* USER CODE BEGIN 3 */  }  /* USER CODE END 3 */}

编译运行测试

测试成功界面

移植LiteOS-M

移植源码

  1. 将 kernel_liteos_m-OpenHarmony-v5.0.2-Release 的 archkal、 kernel、 utils 文件夹拷贝至项目 Middleware\liteos-m 文件夹
  2. 删除文件夹Middleware\liteos-m\arch\arm\arm9Middleware\liteos-m\arch\arm\arm4Middleware\liteos-m\arch\arm\arm7Middleware\liteos-m\arch\arm\arm33Middleware\liteos-m\arch\arm\arm55Middleware\liteos-m\arch\cskyMiddleware\liteos-m\arch\risc-vMiddleware\liteos-m\arch\xtensaMiddleware\liteos-m\kal\libcMiddleware\liteos-m\kal\libsecMiddleware\liteos-m\kal\posix
  3. 在 Middleware\liteos-m 路径下创建文件夹 bounds_checking
  4. 将 third_party_bounds_checking_function-OpenHarmony-v5.0.2-Release 的 include 和 src 文件夹拷贝至项目 Middleware\liteos-m\bounds_checking 文件夹中
  5. 删除非源码文件(可不操作)

文件结构为:

liteos-m
├── arch
│   ├── arm
│   │   ├── common
│   │   │   ├── los_common_interrupt.c
│   │   │   └── los_common_interrupt.h
│   │   ├── cortex-m3
│   │   │   └── keil
│   │   │       ├── los_arch_atomic.h
│   │   │       ├── los_arch_context.h
│   │   │       ├── los_arch_interrupt.h
│   │   │       ├── los_arch_timer.h
│   │   │       ├── los_atomic.S
│   │   │       ├── los_context.c
│   │   │       ├── los_dispatch.S
│   │   │       ├── los_exc.S
│   │   │       ├── los_interrupt.c
│   │   │       ├── los_startup.s
│   │   │       └── los_timer.c
│   │   └── include
│   │       └── arch_elf.h
│   └── include
│       ├── los_arch.h
│       ├── los_atomic.h
│       ├── los_context.h
│       ├── los_interrupt.h
│       ├── los_mpu.h
│       └── los_timer.h
├── bounds_checking
│   ├── include
│   │   ├── securec.h
│   │   └── securectype.h
│   └── src
│       ├── fscanf_s.c
│       ├── fwscanf_s.c
│       ├── gets_s.c
│       ├── input.inl
│       ├── memcpy_s.c
│       ├── memmove_s.c
│       ├── memset_s.c
│       ├── output.inl
│       ├── scanf_s.c
│       ├── secinput.h
│       ├── securecutil.c
│       ├── securecutil.h
│       ├── secureinput_a.c
│       ├── secureinput_w.c
│       ├── secureprintoutput_a.c
│       ├── secureprintoutput.h
│       ├── secureprintoutput_w.c
│       ├── snprintf_s.c
│       ├── sprintf_s.c
│       ├── sscanf_s.c
│       ├── strcat_s.c
│       ├── strcpy_s.c
│       ├── strncat_s.c
│       ├── strncpy_s.c
│       ├── strtok_s.c
│       ├── swprintf_s.c
│       ├── swscanf_s.c
│       ├── vfscanf_s.c
│       ├── vfwscanf_s.c
│       ├── vscanf_s.c
│       ├── vsnprintf_s.c
│       ├── vsprintf_s.c
│       ├── vsscanf_s.c
│       ├── vswprintf_s.c
│       ├── vswscanf_s.c
│       ├── vwscanf_s.c
│       ├── wcscat_s.c
│       ├── wcscpy_s.c
│       ├── wcsncat_s.c
│       ├── wcsncpy_s.c
│       ├── wcstok_s.c
│       ├── wmemcpy_s.c
│       ├── wmemmove_s.c
│       └── wscanf_s.c
├── kal
│   └── cmsis
│       ├── cmsis_liteos2.c
│       ├── cmsis_os2.h
│       ├── cmsis_os.h
│       ├── hos_cmsis_adp.h
│       └── kal.h
├── kernel
│   ├── include
│   │   ├── los_config.h
│   │   ├── los_event.h
│   │   ├── los_membox.h
│   │   ├── los_memory.h
│   │   ├── los_mux.h
│   │   ├── los_queue.h
│   │   ├── los_sched.h
│   │   ├── los_sem.h
│   │   ├── los_sortlink.h
│   │   ├── los_swtmr.h
│   │   ├── los_task.h
│   │   └── los_tick.h
│   └── src
│       ├── los_event.c
│       ├── los_init.c
│       ├── los_mux.c
│       ├── los_queue.c
│       ├── los_sched.c
│       ├── los_sem.c
│       ├── los_sortlink.c
│       ├── los_swtmr.c
│       ├── los_task.c
│       ├── los_tick.c
│       └── mm
│           ├── los_membox.c
│           └── los_memory.c
└── utils
    ├── internal
    │   ├── los_hook_types.h
    │   └── los_hook_types_parse.h
    ├── los_compiler.h
    ├── los_debug.c
    ├── los_debug.h
    ├── los_error.c
    ├── los_error.h
    ├── los_hook.c
    ├── los_hook.h
    ├── los_list.h
    └── los_reg.h

19 directories, 106 files

项目添加源文件

添加头文件路径

..\Middleware\simplelogger\inc
..\Middleware\liteos-m\arch\include
..\Middleware\liteos-m\arch\arm\include
..\Middleware\liteos-m\arch\arm\cortex-m3\keil
..\Middleware\liteos-m\arch\arm\common
..\Middleware\liteos-m\kernel\include
..\Middleware\liteos-m\utils
..\Middleware\liteos-m\bounds_checking\include

编译器选择

Use default compiler version 6

Use MicroLlB

C语言使用 C11 规则

C语言优化等级 -0

解决 target_config.h 未找到问题

  1. 在 Config 文件夹下创建空文件 ARMCM3.h 和 target_config.h
  2. target_config.h 添加以下内容
    /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of its contributors may be used * to endorse or promote products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *//**@defgroup los_config System configuration items * @ingroup kernel */#ifndef _TARGET_CONFIG_H#define _TARGET_CONFIG_H#include"ARMCM3.h"#include"stm32f1xx_hal.h"#include"los_common_interrupt.h"#ifdef __cplusplus#if __cplusplusextern"C" {#endif/* __cplusplus */#endif/* __cplusplus *//*============================================================================= System clock module configuration =============================================================================*/#define OS_SYS_CLOCK                            SystemCoreClock#define LOSCFG_BASE_CORE_TICK_PER_SECOND        (1000UL)#define LOSCFG_BASE_CORE_TICK_WTIMER            0#define LOSCFG_BASE_CORE_TICK_RESPONSE_MAX      (0xFFFFFFFFUL)/*============================================================================= Hardware interrupt module configuration =============================================================================*/#define LOSCFG_PLATFORM_HWI                     0#define LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT     0#define LOSCFG_PLATFORM_HWI_LIMIT               128/*============================================================================= Task module configuration =============================================================================*/#define LOSCFG_BASE_CORE_TSK_LIMIT              24#define LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE    (0x500U)#define LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE (0x2D0U)#define LOSCFG_BASE_CORE_TSK_MIN_STACK_SIZE     (0x130U)#define LOSCFG_BASE_CORE_TIMESLICE              1#define LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT      20000/*============================================================================= Semaphore module configuration =============================================================================*/#define LOSCFG_BASE_IPC_SEM                     1#define LOSCFG_BASE_IPC_SEM_LIMIT               48/*============================================================================= Mutex module configuration =============================================================================*/#define LOSCFG_BASE_IPC_MUX                     1#define LOSCFG_BASE_IPC_MUX_LIMIT               24/*============================================================================= Queue module configuration =============================================================================*/#define LOSCFG_BASE_IPC_QUEUE                   1#define LOSCFG_BASE_IPC_QUEUE_LIMIT             24/*============================================================================= Software timer module configuration =============================================================================*/#define LOSCFG_BASE_CORE_SWTMR                  1#define LOSCFG_BASE_CORE_SWTMR_ALIGN            1#define LOSCFG_BASE_CORE_SWTMR_LIMIT            48/*============================================================================= Memory module configuration =============================================================================*/#define LOSCFG_SYS_EXTERNAL_HEAP                0#define LOSCFG_SYS_HEAP_SIZE                    0x00008000#define LOSCFG_MEM_MUL_POOL                     1#define OS_SYS_MEM_NUM                          20/*============================================================================= Exception module configuration =============================================================================*/#define LOSCFG_PLATFORM_EXC                     0/* ============================================================================= PM module configuration ============================================================================= */#define LOSCFG_KERNEL_PM                        0/* ============================================================================= printf module configuration ============================================================================= */#define LOSCFG_KERNEL_PRINTF                    2#ifdef __cplusplus#if __cplusplus}#endif/* __cplusplus */#endif/* __cplusplus */#endif/* _TARGET_CONFIG_H */
  3. 添加 Config 文件夹为头文件路径

解决 HWI_PROC_FUNC 未定义问题

在 Middleware\liteos-m\arch\arm\common\los_common_interrupt.h 中添加以下代码

/* ---> liteos-m add */#if (LOSCFG_PLATFORM_HWI_WITH_ARG == 1)typedefVOID(*HWI_PROC_FUNC)(VOID *parm);#elsetypedefVOID(*HWI_PROC_FUNC)(void);#endif/* ---/ */

强制内存池4字节对齐

Middleware\liteos-m\kernel\src\mm\los_memory.c 53行 由 STATIC UINT8 g_memStart[LOSCFG_SYS_HEAP_SIZE]; 修改为 STATIC UINT8 __attribute__((aligned(4))) g_memStart[LOSCFG_SYS_HEAP_SIZE]; 增加 __attribute__((aligned(4))) 预处理

修改 SysTick_Config 参数

将 Middleware\liteos-m\arch\arm\cortex-m3\keil\los_timer.c 文件中调用 SysTick_Config 接口的参数 由LOSCFG_BASE_CORE_TICK_RESPONSE_MAX 修改为 OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND

移植 PendSV_Handler

在 PendSV_Handler 函数中调用 HalPendSV 接口

voidPendSV_Handler(void){  /* USER CODE BEGIN PendSV_IRQn 0 */voidHalPendSV(void);  HalPendSV();  /* USER CODE END PendSV_IRQn 0 *//* USER CODE BEGIN PendSV_IRQn 1 *//* USER CODE END PendSV_IRQn 1 */}

移植 OsTickHandler

在 SysTick_Handler 函数中调用 OsTickHandler 接口

/**
  * @brief This function handles System tick timer.
  */voidSysTick_Handler(void){  /* USER CODE BEGIN SysTick_IRQn 0 */voidOsTickHandler(void);  OsTickHandler();  /* USER CODE END SysTick_IRQn 0 *//* USER CODE BEGIN SysTick_IRQn 1 *//* USER CODE END SysTick_IRQn 1 */}

增加内核打印接口

  1. HalConsoleOutput 增加调用 Jlink-RTT 打印功能
    WEAK VOID HalConsoleOutput(LogModuleType type, INT32 level, const CHAR *fmt, ...){    /* ---> liteos-m add */#include"../rtt/SEGGER_RTT.h"    va_list ParamList;        va_start(ParamList, fmt);    SEGGER_RTT_vprintf(0, fmt, &ParamList);    va_end(ParamList);    /* ---/ */}

测试LiteOS-M

  1. APP_main.c 添加测试代码,其完整文件为:
    #include"slog.h"#include"los_task.h"VOID taskSampleEntry2(VOID){    while (1) {        LOS_TaskDelay(1000);        log_v("taskSampleEntry2 running...");    }}VOID taskSampleEntry1(VOID){    while (1) {        LOS_TaskDelay(2000);        log_v("taskSampleEntry1 running...");    }}UINT32 taskSample(VOID){    UINT32           uwRet;    UINT32           taskID1, taskID2;    TSK_INIT_PARAM_S stTask1 = {0};    stTask1.pfnTaskEntry     = (TSK_ENTRY_FUNC)taskSampleEntry1;    stTask1.uwStackSize      = 0X1000;    stTask1.pcName           = "taskSampleEntry1";    stTask1.usTaskPrio       = 6;    uwRet                    = LOS_TaskCreate(&taskID1, &stTask1);    if (uwRet != LOS_OK) {        log_v("create task1 failed\n");    }    stTask1.pfnTaskEntry = (TSK_ENTRY_FUNC)taskSampleEntry2;    stTask1.uwStackSize  = 0X1000;    stTask1.pcName       = "taskSampleEntry2";    stTask1.usTaskPrio   = 7;    uwRet                = LOS_TaskCreate(&taskID2, &stTask1);    if (uwRet != LOS_OK) {        log_v("create task2 failed\n");    }    return LOS_OK;}voidapp_main(void){    unsignedint ret;        slog_test();    ret = LOS_KernelInit();    if (ret == LOS_OK) {        taskSample();        LOS_Start();    }    while (1) {        ;    }}
  2. 测试成功界面为

适配 CMSIS

添加源码

Middleware\liteos-m\kal\cmsis\cmsis_liteos2.c

修改源码

third_party_cmsis-OpenHarmony-v5.0.2-Release\CMSIS\RTOS2\Include\cmsis_os2.h 覆盖 Middleware\liteos-m\kal\cmsis\cmsis_os2.h

添加头文件路径

..\Middleware\liteos-m\kal\cmsis

创建使用 cmsis_os2 接口的源码

  1. 在 APP 文件夹中创建源文件 cmsis_os2_creat_thread.c,代码如下:
    /** * @file cmsis_os2_creat_thread.c * @author TianBeiBei (tianbeibei5628@dingtalk.com) * @brief * @version 0.1 * @date 2025-02-25 * * @copyright Copyright (c) 2025 * */#include"slog.h"#include"cmsis_os2.h"#define MINI_TASK_DELAY_MS (1 * 1000)/* Definitions for BelowNormalTask */osThreadId_t         BelowNormalTaskHandle;const osThreadAttr_t BelowNormalTask_attributes = {    .name       = "BelowNormalTask",    .stack_size = 1024 * 4,    .priority   = (osPriority_t)osPriorityBelowNormal,};/* Definitions for NormalTask */osThreadId_t         NormalTaskHandle;const osThreadAttr_t NormalTask_attributes = {    .name       = "NormalTask",    .stack_size = 1024 * 4,    .priority   = (osPriority_t)osPriorityNormal,};/* Definitions for LowTask */osThreadId_t         LowTaskHandle;const osThreadAttr_t LowTask_attributes = {    .name       = "LowTask",    .stack_size = 1024 * 4,    .priority   = (osPriority_t)osPriorityLow,};voidlow_task(void *argument){    for (;;) {        log_v("low_task runing");        osDelay(MINI_TASK_DELAY_MS * 3);    }#if 0    osThreadExit();/* 任务退出 */#endif}voidnormal_task(void *argument){    for (;;) {        log_v("normal_task runing");        osDelay(MINI_TASK_DELAY_MS * 2);    }#if 0    osThreadExit();/* 任务退出 */#endif}voidbelow_normal_task(void *argument){    for (;;) {        log_v("below_normal_task runing");        osDelay(MINI_TASK_DELAY_MS * 1);    }#if 0    osThreadExit();/* 任务退出 */#endif}voidliteos_m_thread_init(void){    /* Create the thread(s) *//* creation of NormalTask */    NormalTaskHandle = osThreadNew(normal_task, NULL, &NormalTask_attributes);    /* creation of BelowNormalTask */    BelowNormalTaskHandle = osThreadNew(below_normal_task, NULL, &BelowNormalTask_attributes);    /* creation of LowTask */    LowTaskHandle = osThreadNew(low_task, NULL, &LowTask_attributes);}voidcmsis_os2_main(void){    /* Init scheduler */    osKernelInitialize();    /* Call init function for freertos objects (in freertos.c) */    liteos_m_thread_init();    /* Start scheduler */    osKernelStart();}
  2. 将 cmsis_os2_creat_thread.c 文件添加到工程中

  1. 修改 APP_main.c 源码,添加调用 cmsis_os2 接口的代码,不再调用源码接口,修改后的源码如下:
    #include"slog.h"#include"los_task.h"VOID taskSampleEntry2(VOID){    while (1) {        log_v("taskSampleEntry2 running...");        LOS_TaskDelay(1000);    }}VOID taskSampleEntry1(VOID){    while (1) {        log_v("taskSampleEntry1 running...");        LOS_TaskDelay(2000);    }}UINT32 taskSample(VOID){    UINT32           uwRet;    UINT32           taskID1, taskID2;    TSK_INIT_PARAM_S stTask1 = {0};    stTask1.pfnTaskEntry     = (TSK_ENTRY_FUNC)taskSampleEntry1;    stTask1.uwStackSize      = 0X1000;    stTask1.pcName           = "taskSampleEntry1";    stTask1.usTaskPrio       = 6;    uwRet                    = LOS_TaskCreate(&taskID1, &stTask1);    if (uwRet != LOS_OK) {        log_v("create task1 failed\n");    }    stTask1.pfnTaskEntry = (TSK_ENTRY_FUNC)taskSampleEntry2;    stTask1.uwStackSize  = 0X1000;    stTask1.pcName       = "taskSampleEntry2";    stTask1.usTaskPrio   = 7;    uwRet                = LOS_TaskCreate(&taskID2, &stTask1);    if (uwRet != LOS_OK) {        log_v("create task2 failed\n");    }    return LOS_OK;}voidapp_main(void){    unsignedint ret;    slog_test();#if 1 /* 0-原接口 1-cmsis_os2接口 */voidcmsis_os2_main(void);    cmsis_os2_main();#else    ret = LOS_KernelInit();    if (ret == LOS_OK) {        taskSample();        LOS_Start();    }#endifwhile (1) {        ;    }}

测试成功界面如下:

作者: 逮到一只程序猿, 来源:面包板社区

链接: https://mbb.eet-china.com/blog/uid-me-4110623.html

版权声明:本文为博主原创,未经本人允许,禁止转载!

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
0
关闭 站长推荐上一条 /2 下一条