介绍
μC/OS-II由Micrium公司提供,是一个可移植、可固化的、可裁剪的、占先式多任务实时内核,它适用于多种微处理器,微控制器和数字处理芯片(已经移植到超过100种以上的微处理器应用中)。同时,该系统源代码开放、整洁、一致,注释详尽,适合系统开发。 μC/OS-II已经通过联邦航空局(FAA)商用航行器认证,符合航空无线电技术委员会(RTCA)DO-178B标准。
本次介绍如何在GD32F310K-START开发板上实现ucois-II的移植。首先下载ucos-II的代码(https://github.com/weston-emb...),文件格式如下图所示:
它的文件结构也很简洁,一般将系统文件分为硬件相关和无关两部分,硬件无关部分主要是系统内内核文件(source/文件下);硬件相关文件包括ports/和CFg/文件下的代码。
系统根据优先级决定任务的执行顺序,在非临界区间内任务可互相抢占系统资源,任务执行状态机如下图所示:
移植
移植需要拷贝的文件包括source/下所有文件
CFg/下的所有文件,app_hooks.c文件可忽略,主要是钩子函数。
Ports/下选择合适芯片及编译器,本文使用的是arm自带的编译器。
创建工程文件,并将所涉及的文件加入到工程中,需要注意的是,ucos_ii.h无需加入到工程中,否则会报重定义错误。
修改GD32的启动文件startup_gd32f3x0.s,在中断向量表中替换PendSV_Handler => OS_CPU_PendSVHandler和SysTick_Handler => OS_CPU_SysTickHandler
修改app_cfg.h文件,由于新版本的ucos不携带cpu_cfg.h和includes.h文件,需要手动创建这两个文件,或是直接在app_cfg.h文件中添加两个参数的值:#define CPU_CFG_KA_IPL_BOUNDARY 4u
#define CPU_CFG_NVIC_PRIO_BITS 4u 来指定应将的内外中断优先级及中断优先级配置位。
完成以上工作后可以在main.c中加入系统头文件及系统函数,本实验创建了一个初始任务(具有低优先级)和一个led任务,由于GD32F310K的运行空间太小,建议将所有非必须外设库文件删除,任务的堆栈空间缩小来确保任务的执行。
#include "gd32f3x0.h"
#include "systick.h"
#include <stdio.h>
#include "main.h"
#include "gd32f350r_eval.h"
#include <ucos_ii.h>
//START task
//task priority
#define START_TASK_PRIO 10 //lowest priority
//size of stack
#define START_STK_SIZE 12
//start task stack
OS_STK START_TASK_STK[START_STK_SIZE];
//start task funciton
void start_task(void *pdata);
//LED task
//stack priority
#define LED_TASK_PRIO 7
//size of task stack
#define LED_STK_SIZE 12
//task stack
OS_STK LED_TASK_STK[LED_STK_SIZE];
//Led0 task funciton
void led_task(void *pdata);
int main(void)
{
/* configure systick */
systick_config();
/* initilize the LEDs, USART and key */
/* enable the LED GPIO clock */
rcu_periph_clock_enable(RCU_GPIOA);
/* configure led GPIO port */
gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_8);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8);
gpio_bit_reset(GPIOA, GPIO_PIN_8);
OSInit();
OSTaskCreate(start_task,(void *)0,(OS_STK *)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO );//create strat task
OSStart();
while(1)
{
//system can not stop
}
//start task
void start_task(void *pdata)
{
OS_CPU_SR cpu_sr=0;
pdata = pdata;
OS_ENTER_CRITICAL(); //Enter critical zone (Cannot be interrupted)
OSTaskCreate(led_task,(void *)0,(OS_STK*)&LED_TASK_STK[LED_STK_SIZE-1],LED_TASK_PRIO);
OSTaskSuspend(START_TASK_PRIO); //suspend task
OS_EXIT_CRITICAL(); //Exit critical zone (Can be interrupted)
}
//LED task
void led_task(void *pdata)
{
while(1)
{
gpio_bit_write(GPIOA,GPIO_PIN_8,SET);
delay_1ms(500);
gpio_bit_write(GPIOA,GPIO_PIN_8,RESET);
delay_1ms(500);
}
}