一、首先先做板级初始化
将外设的初始化写在BSP_Init函数里,之后在main函数中调用
/***********************************************************************
2 * @ 函数名: BSP_Init
3 * @ 功能说明:板级外设初始化,所有板子上的初始化均可放在这个函数里面
4 * @ 参数:
5 * @ 返回值:无
6 *********************************************************************/
7 static void BSP_Init(void)
8 {
9 /*
10 * STM32 中断优先级分组为 4,即 4bit 都用来表示抢占优先级,范围为:0~15
11 * 优先级分组只需要分组一次即可,以后如果有其他的任务需要用到中断,
12 * 都统一用这个优先级分组,千万不要再分组,切忌。
13 */
14 NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );
15
16 /* 外设初始化,这里以LED和串口为例 */
17 LED_GPIO_Config();
18
19 /* 串口初始化 */
20 USART_Config();
21 }
二、正式创建任务
在app.c文件中创建起始任务,并在star_task起始任务函数中调用其它的创建任务函数,
起始任务函数同样在main函数中被调用
在创建任务之前先做一些必要的定义:
#define STAR_STK_SIZE 128 //任务堆栈大小
OS_TCB StarTaskTCB; //任务控制块
CPU_STK STAR_TASK_STK[STAR_STK_SIZE]; //任务堆栈
创建任务函数:
void create_star_task(uint8_t prio)
{
OS_ERR err;
OSTaskCreate ((OS_TCB *) &StarTaskTCB, //任务控制块
(CPU_CHAR *) "star_task", //任务名称,该名字能被调试器显示出来
(OS_TASK_PTR) star_task, //任务函数
(void *) 0, //传入函数的参数
(OS_PRIO ) prio, //任务的优先级
(CPU_STK *) &STAR_TASK_STK[0],//任务堆栈基地址
(CPU_STK_SIZE) STAR_STK_SIZE/10,//任务堆栈深度限制,用于堆栈溢出检测
(CPU_STK_SIZE) STAR_STK_SIZE, //任务堆栈大小
(OS_MSG_QTY ) 0, //任务内部消息队列接收的最大消息数目,0则是禁止消息队列
(OS_TICK ) 0, //使能时间片轮转调度时设定当前任务的时间片长度,0为默认长度
(void *) 0, //用户补充的存储区,一般为一个数据结构,用来扩展任务的TCB,如:放浮点运算内容
(OS_OPT ) OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, //包含任务的特定选项:检测该任务的堆栈|需要堆栈清零
(OS_ERR *) &err); //指定一个变量存储错误码
}
任务主体函数:
void star_task(void *p_arg)
{
OS_ERR err;
CPU_SR_ALLOC();
CPU_Init();
p_arg = p_arg;//防止编译器报警
OS_CRITICAL_ENTER(); //进入临界区
/* 创建任务区 */
create_throw_task(4);
create_load_task(5);
create_pose_task(6,7);
create_connect_task(9);
create_navigation_task(10);
create_monitor_task(11);
create_command_task(12);
create_hand_task(13);
create_key_task(14);
create_motor_driver_task(15);
create_display_task(16);
retarget_init();
OS_CRITICAL_EXIT(); //退出临界区
OS_TaskSuspend((OS_TCB*)&StarTaskTCB,&err); //挂起开始任务
}
可以看到,任务的优先级作为任务主体函数的参数来进行设置
对比其它创建函数可以发现,创建函数的区别在于
1、任务控制块不同
OS_TCB StarTaskTCB; //任务控制块
OSTaskCreate ((OS_TCB *) &StarTaskTCB, //任务控制块
2、任务名与任务函数名不同
(CPU_CHAR *) "star_task", //任务名称,该名字能被调试器显示出来
(OS_TASK_PTR) star_task, //任务函数
3、任务堆栈不同
(CPU_STK *) &STAR_TASK_STK[0],//任务堆栈基地址
(CPU_STK_SIZE) STAR_STK_SIZE/10,//任务堆栈深度限制,用于堆栈溢出检测
(CPU_STK_SIZE) STAR_STK_SIZE, //任务堆栈大小
总结:创建任务需要先定义任务堆栈大小、任务控制块和任务堆栈,之后copy例程进行修改
最后看一下mian函数里有什么:
int main(void)
{
/****************** Operation System Initialization ***************/
OS_ERR err;
CPU_SR_ALLOC();
OSInit(&err); //初始化UCOSIII
/****************** Operation Task **************/
OS_CRITICAL_ENTER(); //进入临界区
/****************** Persional Init Code **************/
BSP_Init(); //初始化各外设
create_star_task(40);
OS_CRITICAL_EXIT(); //退出临界区
/****************** Open UCOSIII System ****************/
OSStart(&err);
while(1);
}
CPU_SR_ALLOC():使用到临界段(在关/开中断时)时必须用到该宏,该宏声明和
定义一个局部变量,用于保存关中断前的 CPU 状态寄存器 SR(临界段关中断只需保存 SR),开中断时将该值还原