UCOSIII(二)
#include "sys.h" #include "delay.h" #include "usart.h" #include "led.h" #include "includes.h" //任务1控制块 OS_TCB Task1_TCB; void task1(void *parg); CPU_STK task1_stk[128]; //任务1的任务堆栈,大小为128字,也就是512字节 //任务2控制块 OS_TCB Task2_TCB; void task2(void *parg); CPU_STK task2_stk[128]; //任务2的任务堆栈,大小为128字,也就是512字节 OS_SEM SYNC_SEM; //定义一个信号量,用于任务同步 //主函数 int main(void) { OS_ERR err; delay_init(168); //时钟初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断分组配置 uart_init(9600); //串口初始化 LED_Init(); //LED初始化 //OS初始化,它是第一个运行的函数,初始化各种的全局变量,例如中断嵌套计数器、优先级、存储器 OSInit(&err); //创建任务1 OSTaskCreate( (OS_TCB *)&Task1_TCB, //任务控制块 (CPU_CHAR *)"Task1", //任务的名字 (OS_TASK_PTR)task1, //任务函数 (void *)0, //传递参数 (OS_PRIO)3, //任务的优先级 (CPU_STK *)task1_stk, //任务堆栈基地址 (CPU_STK_SIZE)128/10, //任务堆栈深度限位,用到这个位置,任务不能再继续使用 (CPU_STK_SIZE)128, //任务堆栈大小 (OS_MSG_QTY)0, //禁止任务消息队列 (OS_TICK)0, //默认时间片长度 (void *)0, //不需要补充用户存储区 (OS_OPT)OS_OPT_TASK_NONE, //没有任何选项 &err //返回的错误码 ); //创建任务2 OSTaskCreate( (OS_TCB *)&Task2_TCB, //任务控制块 (CPU_CHAR *)"Task2", //任务的名字 (OS_TASK_PTR)task2, //任务函数 (void *)0, //传递参数 (OS_PRIO)2, //任务的优先级 (CPU_STK *)task2_stk, //任务堆栈基地址 (CPU_STK_SIZE)128/10, //任务堆栈深度限位,用到这个位置,任务不能再继续使用 (CPU_STK_SIZE)128, //任务堆栈大小 (OS_MSG_QTY)0, //禁止任务消息队列 (OS_TICK)0, //默认时间片长度 (void *)0, //不需要补充用户存储区 (OS_OPT)OS_OPT_TASK_NONE, //没有任何选项 &err //返回的错误码 ); //创建一个信号量 OSSemCreate ((OS_SEM* )&SYNC_SEM, (CPU_CHAR* )"SYNC_SEM", (OS_SEM_CTR)0, (OS_ERR* )&err); //启动OS,进行任务调度 OSStart(&err); } void task1(void *parg) { OS_ERR err; printf("task1 is create ok\r\n"); while(1) { OSSemPend(&SYNC_SEM,0,OS_OPT_PEND_BLOCKING,0,&err); //请求信号量 printf("task1 is running ...\r\n"); } } void task2(void *parg) { OS_ERR err; printf("task2 is create ok\r\n"); while(1) { //连续发送3个信号量 OSSemPost(&SYNC_SEM,OS_OPT_POST_1,&err); //发送信号量 OSSemPost(&SYNC_SEM,OS_OPT_POST_1,&err); //发送信号量 OSSemPost(&SYNC_SEM,OS_OPT_POST_1,&err); //发送信号量 printf("task2 is running ...\r\n"); OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); //延时10ms } }
#include "sys.h" #include "delay.h" #include "usart.h" #include "led.h" #include "includes.h" //任务1控制块 OS_TCB Task1_TCB; void task1(void *parg); CPU_STK task1_stk[128]; //任务1的任务堆栈,大小为128字,也就是512字节 //任务2控制块 OS_TCB Task2_TCB; void task2(void *parg); CPU_STK task2_stk[128]; //任务2的任务堆栈,大小为128字,也就是512字节 //任务3控制块 OS_TCB Task3_TCB; void task3(void *parg); CPU_STK task3_stk[128]; //任务2的任务堆栈,大小为128字,也就是512字节 OS_FLAG_GRP g_os_flag; //定义一个事件标志组 //按键初始化函数 void KEY_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOE,ENABLE); //使能GPIOA GPIOE时钟 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4; //PE2,3,4引脚 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN; //输入 GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP; //上拉输入 GPIO_Init(GPIOE,&GPIO_InitStructure); //初始化GPIOE GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0; //PA0引脚 GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_DOWN; //下拉输入 GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化GPIOA } //主函数 int main(void) { OS_ERR err; delay_init(168); //时钟初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断分组配置 uart_init(115200); //串口初始化 LED_Init(); //LED初始化 //OS初始化,它是第一个运行的函数,初始化各种的全局变量,例如中断嵌套计数器、优先级、存储器 OSInit(&err); //创建任务1 OSTaskCreate( (OS_TCB *)&Task1_TCB, //任务控制块 (CPU_CHAR *)"Task1", //任务的名字 (OS_TASK_PTR)task1, //任务函数 (void *)0, //传递参数 (OS_PRIO)3, //任务的优先级 (CPU_STK *)task1_stk, //任务堆栈基地址 (CPU_STK_SIZE)128/10, //任务堆栈深度限位,用到这个位置,任务不能再继续使用 (CPU_STK_SIZE)128, //任务堆栈大小 (OS_MSG_QTY)0, //禁止任务消息队列 (OS_TICK)0, //默认时间片长度 (void *)0, //不需要补充用户存储区 (OS_OPT)OS_OPT_TASK_NONE, //没有任何选项 &err //返回的错误码 ); //创建任务2 OSTaskCreate( (OS_TCB *)&Task2_TCB, //任务控制块 (CPU_CHAR *)"Task2", //任务的名字 (OS_TASK_PTR)task2, //任务函数 (void *)0, //传递参数 (OS_PRIO)2, //任务的优先级 (CPU_STK *)task2_stk, //任务堆栈基地址 (CPU_STK_SIZE)128/10, //任务堆栈深度限位,用到这个位置,任务不能再继续使用 (CPU_STK_SIZE)128, //任务堆栈大小 (OS_MSG_QTY)0, //禁止任务消息队列 (OS_TICK)0, //默认时间片长度 (void *)0, //不需要补充用户存储区 (OS_OPT)OS_OPT_TASK_NONE, //没有任何选项 &err //返回的错误码 ); //创建任务3 OSTaskCreate( (OS_TCB *)&Task3_TCB, //任务控制块 (CPU_CHAR *)"Task3", //任务的名字 (OS_TASK_PTR)task3, //任务函数 (void *)0, //传递参数 (OS_PRIO)2, //任务的优先级 (CPU_STK *)task3_stk, //任务堆栈基地址 (CPU_STK_SIZE)128/10, //任务堆栈深度限位,用到这个位置,任务不能再继续使用 (CPU_STK_SIZE)128, //任务堆栈大小 (OS_MSG_QTY)0, //禁止任务消息队列 (OS_TICK)0, //默认时间片长度 (void *)0, //不需要补充用户存储区 (OS_OPT)OS_OPT_TASK_NONE, //没有任何选项 &err //返回的错误码 ); //创建一个事件标志组 OSFlagCreate( (OS_FLAG_GRP* )&g_os_flag, (CPU_CHAR*)"os_flag", (OS_FLAGS)0, (OS_ERR* )&err); //按键初始化 KEY_Init(); //启动OS,进行任务调度 OSStart(&err); } void task1(void *parg) { OS_ERR err; OS_FLAGS os_flag; printf("task1 is create ok\r\n"); while(1) { if(PAin(0) == 0) { //去抖动 OSTimeDlyHMSM(0,0,0,20,OS_OPT_TIME_HMSM_STRICT,&err); //延时20ms if(PAin(0) == 0) { //发送事件标志,标志值为0x1,设置g_os_flag的bit0为1 os_flag= OSFlagPost((OS_FLAG_GRP* )&g_os_flag, (OS_FLAGS)0x1, (OS_OPT)OS_OPT_POST_FLAG_SET, &err); printf("task1,os_flag=%02X\r\n",os_flag); } } OSTimeDlyHMSM(0,0,0,20,OS_OPT_TIME_HMSM_STRICT,&err); //延时20ms } } void task2(void *parg) { OS_ERR err; OS_FLAGS os_flag; printf("task2 is create ok\r\n"); while(1) { if(PEin(2) == 0) { OSTimeDlyHMSM(0,0,0,20,OS_OPT_TIME_HMSM_STRICT,&err); //延时20ms if(PEin(2) == 0) { //发送事件标志,标志值为0x2,设置g_os_flag的bit1为1 os_flag= OSFlagPost((OS_FLAG_GRP* )&g_os_flag, (OS_FLAGS)0x2, (OS_OPT)OS_OPT_POST_FLAG_SET, &err); printf("task2,os_flag=%02X\r\n",os_flag); } } OSTimeDlyHMSM(0,0,0,20,OS_OPT_TIME_HMSM_STRICT,&err); //延时20ms } } void task3(void *parg) { OS_ERR err; OS_FLAGS os_flag; printf("task3 is create ok\r\n"); while(1) { //OS_OPT_PEND_FLAG_SET_ANY 和OS_OPT_PEND_FLAG_SET_ALL是有区别的 //前者是等待任意一个事件,后者要确保所有事件成立 os_flag= OSFlagPend((OS_FLAG_GRP* )&g_os_flag, (OS_FLAGS)0x3, //等待bit1和bit0置位 (OS_TICK)0, //0代表是默认一直阻塞等待 (OS_OPT)OS_OPT_PEND_FLAG_SET_ANY+OS_OPT_PEND_FLAG_CONSUME, //等待事件标志组任何一位置位 (CPU_TS *)0, //默认不记录时间戳 &err); printf("task3,os_flag=%02X\r\n",os_flag); } }
#include "sys.h" #include "delay.h" #include "usart.h" #include "led.h" #include "includes.h" //任务1控制块 OS_TCB Task1_TCB; void task1(void *parg); CPU_STK task1_stk[128]; //任务1的任务堆栈,大小为128字,也就是512字节 //任务2控制块 OS_TCB Task2_TCB; void task2(void *parg); CPU_STK task2_stk[128]; //任务2的任务堆栈,大小为128字,也就是512字节 #define TASK_Q_NUM 64 //发任务内建消息队列的长度 //主函数 int main(void) { OS_ERR err; delay_init(168); //时钟初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断分组配置 uart_init(9600); //串口初始化 LED_Init(); //LED初始化 //OS初始化,它是第一个运行的函数,初始化各种的全局变量,例如中断嵌套计数器、优先级、存储器 OSInit(&err); //创建任务1 OSTaskCreate( (OS_TCB *)&Task1_TCB, //任务控制块 (CPU_CHAR *)"Task1", //任务的名字 (OS_TASK_PTR)task1, //任务函数 (void *)0, //传递参数 (OS_PRIO)3, //任务的优先级 (CPU_STK *)task1_stk, //任务堆栈基地址 (CPU_STK_SIZE)128/10, //任务堆栈深度限位,用到这个位置,任务不能再继续使用 (CPU_STK_SIZE)128, //任务堆栈大小 (OS_MSG_QTY)0, //禁止任务消息队列 (OS_TICK)0, //默认时间片长度 (void *)0, //不需要补充用户存储区 (OS_OPT)OS_OPT_TASK_NONE, //没有任何选项 &err //返回的错误码 ); //创建任务2 OSTaskCreate( (OS_TCB *)&Task2_TCB, //任务控制块 (CPU_CHAR *)"Task2", //任务的名字 (OS_TASK_PTR)task2, //任务函数 (void *)0, //传递参数 (OS_PRIO)2, //任务的优先级 (CPU_STK *)task2_stk, //任务堆栈基地址 (CPU_STK_SIZE)128/10, //任务堆栈深度限位,用到这个位置,任务不能再继续使用 (CPU_STK_SIZE)128, //任务堆栈大小 (OS_MSG_QTY)TASK_Q_NUM, //任务2需要使用内建消息队列,消息队列长度为64个字 (OS_TICK)0, //默认时间片长度 (void *)0, //不需要补充用户存储区 (OS_OPT)OS_OPT_TASK_NONE, //没有任何选项 &err //返回的错误码 ); //启动OS,进行任务调度 OSStart(&err); } void task1(void *parg) { uint32_t msg_cnt=0; char pbuf[64]; OS_ERR err; printf("task1 is create ok\r\n"); while(1) { msg_cnt++; sprintf((char*)pbuf,"msg_cnt=%d\r\n",msg_cnt); //发送消息 OSTaskQPost((OS_TCB* )&Task2_TCB, //向任务task2发送消息 (void* )pbuf, (OS_MSG_SIZE)strlen(pbuf), (OS_OPT )OS_OPT_POST_FIFO, (OS_ERR* )&err); printf("task1 is running ...\r\n"); OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); //延时1S } } void task2(void *parg) { char *p; OS_MSG_SIZE size; OS_ERR err; printf("task2 is create ok\r\n"); while(1) { //请求消息 p=OSTaskQPend((OS_TICK )0, (OS_OPT )OS_OPT_PEND_BLOCKING, (OS_MSG_SIZE* )&size, (CPU_TS* )0, (OS_ERR* )&err ); printf("task2 is running ...\r\n"); printf(p); } }
/* 描述: 1.当前创建了软件定时器1,工作频率为100Hz,优先级为2,可在os_cfg_app.h进行设置 #define OS_CFG_TMR_TASK_PRIO 2u #define OS_CFG_TMR_TASK_RATE_HZ 100u 2.创建任务1,优先级为3,;创建任务2,优先级为4 */ #include "sys.h" #include "delay.h" #include "usart.h" #include "led.h" #include "includes.h" //任务1控制块 OS_TCB Task1_TCB; void task1(void *parg); CPU_STK task1_stk[128]; //任务1的任务堆栈,大小为128字,也就是512字节 //任务2控制块 OS_TCB Task2_TCB; void task2(void *parg); CPU_STK task2_stk[128]; //任务2的任务堆栈,大小为128字,也就是512字节 OS_TMR tmr1; //定时器1 //软件定时器1回调函数 void tmr1_callback(void *ptmr,void *p_arg); //主函数 int main(void) { OS_ERR err; delay_init(168); //时钟初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断分组配置 uart_init(9600); //串口初始化 LED_Init(); //LED初始化 //OS初始化,它是第一个运行的函数,初始化各种的全局变量,例如中断嵌套计数器、优先级、存储器 OSInit(&err); //创建任务1 OSTaskCreate( (OS_TCB *)&Task1_TCB, //任务控制块 (CPU_CHAR *)"Task1", //任务的名字 (OS_TASK_PTR)task1, //任务函数 (void *)0, //传递参数 (OS_PRIO)3, //任务的优先级 (CPU_STK *)task1_stk, //任务堆栈基地址 (CPU_STK_SIZE)128/10, //任务堆栈深度限位,用到这个位置,任务不能再继续使用 (CPU_STK_SIZE)128, //任务堆栈大小 (OS_MSG_QTY)0, //禁止任务消息队列 (OS_TICK)0, //默认时间片长度 (void *)0, //不需要补充用户存储区 (OS_OPT)OS_OPT_TASK_NONE, //没有任何选项 &err //返回的错误码 ); //创建任务2 OSTaskCreate( (OS_TCB *)&Task2_TCB, //任务控制块 (CPU_CHAR *)"Task2", //任务的名字 (OS_TASK_PTR)task2, //任务函数 (void *)0, //传递参数 (OS_PRIO)4, //任务的优先级 (CPU_STK *)task2_stk, //任务堆栈基地址 (CPU_STK_SIZE)128/10, //任务堆栈深度限位,用到这个位置,任务不能再继续使用 (CPU_STK_SIZE)128, //任务堆栈大小 (OS_MSG_QTY)0, //禁止任务消息队列 (OS_TICK)0, //默认时间片长度 (void *)0, //不需要补充用户存储区 (OS_OPT)OS_OPT_TASK_NONE, //没有任何选项 &err //返回的错误码 ); //创建软件定时器1 OSTmrCreate( (OS_TMR *)&tmr1, //软件定时器1 (CPU_CHAR *)"tmr1", //定时器名字 (OS_TICK )20, //20*10=200ms,延迟200ms执行 (OS_TICK )100, //100*10=1000ms,执行周期为1000ms (OS_OPT )OS_OPT_TMR_PERIODIC, //周期模式 (OS_TMR_CALLBACK_PTR )tmr1_callback, //软件定时器1回调函数 (void *)0, //参数为0 (OS_ERR *)&err); //返回的错误码 //启动软件定时器1 OSTmrStart(&tmr1,&err); //启动OS,进行任务调度 OSStart(&err); } void task1(void *parg) { OS_ERR err; printf("task1 is create ok\r\n"); while(1) { printf("task1 is running ...\r\n"); OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); //延时1S } } void task2(void *parg) { OS_ERR err; printf("task2 is create ok\r\n"); while(1) { printf("task2 is running ...\r\n"); OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); //延时1S } } void tmr1_callback(void *ptmr,void *p_arg) { //软件定时器回调函数禁止使用任何的阻塞或者删除定时器函数 printf("tmr1_callback\r\n"); }
/* 描述: 1.当前创建了软件定时器1,工作频率为100Hz,优先级为2,可在os_cfg_app.h进行设置 #define OS_CFG_TMR_TASK_PRIO 2u #define OS_CFG_TMR_TASK_RATE_HZ 100u 2.创建任务1,优先级为3,;创建任务2,优先级为4 3.测试结果: 任务1、任务2、软件定时器回调函数通过临界区代码保护了共享资源,各任务之间很好地执行 */ #include "sys.h" #include "delay.h" #include "usart.h" #include "led.h" #include "includes.h" //任务1控制块 OS_TCB Task1_TCB; void task1(void *parg); CPU_STK task1_stk[128]; //任务1的任务堆栈,大小为128字,也就是512字节 //任务2控制块 OS_TCB Task2_TCB; void task2(void *parg); CPU_STK task2_stk[128]; //任务2的任务堆栈,大小为128字,也就是512字节 OS_TMR tmr1; //定时器1 //软件定时器1回调函数 void tmr1_callback(void *ptmr,void *p_arg); OS_Q queue; //声明消息队列 OS_SEM sem; //声明多值信号量 OS_PEND_DATA mul_pend_array [ 2 ]; //声明等待对象数组 //主函数 int main(void) { OS_ERR err; delay_init(168); //时钟初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断分组配置 uart_init(9600); //串口初始化 LED_Init(); //LED初始化 //OS初始化,它是第一个运行的函数,初始化各种的全局变量,例如中断嵌套计数器、优先级、存储器 OSInit(&err); //创建任务1 OSTaskCreate( (OS_TCB *)&Task1_TCB, //任务控制块 (CPU_CHAR *)"Task1", //任务的名字 (OS_TASK_PTR)task1, //任务函数 (void *)0, //传递参数 (OS_PRIO)3, //任务的优先级 (CPU_STK *)task1_stk, //任务堆栈基地址 (CPU_STK_SIZE)128/10, //任务堆栈深度限位,用到这个位置,任务不能再继续使用 (CPU_STK_SIZE)128, //任务堆栈大小 (OS_MSG_QTY)0, //禁止任务消息队列 (OS_TICK)0, //默认时间片长度 (void *)0, //不需要补充用户存储区 (OS_OPT)OS_OPT_TASK_NONE, //没有任何选项 &err //返回的错误码 ); //创建任务2 OSTaskCreate( (OS_TCB *)&Task2_TCB, //任务控制块 (CPU_CHAR *)"Task2", //任务的名字 (OS_TASK_PTR)task2, //任务函数 (void *)0, //传递参数 (OS_PRIO)4, //任务的优先级 (CPU_STK *)task2_stk, //任务堆栈基地址 (CPU_STK_SIZE)128/10, //任务堆栈深度限位,用到这个位置,任务不能再继续使用 (CPU_STK_SIZE)128, //任务堆栈大小 (OS_MSG_QTY)64, //任务消息队列64字 (OS_TICK)0, //默认时间片长度 (void *)0, //不需要补充用户存储区 (OS_OPT)OS_OPT_TASK_NONE, //没有任何选项 &err //返回的错误码 ); //创建软件定时器1 OSTmrCreate( (OS_TMR *)&tmr1, (CPU_CHAR *)"tmr1", (OS_TICK )20, (OS_TICK )100, (OS_OPT )OS_OPT_TMR_PERIODIC, (OS_TMR_CALLBACK_PTR )tmr1_callback, (void *)0, (OS_ERR *)&err); //启动软件定时器1 OSTmrStart(&tmr1,&err); /* 创建多值信号量 sem */ OSSemCreate ( (OS_SEM *)&sem, //指向要创建的多值信号量 (CPU_CHAR *)"Sem For Test", //多值信号量的名字 (OS_SEM_CTR )0, //多值信号量初始不可用 (OS_ERR *)&err); //返回错误类型 /* 创建消息队列 queue */ OSQCreate ( (OS_Q *)&queue, //指向要创建的消息队列 (CPU_CHAR *)"Queue For Test", //消息队列的名字 (OS_MSG_QTY )20, //最多可容20条消息 (OS_ERR *)&err); //返回错误类型 /* 初始化要等待的多个内核对象 */ mul_pend_array [ 0 ] .PendObjPtr = ( OS_PEND_OBJ * ) & sem; mul_pend_array [ 1 ] .PendObjPtr = ( OS_PEND_OBJ * ) & queue; //启动OS,进行任务调度 OSStart(&err); } void task1(void *parg) { static uint32_t task_cnt=0; char buf[64]={0}; OS_ERR err; printf("task1 is create ok\r\n"); while(1) { task_cnt++; sprintf(buf,"task1 run cnt=%d",task_cnt); /* 发布消息到消息队列 queue */ OSQPost ( (OS_Q *)&queue, //消息队列 (void *)buf, //消息内容 (OS_MSG_SIZE )strlen(buf), //消息长度 (OS_OPT )OS_OPT_POST_FIFO|OS_OPT_POST_ALL, //发到队列且发送给所有任务 (OS_ERR *)&err); //返回错误类型 OSTimeDlyHMSM(0,0,3,0,OS_OPT_TIME_HMSM_STRICT,&err); //延时3S } } void task2(void *parg) { OS_ERR err; printf("task2 is create ok\r\n"); while(1) { /* 等待多个内核对象 */ OSPendMulti((OS_PEND_DATA *)mul_pend_array, //等待对象数组 (OS_OBJ_QTY )2, //等待对象数目 (OS_TICK )0, //无期限等待 (OS_OPT )OS_OPT_PEND_BLOCKING, //阻塞任务 (OS_ERR *)&err); //返回错误类型 /* 查看哪些等待对象可用 */ if ( mul_pend_array [0] .RdyObjPtr == mul_pend_array [0] .PendObjPtr ) //如果 sem 可用 { printf("find tmr1 running...\r\n"); } if ( mul_pend_array [1] .RdyObjPtr == mul_pend_array [1] .PendObjPtr )//如果 queue 可用 { printf("recv msg:%s,len:%d\r\n",(char *) mul_pend_array[1] .RdyMsgPtr, mul_pend_array [1] .RdyMsgSize ); } } } //软件定时器回调函数禁止使用任何的阻塞或者删除定时器函数 void tmr1_callback(void *ptmr,void *p_arg) { OS_ERR err; OSSemPost(&sem,OS_OPT_POST_1,&err); //释放信号量 }