GD32F103*固件库移植μCOS-Ⅲ详细教程与解析(最终版本已上传,可下载)

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 分组中

完成后如图所示
GD32F103*固件库移植μCOS-Ⅲ详细教程与解析(最终版本已上传,可下载)_第1张图片
3.添加头文件路径,Target-C/C++下,添加如下8个头文件路径
GD32F103*固件库移植μCOS-Ⅲ详细教程与解析(最终版本已上传,可下载)_第2张图片
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中进行任务调度,以下会详细说明各个文件的作用和内容。
GD32F103*固件库移植μCOS-Ⅲ详细教程与解析(最终版本已上传,可下载)_第3张图片
5.如图将system_cfg.c和uCOS_main.c文件添加到user组件下方。
GD32F103*固件库移植μCOS-Ⅲ详细教程与解析(最终版本已上传,可下载)_第4张图片

至此我们的文件结构雏形已经完成,接下来就是添加代码,修改配置。

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 
#include 
#include 
#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中断),另一个是跟任务调度有关的(PendSV_Handler中断),都在gd32f1xx_it.c 、gd32f1xx_it.h以及startup_gd32f10x_hd.s文件中。一般来讲,进入系统运行后这两个中断都应该调用OS系统的os_cpu.h所定义的中断函数(入下所示),但是这样需要修改startup_gd32f10x_hd.s启动文件,将void PendSV_Handler(void)和void SysTick_Handler(void)这两个中断函数名进行修改 。

void  OS_CPU_SysTickHandler (void);
void  OS_CPU_PendSVHandler  (void);

为了修改简单和清晰,我们选择直接在gd32f1xx_it.c中的SysTick_Handler函数和PendSV_Handler函数下分别调用这两个OS函数,将void PendSV_Handler(void)和void SysTick_Handler(void)处修改为如下:(等效跳转到系统中断函数,记得要包含头文件)

#if SYSTEM_SUPPORT_OS

  void PendSV_Handler(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 PendSV_Handler(void)
  {

  }
  /*!
      \brief      this function handles SysTick exception
      \param[in]  none
      \param[out] none
      \retval     none
  */
  void SysTick_Handler(void)
  {

  }
#endif

2. µC/OS-III 相关组件配置

此时编译代码会有很多错误
GD32F103*固件库移植μCOS-Ⅲ详细教程与解析(最终版本已上传,可下载)_第5张图片
这是因为µ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-Ⅲ详细教程与解析到此就算完成,其他功能的讲解后续将持续更新,欢迎订阅。

你可能感兴趣的:(μC/OS-Ⅲ,单片机嵌入式,数据库,单片机,c语言)