GD32F103*固件库移植μCOS-Ⅲ详细教程与解析(最终版本已上传,可下载)
GD32F103*移植μCOS-Ⅲ详细教程与解析,欢迎指正
文章目录
- GD32F103*固件库移植μCOS-Ⅲ详细教程与解析(最终版本已上传,可下载)
- 前言
- 一、移植前的准备
- 二、移植步骤
- 1.文件结构
- 2.添加代码
- 3.系统配置
- 1.中断配置
- 2. µC/OS-III 相关组件配置
- 4.注意事项
- 总结
前言
μcos-III是一个可以基于ROM运行的、可裁剪的、抢占式、实时多任务内核,具有高度可移植性,特点:公开源代码、可移植性、可固化、可裁剪、多任务、占先式,特别适合于微处理器和控制器,适合很多商业操作系统性能相当的实时操作系统(RTOS)。在使用GD32F103单片机项目使用过μcos-III,这里作为一个基础教学版简单记录一下移植过程,欢迎大佬指正!!!!
最终成果放在此处,欢迎大家下载!后续上传git会更新
一、移植前的准备
<1>、硬件平台:可运行软件程序的GD32单片机(本项目使用GD32F103RET6硬件平台)
<2>、软件平台:可直接下载运行的单片机基础工程,本例程是基于使用标准库GD32F10x_Firmware_Library_V2.2.4固件库编写,点击此处可直接获取本试验基础工程
<3>、源码获取:μCOS源码(本例程使用μCOS源码版本为:uC-CPU-1.32.01/uC-LIB-1.39.01/uC-OS3-3.08.01)点此GitHub获取或点此免费获取
<4>、J-link或ST-link等下载器
二、移植步骤
1.文件结构
1.在基础工程目录下新建文件夹uCOS3,再在uCOS3文件夹下新建uC-CPU、uC-LIB、uC-OS分别保存OS的三份源码文件。(注意是’u’而不是’μ’,误写成’μ’可能因非法字符路径导致编译调试出问题)
2.打开基础工程新建三个以下四个分组。然后严格按照以下步骤去添加文件。
■将 uCCPU/BSP/Template/bsp_cpu.c 和 uC-OS3/Template/bsp_os_dt.c 这 个 两 个 文 件 添 加 到uC-OS3/BSP 分组中;
■C-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,将以上三个文件添加到 uC-OS3/CPU 分组中
■uC-LIB/lib_ascii.c、 uC-LIB/lib_math.c、 uC-LIB/lib_mem.c 和 uC-LIB/lib_str.c,将以上四个文件添加到 uC-OS3/LIB 分组中
■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 源文件,将以上列出的共十九个文件添加到/uC-OS3/OS3 分组中
完成后如图所示
3.添加头文件路径,Target-C/C++下,添加如下8个头文件路径
4.新建四个文件名字分别是system_cfg.c和system_cfg.h,uCOS_main.c和uCOS_main.h都保存到main.c所在目录下。system_cfg.c和system_cfg.h文件主要是包含一些全局的自定义配置。uCOS_main.c和uCOS_main.h主要是OS的任务启动、调度函数等,这样划分的主要目的是使得系统main函数和OS的main函数分开,结构会很清晰明朗,系统启动会进入系统main函数初始化各个外设组件和软件模块,然后再进入OS的main中进行任务调度,以下会详细说明各个文件的作用和内容。
5.如图将system_cfg.c和uCOS_main.c文件添加到user组件下方。
至此我们的文件结构雏形已经完成,接下来就是添加代码,修改配置。
2.添加代码
1.system_cfg.c主要是系统配置需要的文件,本例程中主要配置主要都在system_cfg.h文件中,所以system_cfg.c文件中的内容之包含system_cfg.h头文件,其他内容可先空着方便后续补充。
代码如下(示例):
/**
****************************************************************************************************
* @file system_cfg.c
* @author Awen_
* @version V1.0
* @date 2023-04-13
* @brief system config file
* @license
* @modifyRecord:
* V1.0 XXX XXXX-XX-XX Modify...
* V2.0 XXX XXXX-XX-XX Modify...
****************************************************************************************************
* @attention :
* Hardware Testing Platform:兆易创新(GigaDevice) GD32F103RE
* Software Support Package :GD32F10x_Firmware_Library_V2.2.4
*
****************************************************************************************************
*/
#include "system_cfg.h"
2.system_cfg.c主要是系统配置需要的文件,本例程中主要配置主要都在system_cfg.h文件中,这里的内容是我自己写的,不必完全参考,其他内容也可自己补充
代码如下(示例):
/**
****************************************************************************************************
* @file system_cfg.c
* @author Awen_
* @version V1.0
* @date 2023-04-13
* @brief system Initialization configuration
* @license
* @modifyRecord:
* V1.0 XXX XXXX-XX-XX Modify...
* V2.0 XXX XXXX-XX-XX Modify...
****************************************************************************************************
* @attention :
* Hardware Testing Platform:兆易创新(GigaDevice) GD32F103RE
* Software Support Package :GD32F10x_Firmware_Library_V2.2.4
*
****************************************************************************************************
*/
#ifndef __SYS_H
#define __SYS_H
#include <stdio.h>
#include <gd32f10x.h>
#include <systick.h>
#include "gd32f10x_libopt.h"
#define SYSTEM_SUPPORT_OS 1 //定义系统文件夹是否支持OS
#define SYSTEM_SUPPORT_DEBUG 1 //是否支持串口打印调试
/*
*********************************************************************************************************
* 如果使用ucos,则包括下面的头文件即可
*********************************************************************************************************
*/
#if SYSTEM_SUPPORT_OS
//#include "includes.h" //ucos-2 使用
#include "os.h" //ucos-3 使用
#endif
/*
*********************************************************************************************************
* 如果使用ucos,则包括下面的头文件即可
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* 定义返回值类型
*********************************************************************************************************
*/
typedef uint8_t ReturnType_u8;
typedef uint16_t ReturnType_u16;
typedef uint32_t ReturnType_u32;
/*
*********************************************************************************************************
* 获取数组长度宏
*********************************************************************************************************
*/
#define ARRAYNUM(arr_name) (uint32_t)(sizeof(arr_name) / sizeof(*(arr_name)))
/*
*********************************************************************************************************
* 如果使用串口Debug,则定义SYSTEM_SUPPORT_DEBUG 1
*********************************************************************************************************
*/
#ifdef SYSTEM_SUPPORT_DEBUG
#define Debug printf
#else
#define Debug(...) do{ }while(0)
#endif
/*
*********************************************************************************************************
* 定义空指针类型
*********************************************************************************************************
*/
#define NULL_PTR ((void*)0)
/*
*********************************************************************************************************
* 定义错误代号
*********************************************************************************************************
*/
#ifndef E_OK
#define E_OK 0U
#endif
#ifndef E_NOT_OK
#define E_NOT_OK 1U
#endif
#endif
3.uCOS_main.h文件主要作为uCOS_main.c的头文件,uc_os3_main(void)函数作为uc_os3系统的入口,可在uCOS_main.c中实现,以供main函数调用,也可自己添加一些OS的配置
/**
****************************************************************************************************
* @file uc-os3_main.h
* @author Awen_
* @version V2.0
* @date 2023-06-13
* @brief uC/OS-III 实验
* @license Copyright (c) 2020-2032,
****************************************************************************************************
* @attention
*
*
****************************************************************************************************
*/
#ifndef __UC_OS3_MAIN_H
#define __UC_OS3_MAIN_H
#include "system_cfg.h"
/*uC/OS-III*********************************************************************************************/
#include "os.h"
#include "cpu.h"
extern void uc_os3_main(void);
#endif
4.uCOS_main.c文件就是OS的主场,uc_os3_main(void)的实现,系统启动,创建任务,任务函数都是在这里实现,此处给出一个简单的例程,不必深究内容,大意就是创建了三个优先级不同的任务,分别闪灯和usart0输出点内容。这里可直节复制粘贴即可,先不必深究内容。
/**
****************************************************************************************************
* @file uCOS_main.c
* @author Awen_
* @version V1.0
* @date 2023-04-13
* @brief Hardware IO Initialization configuration
* @license
* @modifyRecord:
* V1.0 XXX XXXX-XX-XX Modify...
* V2.0 XXX XXXX-XX-XX Modify...
****************************************************************************************************
* @attention :
* Hardware Testing Platform:兆易创新(GigaDevice) GD32F103RE
* Software Support Package :GD32F10x_Firmware_Library_V2.2.4
*
****************************************************************************************************
*/
/*
*****************************************************************************************************
* Header Flie
*****************************************************************************************************
*/
#include "uCOS_main.h"
/*Peripheral Header file*/
#include "IOHard_cfg.h"
#include "usart_cfg.h"
/******************************************************************************************************/
/*uC/OS-III配置*/
#define START_TASK_PRIO 5
#define START_TASK_STACK_SIZE 256
#define TASK1_PRIO 2
#define TASK1_STACK_SIZE 256
#define TASK2_PRIO 3
#define TASK2_STACK_SIZE 256
#define TASK3_PRIO 4
#define TASK3_STACK_SIZE 256
/* START_TASK 任务 配置
* 包括: 任务优先级 任务栈大小 任务控制块 任务栈任务函数
*/
CPU_STK START_TASK_STACK[START_TASK_STACK_SIZE];
OS_TCB StartTask_Tcp; //起始任务控制块
void start_task(void *p_arg);
//CPU_STK* TASK2_STACK;
static CPU_STK TASK1_Stack[TASK1_STACK_SIZE];
OS_TCB Task1_Tcp; //任务1控制块
void task1(void *p_arg);
//CPU_STK* TASK2_STACK;
static CPU_STK TASK2_Stack[TASK2_STACK_SIZE];
OS_TCB Task2_Tcp; //任务2控制块
void task2(void *p_arg);
//CPU_STK* TASK3_STACK;
static CPU_STK TASK3_Stack[TASK3_STACK_SIZE];
OS_TCB Task3_Tcp; //任务3控制块
void task3(void *p_arg);
OS_FLAG_GRP Event_Flag;
/**
* @brief uC/OS-III main.c 入口函数
* @param 无
* @retval 无
*/
void uc_os3_main(void)
{
OS_ERR err;
/* 初始化uC/OS-III*/
OSInit(&err);
OSTaskCreate( (OS_TCB*) &StartTask_Tcp, /*指向任务控制块的指针*/
(CPU_CHAR*) "start_task", /*指向任务名字*/
(OS_TASK_PTR) start_task, /*指向任务函数的指针*/
(void*) 0, /*传递给任务函数的参数*/
(OS_PRIO) TASK1_PRIO, /*任务优先级,越小优先级越高*/
(CPU_STK*) &START_TASK_STACK[0], /*指向任务栈的起始地址指针*/
(CPU_STK_SIZE) START_TASK_STACK_SIZE/10, /*任务使用的警戒线*/
(CPU_STK_SIZE) START_TASK_STACK_SIZE, /*任务堆栈大小*/
(OS_MSG_QTY) 0, /*任务内嵌消息队列的大小*/
(OS_TICK) 0, /*任务时间片*/
(void*) 0, /*指向用户扩展内存的指针*/
(OS_OPT) (OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR), /*任务选项共5个*/
(OS_ERR*) &err); /*指向接收错误代码变量指针*/
/* 开始任务调度 */
OSStart(&err);
}
void start_task(void *p_arg)
{
OS_ERR err;
CPU_INT32U cntr = 0;
cntr = rcu_clock_freq_get(CK_SYS) / OS_CFG_TICK_RATE_HZ;
CPU_Init();
OS_CPU_SysTickInit(cntr);
Debug("start_Task Running****!!!!\r\n\n");
OSSchedRoundRobinCfg(OS_TRUE, 0, &err);
/*高优先级任务1*/
//TASK1_STACK = mymalloc(SRAMIN,TASK1_STACK_SIZE * sizeof(CPU_STK));
OSTaskCreate( (OS_TCB*) &Task1_Tcp, /*指向任务控制块的指针*/
(CPU_CHAR*) "task1", /*指向任务名字*/
(OS_TASK_PTR) task1, /*指向任务函数的指针*/
(void*) 0, /*传递给任务函数的参数*/
(OS_PRIO) TASK1_PRIO, /*任务优先级,越小优先级越高*/
(CPU_STK*) TASK1_Stack, /*指向任务栈的起始地址指针*/
(CPU_STK_SIZE) TASK1_STACK_SIZE/10, /*任务使用的警戒线*/
(CPU_STK_SIZE) TASK1_STACK_SIZE, /*任务堆栈大小*/
(OS_MSG_QTY) 0, /*任务内嵌消息队列的大小*/
(OS_TICK) 0, /*任务时间片*/
(void*) 0, /*指向用户扩展内存的指针*/
(OS_OPT) (OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR), /*任务选项共5个*/
(OS_ERR*) &err);
/*中优先级任务2*/
//TASK2_STACK = mymalloc(SRAMIN,TASK2_STACK_SIZE * sizeof(CPU_STK));
OSTaskCreate( (OS_TCB*) &Task2_Tcp, /*指向任务控制块的指针*/
(CPU_CHAR*) "task2", /*指向任务名字*/
(OS_TASK_PTR) task2, /*指向任务函数的指针*/
(void*) 0, /*传递给任务函数的参数*/
(OS_PRIO) TASK2_PRIO, /*任务优先级,越小优先级越高*/
(CPU_STK*) TASK2_Stack, /*指向任务栈的起始地址指针*/
(CPU_STK_SIZE) TASK2_STACK_SIZE/10, /*任务使用的警戒线*/
(CPU_STK_SIZE) TASK2_STACK_SIZE, /*任务堆栈大小*/
(OS_MSG_QTY) 0, /*任务内嵌消息队列的大小*/
(OS_TICK) 0, /*任务时间片*/
(void*) 0, /*指向用户扩展内存的指针*/
(OS_OPT) (OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR), /*任务选项共5个*/
(OS_ERR*) &err);
/*中优先级任务3*/
//TASK3_STACK = mymalloc(SRAMIN,TASK1_STACK_SIZE * sizeof(CPU_STK));
OSTaskCreate( (OS_TCB*) &Task3_Tcp, /*指向任务控制块的指针*/
(CPU_CHAR*) "task3", /*指向任务名字*/
(OS_TASK_PTR) task3, /*指向任务函数的指针*/
(void*) 0, /*传递给任务函数的参数*/
(OS_PRIO) TASK3_PRIO, /*任务优先级,越小优先级越高*/
(CPU_STK*) TASK3_Stack, /*指向任务栈的起始地址指针*/
(CPU_STK_SIZE) TASK3_STACK_SIZE/10, /*任务使用的警戒线*/
(CPU_STK_SIZE) TASK3_STACK_SIZE, /*任务堆栈大小*/
(OS_MSG_QTY) 0, /*任务内嵌消息队列的大小*/
(OS_TICK) 0, /*任务时间片*/
(void*) 0, /*指向用户扩展内存的指针*/
(OS_OPT) (OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR), /*任务选项共5个*/
(OS_ERR*) &err);
//删除自己
OSTaskDel((OS_TCB*)0, &err);
}
/*高优先级任务*/
void task1(void *p_arg)
{
OS_ERR err;
while(1)
{
//Usart_SendMsg(UART_0,&arr);
Debug("Tsak1 running !!!! \r\n\n");
OSTimeDly(1000,OS_OPT_TIME_DLY,&err);
gpio_bit_set(GPIOC,GPIO_PIN_7);
OSTimeDly(1000,OS_OPT_TIME_DLY,&err);
gpio_bit_reset(GPIOC,GPIO_PIN_7);
}
}
/*低优先级任务*/
void task2(void *p_arg)
{
OS_ERR err;
while(1)
{
Debug("Tsak2 running !!!! \r\n\n");
OSTimeDly(500,OS_OPT_TIME_DLY,&err);
gpio_bit_set(GPIOC,GPIO_PIN_9);
OSTimeDly(500,OS_OPT_TIME_DLY,&err);
gpio_bit_reset(GPIOC,GPIO_PIN_9);
}
}
/*高优先级任务*/
void task3(void *p_arg)
{
OS_ERR err;
while(1)
{
Debug("Tsak3 running !!!! \r\n\n");
OSTimeDly(200,OS_OPT_TIME_DLY,&err);
gpio_bit_set(GPIOC,GPIO_PIN_8);
OSTimeDly(200,OS_OPT_TIME_DLY,&err);
gpio_bit_reset(GPIOC,GPIO_PIN_8);
}
}
5.最后说说main.c文件,主要是系统初始化和硬件初始化,然后通过调用uc_os3_main(void)函数进入系统
/**
****************************************************************************************************
* @file main.c
* @author Awen_
* @version V1.0
* @date 2023-04-13
* @brief main.c
* @license
* @modifyRecord:
* V1.0 XXX XXXX-XX-XX Modify...
* V2.0 XXX XXXX-XX-XX Modify...
****************************************************************************************************
* @attention :
* Hardware Testing Platform:兆易创新(GigaDevice) GD32F103RE
* Software Support Package :GD32F10x_Firmware_Library_V2.2.4
* μC-OS-III :uC-CPU-1.32.01/uC-LIB-1.39.01/uC-OS3-3.08.01
****************************************************************************************************
*/
/***********************************************************************
*功能块说明:Include
***********************************************************************/
#include "system_cfg.h"
/*uCOS-3 Header file*/
#include "uCOS_main.h"
/*Peripheral Header file*/
#include "IOHard_cfg.h"
#include "usart_cfg.h"
/*
*****************************************************************************************************
*功能块说明:宏定义
****************************************************************************************************
*/
/*
*****************************************************************************************************
*功能块说明:全局变量定义
****************************************************************************************************
*/
/*
*****************************************************************************************************
*功能块说明:静态局部变量定义
****************************************************************************************************
*/
/**********************************************************************
*1-函数名:main
*2-函数功能:
*3-输入参数:无
*4-返回值:int
*5-输入全局变量:无
*6-输出全局变量:无
*7-创建者与创建日期:Awen_ 2023-06-26
**********************************************************************/
int main(int argc,char* argv[])
{
SystemInit();
IoHwAb_Init();
Usart0_Init();
uc_os3_main();
while(1)
{
Debug("Enter μCOS-3 Failed !!!!\n\t");
Debug("While ..... !!!!\n\t");
}
}
3.系统配置
1.中断配置
μCOS与系统相关的主要有两个非常重要的中断,一个是提供OS系统时基的滴答定时器(SysTick_Handler中断),另一个是跟任务调度有关的(PendSVHandler中断),都在gd32f1xx_it.c 、gd32f1xx_it.h以及startup_gd32f10x_hd.s文件中。一般来讲,进入系统运行后这两个中断都应该调用OS系统的os_cpu.h所定义的中断函数(入下所示),但是这样需要修改startup_gd32f10x_hd.s启动文件,将void PendSVHandler(void)和void SysTick_Handler(void)这两个中断函数名进行修改 。
void OS_CPU_SysTickHandler (void);
void OS_CPU_PendSVHandler (void);
为了修改简单和清晰,我们选择直接在gd32f1xx_it.c中的SysTick_Handler函数和PendSVHandler函数下分别调用这两个OS函数,将void PendSVHandler(void)和void SysTick_Handler(void)处修改为如下:(等效跳转到系统中断函数,记得要包含头文件)
#if SYSTEM_SUPPORT_OS
void PendSVHandler(void)
{
/*File:os_cpu_a.asm 汇编代码,无法直接转到定义,直接搜索*/
OS_CPU_PendSVHandler();
}
/*!
\brief this function handles SysTick exception
\param[in] none
\param[out] none
\retval none
*/
void SysTick_Handler(void)
{
/*OS开始跑了,才执行正常的调度处理*/
if(OSRunning == OS_STATE_OS_RUNNING)
{
/*调用uC/OS-III 的 SysTick 中断服务函数 */
OS_CPU_SysTickHandler();
}
//HAL_IncTick();
}
#else
/*!
\brief this function handles PendSV exception
\param[in] none
\param[out] none
\retval none
*/
void PendSVHandler(void)
{
}
/*!
\brief this function handles SysTick exception
\param[in] none
\param[out] none
\retval none
*/
void SysTick_Handler(void)
{
}
#endif
2. µC/OS-III 相关组件配置
此时编译代码会有很多错误
这是因为µC/OS-III代码中还有很多组件还没有配置,组件配置主要修改配置文件的相关宏参数,重要的宏都在如下四个主要配置文件中:
文件名称 | 路径 | 功能 |
---|---|---|
Os_cfg.h | uC-OS3/Cfg/Template/os_cfg.h | 该文件用于配置μCOS-3的内核的一些功能,比如消息队列,信号量,事件标志 |
Os_cfg_app.h | uC-OS3/Cfg/Template/os_cfg_app.h | 该文件用于系统的系统应用配置,如空闲任务,任务统计任务,软件定时器任务的任务参数配置 |
Cpu-cfg.h | uC-CPU/Cfg/Template/cpu_cfg.h | 配置cpu相关的宏定义,如事件戳,前导置零指令,大小端模式相关内容 |
Lib_cfg.h | uC-OS3/uC-LIB/Cfg/lib_cfg.h | 配置μC/lib组件,如内存库中优化的内存相关操作函数,数学函数、ascall码 |
将cpu_cfg.h中文件中用于配置 CPU 中断优先级寄存器使用位数的宏开关置 1
修改前代码:
#if 0
#define CPU_CFG_NVIC_PRIO_BITS 4u
#endif
修改后代码:
#if 1
#define CPU_CFG_NVIC_PRIO_BITS 4u
#endif
至此,代码基本雏形就完成了最简单子系统已经完成,编译无错误,下载到开发板中,usart0输出任务运行情况。
如果要使用其他组件,需要打开相关宏即可,关于四个配置文件的配置有很多,为了方便,可以不用依次配置每个宏,直接将我上传的移植完成的Demo中的这几个文件内容直接拷贝过来即可,然后跳过以下关于这几个文件的详细内容。
cpu_cfg.h文件:
配置前 | 配置后 | 备注 |
---|---|---|
#define CPU_CFG_NAME_EN DEF_DISABLED | #define CPU_CFG_NAME_EN DEF_ENABLED | 使能主机名称 |
#define CPU_CFG_TS_32_EN DEF_DISABLED | #define CPU_CFG_TS_32_EN DEF_ENABLED | 使能32位CPU时间戳功能 |
#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT | #if 0改为#if 1 | 使能前导置零指令 |
#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT | #if 0改为#if 1 | 使能后导置零指令 |
#if0 #define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG | #if 1 #define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE | 使用小端模式 |
#define CPU_CFG_NVIC_PRIO_BITS | #if 0改为#if 1 | 配置 CPU 中断优先级寄存器使用位数的宏开关 |
lib_cfg.h文件:
配置前 | 配置后 | 备注 |
---|---|---|
#define LIB_MEM_CFG_HEAP_SIZE 1024u | #define LIB_MEM_CFG_HEAP_SIZE 0u | 堆大小 |
os_cfg.h文件:
配置前 | 配置后 | 备注 |
---|---|---|
#define OS_CFG_APP_HOOKS_EN 1u | #define OS_CFG_APP_HOOKS_EN 0u | 失能特定应用程序钩子函数 |
#define OS_CFG_DBG_EN 0u | #define OS_CFG_DBG_EN 1u | 使能调试代码/变量 |
#define OS_CFG_TS_EN 0u | #define OS_CFG_TS_EN 1u | 使能时间戳功能 |
#define OS_CFG_PRIO_MAX 64u | #define OS_CFG_PRIO_MAX 32u | 任务优先级数值取值范围0—31 |
#define OS_CFG_TASK_REG_TBL_SIZE 1u | #define OS_CFG_TASK_REG_TBL_SIZE 0u | 任务特定寄存器的数量为0 |
#define OS_CFG_TASK_STK_REDZONE_EN 0u | #define OS_CFG_TASK_STK_REDZONE_EN 1u | 禁止越过栈区警戒线 |
os_cfg_app.h文件:
os_cfg_app.h文件没有什么特别要配置的,只说一下值得注意的几个宏,尤其是这个OS_CFG_TICK_RATE_HZ 作为滴答定时器中断频率使用,决定了系统时基。
宏 | 备注 |
---|---|
#define OS_CFG_IDLE_TASK_STK_SIZE 64u | 空闲任务堆栈大小 |
#define OS_CFG_STAT_TASK_PRIO ((OS_PRIO)(OS_CFG_PRIO_MAX-2u)) | 统计任务任务优先级 |
#define OS_CFG_TICK_RATE_HZ 1000u | 滴答定时器中断频率 |
#define OS_CFG_TMR_TASK_PRIO ((OS_PRIO)(OS_CFG_PRIO_MAX-3u)) | 软件定时器的优先级 |
4.注意事项
void start_task(void *p_arg)函数作为OS开始函数,包含了对系统时钟的配置,其中rcu_clock_freq_get()函是GD32固件库的获取时钟频率的函数(有时会报错,要根据自己使用的库来决定),用在此处是因为滴答定时器的时钟频率和系统时钟频率一样,这里主要目的是获取系统时钟频率,再根据系统时钟频率和滴答定时器中断频率宏来配置滴答定时器。
CPU_INT32U cntr = 0;
cntr = rcu_clock_freq_get(CK_SYS) / OS_CFG_TICK_RATE_HZ;
CPU_Init();
OS_CPU_SysTickInit(cntr);
总结
GD32F103*固件库移植μCOS-Ⅲ详细教程与解析到此就算完成,其他功能的讲解后续将持续更新,欢迎订阅。