嵌入式实时操作系统(RTOS)移植与实践:将 uc/OS 移植到 STM32F103

在嵌入式系统开发中,实时操作系统(RTOS)的应用越来越广泛。uc/OS 是一款经典的开源实时操作系统,具有高效、可靠、可裁剪等优点。本文将详细介绍如何将 uc/OS 移植到 STM32F103 上,并构建三个任务来实现对 LED 的控制和通过串口发送消息的功能。

一、开发环境准备

在开始移植之前,需要准备好以下开发环境:

  1. 硬件环境:STM32F103C8T6 开发板。
  2. 软件环境
    • Keil uVision 5(或其他支持 STM32 的 IDE)。
    • STM32 HAL 库。
    • uc/OS 源码。

二、uc/OS 移植步骤

1. 创建工程

  1. 打开 Keil uVision 5,创建一个新的 STM32 工程。
  2. 添加 STM32 HAL 库文件到工程中。
  3. 将 uc/OS 源码文件夹(如 ucos-ii)添加到工程中。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
4.app_cfg.h
第一处修改:
修改前
#define APP_CFG_SERIAL_EN DEF_ENABLED
修改后
#define APP_CFG_SERIAL_EN DEF_DISABLED
第二处修改:
修改前
#define APP_TRACE BSP_Ser_Printf
修改后
#define APP_TRACE (void)
3. includes.h
第一处修改: 添加相关头文件
修改前
#include <bsp.h>
修改后
#include <bsp.h>
#include “gpio.h”
#include “app_cfg.h”
#include “app.h”
第二处修改: 添加HAL 库
修改前
#include <stm32f10x_lib.h>
修改后
#include “stm32f1xx_hal.h”
————————————————
版权声明:本文为CSDN博主「带火星的小木头」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43116606/article/details/105532222

2. 配置时钟

uc/OS 需要一个定时器来提供时钟中断。STM32F103 提供了多个定时器,可以选择其中一个作为系统时钟。

#include "stm32f1xx_hal.h"

TIM_HandleTypeDef htim1;

void TIM1_UP_Init(void)
{
    __HAL_RCC_TIM1_CLK_ENABLE();

    htim1.Instance = TIM1;
    htim1.Init.Prescaler = (uint16_t)(SystemCoreClock / 1000) - 1; // 设置时钟频率为 1kHz
    htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim1.Init.Period = 1000 - 1; // 设置定时周期为 1ms
    htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    HAL_TIM_Base_Init(&htim1);

    HAL_NVIC_SetPriority(TIM1_UP_IRQn, 0, 0); // 设置中断优先级
    HAL_NVIC_EnableIRQ(TIM1_UP_IRQn); // 使能中断
    HAL_TIM_Base_Start_IT(&htim1); // 启动定时器
}

!](https://i-blog.csdnimg.cn/direct/029be6cf9c4e4ba8879db21468f0dae5.png)

3. 配置中断服务例程

uc/OS 需要一个中断服务例程(ISR)来处理时钟中断。在 stm32f1xx_it.c 文件中添加以下代码:

extern void OSTickISR(void);

void TIM1_UP_IRQHandler(void)
{
    if (__HAL_TIM_GET_FLAG(&htim1, TIM_FLAG_UPDATE) != RESET)
    {
        if (__HAL_TIM_GET_IT_SOURCE(&htim1, TIM_IT_UPDATE) != RESET)
        {
            __HAL_TIM_CLEAR_IT(&htim1, TIM_IT_UPDATE);
            OSTickISR(); // 调用 uc/OS 的时钟中断处理函数
        }
    }
}

4. 配置任务调度器

main.c 文件中初始化 uc/OS 并启动任务调度器:

#include "ucos_ii.h"
#include "stm32f1xx_hal.h"

#define LED1_PIN GPIO_PIN_5
#define LED1_GPIO_PORT GPIOA
#define LED2_PIN GPIO_PIN_6
#define LED2_GPIO_PORT GPIOA

OS_TCB Task1TCB, Task2TCB, Task3TCB;
OS_STK Task1Stk[128], Task2Stk[128], Task3Stk[128];

void Task1(void *p_arg)
{
    while (1)
    {
        HAL_GPIO_TogglePin(LED1_GPIO_PORT, LED1_PIN);
        OSTimeDlyHMSM(0, 0, 1, 0); // 延时 1 秒
    }
}

void Task2(void *p_arg)
{
    while (1)
    {
        HAL_GPIO_TogglePin(LED2_GPIO_PORT, LED2_PIN);
        OSTimeDlyHMSM(0, 0, 3, 0); // 延时 3 秒
    }
}

void Task3(void *p_arg)
{
    char *msg = "hello uc/OS! 欢迎来到RTOS多任务环境!\r\n";
    while (1)
    {
        HAL_UART_Transmit(&huart1, (uint8_t *)msg, strlen(msg), HAL_MAX_DELAY);
        OSTimeDlyHMSM(0, 0, 2, 0); // 延时 2 秒
    }
}

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    TIM1_UP_Init();

    GPIO_InitTypeDef GPIO_InitStruct = {0};
    __HAL_RCC_GPIOA_CLK_ENABLE();
    GPIO_InitStruct.Pin = LED1_PIN | LED2_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(LED1_GPIO_PORT, &GPIO_InitStruct);

    OSInit(); // 初始化 uc/OS
    OSTaskCreate(Task1, NULL, &Task1Stk[128 - 1], 1);
    OSTaskCreate(Task2, NULL, &Task2Stk[128 - 1], 2);
    OSTaskCreate(Task3, NULL, &Task3Stk[128 - 1], 3);
    OSStart(); // 启动任务调度器

    while (1)
    {
    }
}

三、调试与测试

  1. 硬件连接:将 LED 连接到 STM32F103 的 PA5 和 PA6 引脚,将串口连接到调试助手。
  2. 编译与下载:编译工程并下载到开发板。
  3. 观察结果
    • LED1 每秒闪烁一次。
    • LED2 每 3 秒闪烁一次。
    • 串口每 2 秒发送一次消息:“hello uc/OS! 欢迎来到RTOS多任务环境!”

四、总结

通过上述步骤,我们成功地将 uc/OS 移植到了 STM32F103 上,并实现了三个任务的功能。这个过程涉及到了硬件初始化、中断配置、任务调度器的启动等多个方面。在实际开发中,可以根据项目需求进一步优化和扩展 uc/OS 的功能。

希望本文能为嵌入式开发人员提供一个清晰的 uc/OS 移植指南。如果有任何问题或建议,欢迎在评论区留言。

参考资料

  1. STM32F103C8T6 移植 uC/OS-III 基于 HAL 库超完整详细过程
  2. uc/OS-III 移植到 STM32F103C8T6
  3. uc/OS-III 移植到 STM32F103C8T6 踩坑较多,总结详细,推荐阅读
Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐