单片机
返回首页

移植uc/OS-III最新版到小熊派开发板(STM32L431)

2021-07-26 来源:eefocus

一、uc/OS全家桶

Micrium Software提供了 RTOS 解决方案系列,俗称ucos全家桶,其中最为出名的就是 ucOS-II 和ucOS-III,于 2016 年成为 Silicon Labs 的一部分。

https://github.com/SiliconLabs

3. ucos内核选择

玩全家桶之前,肯定要先把RTOS内核玩起来,关于选择ucos-II还是ucos-III是个老生长谈的问题,上图解决:

4. uc/OS-III源码下载

uc/OS-III系统分为了三个开源仓库,要分别拉取。

① uC-OS3:

git clone https://github.com/SiliconLabs/uC-OS3.git1.

② uC-CPU:

git clone https://github.com/SiliconLabs/uC-CPU.git1.


③ uC-LIB:

git clone https://github.com/SiliconLabs/uC-LIB.git1.

二、移植前的准备

本文中使用的开发板为小熊派IoT开发板,主控为STM32L431RCT6:

本文使用的开发工具是MDK 5.30版本,编译器版本为ARMCC5。

移植之前使用STM32CubeMX生成一份裸机工程,保证可以使用printf在串口正常打印。

三、移植uc/OS-III

1. 复制ucos内核文件到工程中

这里我全都复制过来,后续可以将未添加到MDK中的文件删除。

在工程下新建 ucOS-III 文件夹,存放ucOS-III相关文件。

① 复制ucos内核文件夹过来:

② 复制uC-CPU和uC-LIB两个文件夹过来:

2.添加文件到MDK工程

① 添加 ucos-iii/ports 分组,添加 PortsARM-Cortex-MARMv7-M 目录下的os_cpu_c.c文件,以及该目录下ARM目录下的os_cpu_a.asm文件和 os_cpu_c.c文件:

② 添加 ucos-iii/source分组,添加Source文件夹下的所有c文件(除去__dbg_uCOS-III.c):

③ 添加uC-LIB分组,添加uC-LIB文件夹下的4个c文件:

④ 添加uC-CPU分组,添加uC-CPU下的相关文件,如图:

⑤ 添加 ucos-iii/config 分组,添加配置文件,如下:

  • lib_cfg.h:uC-LIBCfgTemplate

  • os_cfg.h:CfgTemplate

  • cpu_cfg.h:uC-CPUCfgTemplate

3. 添加头文件路径到工程中

4. 修改配置文件

① 修改 cpu_cfg.h,配置本工程所使用内核中CPU的NVIC优先级位数:

② 修改 os_cfg.h,关闭系统中 APP HOOKS 功能:

5. 处理中断

RTOS中内核得以运行需要两个中断:


在pendSV异常处理中进行任务切换

在systick异常处理中进行内核时钟处理

首先包含进来ucos的头文件,修改 stm32l4xx_it.c 文件,在头文件添加:


/* Private includes ----------------------------------------------------------*/

/* USER CODE BEGIN Includes */

#include 'os.h'

/* USER CODE END Includes */


① 处理pendSV异常,如下:


/**

  * @brief This function handles Pendable request for system service.

  */

void PendSV_Handler(void)

{

  /* USER CODE BEGIN PendSV_IRQn 0 */

   OS_CPU_PendSVHandler();


  /* USER CODE END PendSV_IRQn 0 */

  /* USER CODE BEGIN PendSV_IRQn 1 */


  /* USER CODE END PendSV_IRQn 1 */

}


② 处理Systick异常,如下:


/**

  * @brief This function handles System tick timer.

  */

void SysTick_Handler(void)

{

/* USER CODE BEGIN SysTick_IRQn 0 */

/* USER CODE END SysTick_IRQn 0 */

HAL_IncTick();

/* USER CODE BEGIN SysTick_IRQn 1 */

OS_CPU_SysTickHandler();

/* USER CODE END SysTick_IRQn 1 */

}


至此,移植完成。


四、测试系统调度和延时

在main.c中按照如下过程编写测试代码。


① 引入ucos头文件:


/* Private includes ----------------------------------------------------------*/

/* USER CODE BEGIN Includes */

#include

#include 'os.h'

/* USER CODE END Includes */


② 定义任务栈、任务控制块、任务入口函数:


/* Private variables ---------------------------------------------------------*/


/* USER CODE BEGIN PV */

static  OS_TCB   Task1TCB;

static  CPU_STK  Task1Stk[512];


static void Task1_entry(void *p_arg)

{

OS_ERR  err;

    

(void)p_arg;

  

while(1)

{

        printf('task1 is running...rn');

    OSTimeDly(1000, OS_OPT_TIME_DLY, &err);

}   

}



static  OS_TCB   Task2TCB;

static  CPU_STK  Task2Stk[512];


static void Task2_entry(void *p_arg)

{

OS_ERR  err;

    

(void)p_arg;

  

while(1)

{

        printf('task2 is running...rn');

    OSTimeDly(1000, OS_OPT_TIME_DLY, &err);

}   

}



/* USER CODE END PV */


③ 在main函数中定义错误值变量:


  /* USER CODE BEGIN 1 */

    OS_ERR  err;

  /* USER CODE END 1 */


④ 在main函数中初始化内核、创建两个任务、启动内核:


/* USER CODE BEGIN 2 */

printf('uc/OS-III Port On BearPi Board By Mculover666rn');


/* 初始化 uc/OS 内核 */

OSInit(&err); 


/* 创建task1 */

OSTaskCreate((OS_TCB       *)&Task1TCB,         //任务控制块指针           

             (CPU_CHAR     *)'Task 1',          //任务名称

             (OS_TASK_PTR   )Task1_entry,       //任务入口函数

             (void         *)NULL,              //任务入口函数的参数

             (OS_PRIO       )2,                 //任务优先级

             (CPU_STK      *)&Task1Stk[0],      //任务栈地址

             (CPU_STK_SIZE  )512 / 10,          //任务栈监测区大小

             (CPU_STK_SIZE  )512,               //任务栈大小

             (OS_MSG_QTY    )0,                 //任务支持接受的最大消息数

             (OS_TICK       )0,                 //时间片 */

             (void         *)0,                 //堆栈空间大小  

             (OS_OPT        )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),

 /*

OS_OPT_TASK_STK_CHK      使能检测任务栈,统计任务栈已用的和未用的

OS_OPT_TASK_STK_CLR      在创建任务时,清零任务栈

 */  

             (OS_ERR       *)&err);


/* 创建task2 */

OSTaskCreate((OS_TCB       *)&Task2TCB,   

             (CPU_CHAR     *)'Task 2',

             (OS_TASK_PTR   )Task2_entry,

             (void         *)0,

             (OS_PRIO       )3,

             (CPU_STK      *)&Task2Stk[0],

             (CPU_STK_SIZE  )512 / 10,

             (CPU_STK_SIZE  )512,

             (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)&err;


/* USER CODE END 2 */


⑤ 编译,下载,在串口助手中查看输出:




接下来就可以愉快的去玩uc/OS-III内核啦~还可以玩玩全家桶,go go go!

进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • PIC单片机控制的遥控防盗报警器电路

  • 使用ESP8266从NTP服务器获取时间并在OLED显示器上显示

  • 用NE555制作定时器

  • 如何构建一个触摸传感器电路

  • 基于ICL296的大电流开关稳压器电源电路

  • 基于TDA2003的简单低功耗汽车立体声放大器电路

    相关电子头条文章