STM32 uCOS-III 移植

下载uCOS源码

uCOS官网:https://www.silabs.com/developer-tools/micrium

Github仓库:https://github.com/weston-embedded/uC-OS3

实验所需uCOS源码:https://wwrx.lanzoum.com/iFtsE2vhvezg

正点原子开发指南:https://wwrx.lanzoum.com/i6IgV2vh99kj

本次实验源码:https://wwrx.lanzoum.com/i3cyK2vquoze

HAL基本工程

stm32cubemx建立cmake工程,打开串口1,板载LED。

stm-1u1.png

stm-1u2.png

生成MDK工程

程序测试

重写printf函数

https://www.cnblogs.com/lsdm/p/19225436

测试

在main.c中引用<stdio.h>,并在while函数中添加以下代码:

HAL_Delay(500);
HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
printf("hello %.2f\n",3.1415926);

编译并下载

打开串口助手,led每500ms闪烁

stm-1u3.png

移植uCOS

引用.c文件

在工程目录下新建文件夹uCOS

stm-1u4.png

打开基础工程,新建四个分组,分别为 uCOS/BSPuCOS/CPUuCOS/LIBuCOS/OS,如下图所示:

stm-1u5.png

uCOS/BSP

uC-CPU/BSP/Template/bsp_cpu.c

uC-OS3/Template/bsp_os_dt.c

stm-1u6.png

uCOS/CPU

uC-CPU/ARM-Cortex-M/ARMv7-M/ARM/cpu_a.asm

uC-CPU/ARM-Cortex-M/ARMv7- M/cpu_c.c

uC-CPU/cpu_core.c

stm-1u7.png

uCOS/LIB

uC-LIB/lib_ascii.c

uC-LIB/lib_math.c

uC-LIB/lib_mem.c

uC-LIB/lib_str.c

stm-1u8.png

uCOS/OS

uC-OS3/Cfg/Template/os_app_hooks.c

uC-OS3/Ports/ARM-Cortex-M/ARMv7- M/ARM/os_cpu_a.asm

uC-OS3/Ports/ARM-Cortex-M/ARMv7-M/os_cpu_c.c

uC-OS3/Source 目录下除__dbg_uCOS-III.c 外的所有 C 源文件

stm-1u9.png

添加.h文件

stm-1u10.png

替换中断服务函数

在 µC/OS-III 的移植过程中会遇到两个重要的中断,分别为 SysTick 中断和 PendSV 中断, 这两个中断分别用于为 µC/OS-III 内核提供时基和任务切换。HAL 库会默认定义 SysTick 和 PendSV 的中断服 务函数,因此在移植 µC/OS-III 的时候,需要将 HAL 库默认定义的 SysTick 和 PendSV 中断服 务函数,替换为 µC/OS-III 提供了中断服务函数。

将启动文件中的PendSV_HandlerSysTick_Handler 修改为OS_CPU_PendSVHandlerOS_CPU_SysTickHandler。分别在第7475行和215210行左右。

stm-1u11.png

stm-1u12.png

µC/CPU 的配置文件的路径在 uC-CPU/Cfg/Template/cpu_cfg.h,打开该文件,并将配置文件中用于配置配置 CPU 中断优先级寄存 器使用位数的宏开关置 1 即可

stm-1u13.png

编译,0错误0警告

测试uCOS

新建用户文件夹

stm-1u14.png

在keil中引用

stm-1u15.png

头文件路径

stm-1u16.png

添加测试代码

#include <stdio.h>

#include "rtos.h"

/**
 * start_task任务配置
 */
#define START_TASK_PRIO 5                           /* 任务优先级 */
#define START_TSAK_STACK_SIZE 256                   /* 任务栈大小 */
CPU_STK satrt_task_stack[START_TSAK_STACK_SIZE];    /* 任务栈 */
OS_TCB  start_task_tcb;                             /* 任务控制块 */
void start_task (void *p_arg);                      /* 任务函数 */

/**
 * led_task任务配置
 */
#define LED_TASK_PRIO 6                             /* 任务优先级 */ 
#define LED_TSAK_STACK_SIZE 256                     /* 任务栈大小 */ 
CPU_STK led_task_stack[LED_TSAK_STACK_SIZE];        /* 任务栈 */ 
OS_TCB  led_task_tcb;                               /* 任务控制块 */ 
static void led_task (void *p_arg);                 /* 任务函数 */ 

/**
 * uart_task任务配置
 */
#define UART_TASK_PRIO 6                            /* 任务优先级 */ 
#define UART_TSAK_STACK_SIZE 256                    /* 任务栈大小 */ 
CPU_STK uart_task_stack[UART_TSAK_STACK_SIZE];      /* 任务栈 */
OS_TCB  uart_task_tcb;                              /* 任务控制块 */ 
static void uart_task (void *p_arg);                /* 任务函数 */ 

/**
 * @brief   uCOS入口函数
 * @retval  无
 */
void OS_StartScheduler(void)
{
    OS_ERR err;

    /* 初始化uCOS-III */
    OSInit(&err);
    /* 创建 start_task */
    OSTaskCreate((OS_TCB *)     &start_task_tcb,
                (CPU_CHAR*)     "start_task",
                (OS_TASK_PTR)   start_task,
                (void*)         0,
                (OS_PRIO)       START_TASK_PRIO,
                (CPU_STK*)      &satrt_task_stack[0],
                (CPU_STK_SIZE)  START_TSAK_STACK_SIZE/10,
                (CPU_STK_SIZE)  START_TSAK_STACK_SIZE,
                (OS_MSG_QTY)    0,
                (OS_TICK)       0,
                (void*)         0,
                (OS_OPT)        (OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
                (OS_ERR*)       &err);

    /* 开启任务调度 */
    OSStart(&err);
}

void start_task (void *p_arg)
{
    OS_ERR  err;

    CPU_INT32U  cnts;
    CPU_Init();

    /* 根据配置的节拍频率配置 SysTick */
    cnts = HAL_RCC_GetSysClockFreq() / OS_CFG_TICK_RATE_HZ;
    OS_CPU_SysTickInit(cnts);

    /* 创建 led_task */
    OSTaskCreate((OS_TCB *)     &led_task_tcb,
                (CPU_CHAR*)     "led_task",
                (OS_TASK_PTR)   led_task,
                (void*)         0,
                (OS_PRIO)       LED_TASK_PRIO,
                (CPU_STK*)      &led_task_stack[0],
                (CPU_STK_SIZE)  LED_TSAK_STACK_SIZE/10,
                (CPU_STK_SIZE)  LED_TSAK_STACK_SIZE,
                (OS_MSG_QTY)    0,
                (OS_TICK)       0,
                (void*)         0,
                (OS_OPT)        (OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
                (OS_ERR*)       &err);
	/* 创建 uart_task */	
    OSTaskCreate((OS_TCB *)     &uart_task_tcb,
                (CPU_CHAR*)     "uart_task",
                (OS_TASK_PTR)   uart_task,
                (void*)         0,
                (OS_PRIO)       UART_TASK_PRIO,
                (CPU_STK*)      &uart_task_stack[0],
                (CPU_STK_SIZE)  UART_TSAK_STACK_SIZE/10,
                (CPU_STK_SIZE)  UART_TSAK_STACK_SIZE,
                (OS_MSG_QTY)    0,
                (OS_TICK)       0,
                (void*)         0,
                (OS_OPT)        (OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
                (OS_ERR*)       &err);
    /* 删除start_sask */
    OSTaskDel((OS_TCB *)0, &err);
}

/**
 * @brief led_task
 * @param p_arg: 传入参数(未用到)
 * @retval 无
 */
static void led_task (void *p_arg)
{
    OS_ERR err;
    while (1)
    {
        HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
        OSTimeDly(1000,OS_OPT_TIME_DLY,&err);
    }
    
}

/**
 * @brief uart_task
 * @param p_arg: 传入参数(未用到)
 * @retval 无
 */
static void uart_task (void *p_arg)
{
    OS_ERR err;
		uint8_t i = 0;
    while (1)
    {
        OSTimeDly(1000,OS_OPT_TIME_DLY,&err);
        if (i < 10) 
        {
            printf("hello world! %d\n",i);
        }
        else 
        {
            printf("task deleted\n");
            OSTaskDel(NULL,&err); 
        } 			
        i++;
    }   
}


#ifndef __RTOS_H
#define __RTOS_H

#include <cpu.h>
#include <os.h>

#include "main.h"

void OS_StartScheduler(void);

#endif

main.c中引用#include "rtos.h",在while(1)前添加OS_StartScheduler()。程序将由uCOS接管,并不会运行while函数。

stm-1u17.png

实验结果

板载LED灯每秒闪烁一次,并且串口每秒发送一次,当发送10次时停止发送

stm-1u18.png

posted @ 2025-11-25 21:06  流水灯明  阅读(79)  评论(0)    收藏  举报