基于GD32F470开发板移植ucosiii详细教程

本文提供了基于GD32F470开发板移植UCOSIII的操作步骤,包括下载源码、准备基础工程、逐个解析UCOSIII的各个组成部分,如uC-CPU和uC-LIB的文件功能,并指导如何向工程添加文件、修改启动文件、配置主程序和工程设置。最终实现3个LED间隔500ms闪烁的效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. 下载ucosiii源码
    下载链接:ucosiii 3.04

  2. GD32F470官网例程
    下载链接:GD32F4XX例程

  3. 移植后工程
    下载链接:移植后工程

  4. 移植讲解
    4.1、准备基础工程,(跑马灯实验工程)可通过以上链接下载;
    4.2、UCOSIII源码,可通过以上链接下载,打开后有以下4个文件夹;
    在这里插入图片描述
    4.3、EvalBoards文件夹中,红框中文件是需要我们添加到工程中的;
    在这里插入图片描述
    4.4、 uC-CPU文件夹
    这个文件里面是与CPU相关的代码,有下面几个文件:
    cpu_core.c文件:该文件包含了适用于所有CPU架构的C代码。该文件包含了用来测量中断关闭事件的函数(中断关闭和打开分别由CPU_CRITICAL_ENTER()和CPU_CRITICAL_EXIT()两个宏实现),还包含了一个可模仿前导码零计算的函数(以防止CPU不提供这样的指令),以及一些其他的函数。
    cpu_core.h文件:包含cpu_core.c中函数的原型声明,以及用来测量中断关闭时间变量的定义。
    cpu_def.h文件:包含uC/CPU模块使用的各种#define常量
    ARM-Cortex-M4文件夹:ARM-Cortex-M3文件夹下有三个文件夹:GNU,IAR,RealView,我们使用的是keil MDK编译器,所以只需要看RealView文件夹,RealView文件夹下有3个文件:cpu.h、 cpu_a.asm、 cpu_c.c文件,这3个文件的具体内容如下:
    ①cpu.h文件:包含了一些类型的定义,使UCOSIII和其他模块可与CPU架构和编译器字宽度无关。在该文件中用户能够找到CPU_INT16U、 CPU_INT32U、 CPU_FP32等数据类型的定义。该文件还指定了CPU使用的是大端模式还是小端模式,定义了UCOSIII使用的 CPU_STK数据类型,定义了CPU_CRITICAL_ENTER()和CPU_CRITICAL_EXTI(),还包括一些与CPU架构相关的函数声明。
    ②cpu_a.asm文件:该文件包含了一些用汇编语言编写的函数,可用来开中断和关中断,计算前导零(如果CPU支持这条指令),以及其他一些只能用汇编语言编写的与CPU相关的函数,这个文件中的函数可以从C代码中调用。
    ③cpu_c.c文件:包含了一些基于特定CPU架构但为了可移植而用C语言编写的函数C代码,作为一个普通原则,除非汇编语言能显著提高性能,否则尽量用C语言编写函数。
    注意,上面的cpu.h 、cpu_a.asm和cpu_c.c这3个文件,是在uC_CPU文件夹中ARM-Cortex-M4文件夹下的,打开ARM-Cortex-M4文件夹如图所示:
    在这里插入图片描述4.5、 uC_LIB文件
    uC_LIB是由一些可移植并且与编译器无关的函数组成,UCOSIII不使用uC_LIB中的函数,但是UCOSIII和uC_CPU假定lib_def.h是存在的,uC_LIB包含以下几个文件:

    lib_ascii.h和lib_ascii.c文件:提供ASCII_ToLower()、ASCII_ToUpper()、ASCII_IsAlpha()和ASCII_IsDig()等函数,他们可以分别替代标准库函数tolower()、toupper()、isalpha()和isdigit()等。
    lib_def.h文件:定义了许多常量,如TURE/FALSE、YES/NO、ENABLE/DISABLE,以及各种进制的常量。但是,该文件中所有#define常量都以DEF_打头,所以上述常量的名字实际上为DEF_TRUE/DEF_FALSE等。该文件还为常量数字计算定义了宏。
    lib_math.h和lib_math.c文件:包含了Math_Rand()、Math_SetRand()等函数的源代码,可用来替代标准库函数rand()、srand()。
    lib_mem.c和lib_mem.h文件:包含了Mem_Clr()、Mem_Set()、Mem_Copy和Mem_Cmp()等函数的源代码,可用于替代标准库函数memclr()、memset()、memcpy()和memcmp()等。
    lib_str.c和lib_str.h文件:包含了str_Len()、str_Copy()和str_Cmp()等函数的源代码,可用于替代标准库函数strlen()、strcpy()、ctrcmp()等。
    lib_mem_a.asm文件:lib_mem_a.asm文件在Ports->ARM_Cortex-M4->RealView下,包含了lib_mem.c函数的汇编优化版。

4.6、uCOS-III文件
这个文件夹中有2个文件Ports和Source,Ports文件为与CPU平台有关的文件,Source文件夹里面为UCOSIII 3.04的源码,打开Source文件夹如图所示:
在这里插入图片描述在这里插入图片描述

5、ucosiii移植
5.1向工程中添加相应的文件

在这里插入图片描述在这里插入图片描述修改启动文件
在这里插入图片描述在这里插入图片描述

6、主程序文件代码

#include "gd32f4xx.h"
#include "gd32f470i_eval.h"
#include "systick.h"
#include "delay.h"
#include <stdio.h>
//#include "includes.h"

//任务优先级
#define START_TASK_PRIO		3
//任务堆栈大小	
#define START_STK_SIZE 		128
//任务控制块
OS_TCB StartTaskTCB;
//任务堆栈	
CPU_STK START_TASK_STK[START_STK_SIZE];
//任务函数
void start_task(void *p_arg);

//任务优先级
#define TASK1_TASK_PRIO		4
//任务堆栈大小	
#define TASK1_STK_SIZE 		128
//任务控制块
OS_TCB Task1_TaskTCB;
//任务堆栈	
CPU_STK TASK1_TASK_STK[TASK1_STK_SIZE];
void task1_task(void *p_arg);

//任务优先级
#define TASK2_TASK_PRIO		5
//任务堆栈大小	
#define TASK2_STK_SIZE 		128
//任务控制块
OS_TCB Task2_TaskTCB;
//任务堆栈	
CPU_STK TASK2_TASK_STK[TASK2_STK_SIZE];
//任务函数
void task2_task(void *p_arg);

//任务优先级
#define TASK3_TASK_PRIO		6
//任务堆栈大小	
#define TASK3_STK_SIZE 		128
//任务控制块
OS_TCB Task3_TaskTCB;
//任务堆栈	
CPU_STK TASK3_TASK_STK[TASK3_STK_SIZE];
//任务函数
void task3_task(void *p_arg);

/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
	OS_ERR err;
	CPU_SR_ALLOC();
	nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
	
	systick_config();
	
	/* enable the LEDs GPIO clock */
	rcu_periph_clock_enable(RCU_GPIOE);
	rcu_periph_clock_enable(RCU_GPIOF);

	/* configure LED1 GPIO port */
	gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_2);
	gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);
	/* reset LED1 GPIO pin */
	gpio_bit_set(GPIOE, GPIO_PIN_2);

	/* enable the LED2 GPIO clock */
	/* configure LED2 GPIO port */
	gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_3);
	gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_3);
	/* reset LED2 GPIO pin */
	gpio_bit_set(GPIOE, GPIO_PIN_3);

	/* enable the LED3 GPIO clock */
	/* configure LED3 GPIO port */
	gpio_mode_set(GPIOF, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_10);
	gpio_output_options_set(GPIOF, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
	/* reset LED3 GPIO pin */
	gpio_bit_set(GPIOF, GPIO_PIN_10);
	
	  
	OSInit(&err);
	OS_CRITICAL_ENTER();//进入临界区
	//创建开始任务
	OSTaskCreate((OS_TCB 	* )&StartTaskTCB,		//任务控制块
							 (CPU_CHAR	* )"start task", 		//任务名字
							 (OS_TASK_PTR )start_task, 			//任务函数
							 (void		* )0,					//传递给任务函数的参数
							 (OS_PRIO	  )START_TASK_PRIO,     //任务优先级
							 (CPU_STK   * )&START_TASK_STK[0],	//任务堆栈基地址
							 (CPU_STK_SIZE)START_STK_SIZE/10,	//任务堆栈深度限位
							 (CPU_STK_SIZE)START_STK_SIZE,		//任务堆栈大小
							 (OS_MSG_QTY  )0,					//任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息
							 (OS_TICK	  )0,					//当使能时间片轮转时的时间片长度,为0时为默认长度,
							 (void   	* )0,					//用户补充的存储区
							 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, //任务选项,为了保险起见,所有任务都保存浮点寄存器的值 |OS_OPT_TASK_SAVE_FP
							 (OS_ERR 	* )&err);				//存放该函数错误时的返回值
		OS_CRITICAL_EXIT();	//退出临界区	 
		OSStart(&err);      //开启UCOSIII
    while(1);	
}

//开始任务任务函数
void start_task(void *p_arg)
{
	OS_ERR err;
	CPU_SR_ALLOC();
	p_arg = p_arg;

	CPU_Init();
	Mem_Init();
	
#if OS_CFG_STAT_TASK_EN > 0u
   OSStatTaskCPUUsageInit(&err);  	//统计任务                
#endif
	
#ifdef CPU_CFG_INT_DIS_MEAS_EN		//如果使能了测量中断关闭时间
    CPU_IntDisMeasMaxCurReset();	
#endif
	
#if	OS_CFG_SCHED_ROUND_ROBIN_EN  //当使用时间片轮转的时候
	 //使能时间片轮转调度功能,设置默认的时间片长度
	OSSchedRoundRobinCfg(DEF_ENABLED,1,&err);  
#endif	
	
	OS_CRITICAL_ENTER();	//进入临界区
	
	//创建TASK1任务
	OSTaskCreate((OS_TCB 	* )&Task1_TaskTCB,		
								 (CPU_CHAR	* )"Task1 task", 		
                 (OS_TASK_PTR )task1_task, 			
                 (void		* )0,					
                 (OS_PRIO	  )TASK1_TASK_PRIO,     
                 (CPU_STK   * )&TASK1_TASK_STK[0],	
                 (CPU_STK_SIZE)TASK1_STK_SIZE/10,	
                 (CPU_STK_SIZE)TASK1_STK_SIZE,		
                 (OS_MSG_QTY  )0,					
                 (OS_TICK	  )0,					
                 (void   	* )0,					
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,//|OS_OPT_TASK_SAVE_FP
                 (OS_ERR 	* )&err);				
				 
	//创建TASK2任务
	OSTaskCreate((OS_TCB 	* )&Task2_TaskTCB,		
				         (CPU_CHAR	* )"task2 task", 		
                 (OS_TASK_PTR )task2_task, 			
                 (void		* )0,					
                 (OS_PRIO	  )TASK2_TASK_PRIO,     	
                 (CPU_STK   * )&TASK2_TASK_STK[0],	
                 (CPU_STK_SIZE)TASK2_STK_SIZE/10,	
                 (CPU_STK_SIZE)TASK2_STK_SIZE,		
                 (OS_MSG_QTY  )0,					
                 (OS_TICK	  )0,					
                 (void   	* )0,				
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,//|OS_OPT_TASK_SAVE_FP
                 (OS_ERR 	* )&err);			 
	
	//创建TASK3任务
	OSTaskCreate((OS_TCB 	* )&Task3_TaskTCB,		
				         (CPU_CHAR	* )"task3 task", 		
                 (OS_TASK_PTR )task3_task, 			
                 (void		* )0,					
                 (OS_PRIO	  )TASK3_TASK_PRIO,     	
                 (CPU_STK   * )&TASK3_TASK_STK[0],	
                 (CPU_STK_SIZE)TASK3_STK_SIZE/10,	
                 (CPU_STK_SIZE)TASK3_STK_SIZE,		
                 (OS_MSG_QTY  )0,					
                 (OS_TICK	  )0,					
                 (void   	* )0,				
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,//|OS_OPT_TASK_SAVE_FP
                 (OS_ERR 	* )&err);			
								 
	OS_TaskSuspend((OS_TCB*)&StartTaskTCB,&err);//挂起开始任务									 
	OS_CRITICAL_EXIT();	//退出临界区
//	OSTaskDel((OS_TCB*)0,&err);	//删除start_task任务自身
}

//task1任务函数
void task1_task(void *p_arg)
{
	OS_ERR err;
	p_arg = p_arg;
	while(1)
	{
		gpio_bit_toggle(GPIOE, GPIO_PIN_2);
		OSTimeDlyHMSM(0,0,0,500,OS_OPT_TIME_HMSM_STRICT,&err); //延时500ms
	}
}

//task2任务函数
void task2_task(void *p_arg)
{
	OS_ERR err;
	p_arg = p_arg;
	while(1)
	{
		gpio_bit_toggle(GPIOF, GPIO_PIN_10);
		OSTimeDlyHMSM(0,0,0,500,OS_OPT_TIME_HMSM_STRICT,&err); //延时500ms
	}
}

//task3任务函数
void task3_task(void *p_arg)
{
	OS_ERR err;
	p_arg = p_arg;
	while(1)
	{
		gpio_bit_toggle(GPIOE, GPIO_PIN_3);
		OSTimeDlyHMSM(0,0,0,500,OS_OPT_TIME_HMSM_STRICT,&err); //延时500ms
	}
}

7、工程配置

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

下载器配置成ST-link,直接使用st-link便可以下载和调试。

8、现象
3个led同时闪烁,间隔500ms。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DHZFSYJ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值