UCOSIII的例程之使用信号量访问共享资源区

2019-08-19 19:04发布

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "includes.h"
#include "lcd.h"
#include "key.h"
#include "string.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 64
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 64
OS_TCB Task2_TaskTCB;
CPU_STK TASK2_TASK_STK[TASK2_STK_SIZE];
void task2_task(void *p_arg);

u8 share_resource[30];

OS_SEM MY_SEM;

int main(void)
{
        OS_ERR err;
        CPU_SR_ALLOC();
        
        delay_init();
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        uart_init(115200);
        led_Init();
        LCD_Init();
        key_Init();
        
        POINT_COLOR = RED;
  LCD_ShowString(30,10,200,16,16,"ALIENTEK STM32F1");
        LCD_ShowString(30,30,200,16,16,"UCOSIII Examp 10-1");
        LCD_ShowString(30,50,200,16,16,"Visit Share Resource");
        LCD_ShowString(30,70,200,16,16,"ATOM@ALIENTEK");
        LCD_ShowString(30,90,200,16,16,"2016/1/21");
        
        
        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,
                     (OS_TICK)0,
                     (void*)0,
                           (OS_OPT)OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
                     (OS_ERR*)&err);
        OS_CRITICAL_EXIT();
  OSStart(&err);                                                         
}        



void start_task(void *p_arg)
{
        OS_ERR err;
        CPU_SR_ALLOC();
        p_arg=p_arg;
        
        CPU_Init();
        
        #if OS_CFG_STAT_TASK_EN>0u
        OSStatTaskCPUUsageInit(&err);
        #endif
                                                                 
        OS_CRITICAL_ENTER();

          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);                                 
                                                
             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);               

    OSSemCreate((OS_SEM*)&MY_SEM,
                                                                 (CPU_CHAR*)"MY_SEM",
                                                                 (OS_SEM_CTR)1,
                                                                 (OS_ERR*)&err);                                                                 
                                OS_CRITICAL_EXIT();
        OSTaskDel((OS_TCB*)0,&err);                                                         
        
}

void task1_task(void *p_arg)
{
        OS_ERR err;
        u8 task1_str[]="First task Running";
        
        while(1)
        {
                printf(" 任务  1: ");
                LCD_Fill(0,110,239,319,CYAN);
                OSSemPend(&MY_SEM,0,OS_OPT_PEND_BLOCKING,0,&err);
                memcpy(share_resource,task1_str,sizeof(task1_str));
                delay_ms(200);
                printf("%s ",share_resource);
                OSSemPost(&MY_SEM,OS_OPT_POST_1,&err);
                PBout(5)=!PBout(5);
                OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err);

        }
        
        
}



void task2_task(void *p_arg)
{
        //u8 i=0;
        OS_ERR err;
        u8 task2_str[]="Second task Running";
        
        while(1)
        {
                printf(" 任务  2: ");
                LCD_Fill(0,110,239,319,BROWN);
                OSSemPend(&MY_SEM,0,OS_OPT_PEND_BLOCKING,0,&err);
                memcpy(share_resource,task2_str,sizeof(task2_str));
                delay_ms(200);
                printf("%s ",share_resource);
                OSSemPost(&MY_SEM,OS_OPT_POST_1,&err);
                PEout(5)=!PEout(5);
                OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err);

        }
}
请问为什么不是先输出任务 1和任务 2再输出"First task Running"?delay_ms(200)不是发生了一次任务调度吗?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
14条回答
电子询问
1楼-- · 2019-08-20 11:48
 精彩回答 2  元偷偷看……
zc123
2楼-- · 2019-08-20 11:56
delay_ms() 就是普通延时,怎么会引发任务切换呢,引发任务切换的是
OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err);这个才是操作系统的延时切换函数
你现在打印的是
任务  1:
"First task Running";
任务  2:
"Second task Running";
你将delay_ms替换为OSTimeDlyHMSM(0,0,0,200,OS_OPT_TIME_PERIODIC,&err);, 就是你想要的答案了
电子询问
3楼-- · 2019-08-20 15:47
zc123 发表于 2016-11-30 10:57
delay_ms() 就是普通延时,怎么会引发任务切换呢,引发任务切换的是
OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_P ...

delay_ms()y也会引起任务调度吧,delay_us()才是普通延时吧。
打洞者
4楼-- · 2019-08-20 19:59
电子询问 发表于 2016-11-29 22:40
复位之后第一次是 但为什么以后的就不是呢?

上电或是复位,代码从头开始执行:
1. 打印屏幕ID
2. 打印 “任务一”,delay_ms(200),触发任务切换,执行任务task2_task
3. 打印 “任务二”,delay_ms(200),触发任务切换,执行任务task1_task
4. 打印 “First task Running”,OSTimeDlyHMSM(1s),延时1s,触发任务切换,执行任务task2_task
5. 打印 “Sencond task Running”,OSTimeDlyHMSM(1s),延时1s,触发任务切换,执行任务task2_task
6.  打印 “任务一”,delay_ms(200),触发任务切换,执行任务task2_task
7. 切换至 “任务二”后,由于“任务二”正在执行1s延时,故200ms后,“任务二”1s延时还未结束,随即“任务一”开始执行,打印“First task Running”,“任务一”开始1s延时,触发任务切换,执行任务task2_task
8.  打印 “任务二”,delay_ms(200),触发任务切换,执行任务task1_task
9. 切换至 “任务一”后,由于“任务一”正在执行1s延时,故200ms后,“任务一”1s延时还未结束,随即“任务二”开始执行,打印“Second task Running”,“任务二”开始1s延时,触发任务切换,执行任务task1_task
10. 重复步骤6
电子询问
5楼-- · 2019-08-20 20:57
打洞者 发表于 2017-1-5 09:21
上电或是复位,代码从头开始执行:
1. 打印屏幕ID
2. 打印 “任务一”,delay_ms(200),触发任务切换, ...

后面的步骤没什么问题,但步骤2是否应该改为“任务二请求信号量失败,任务二阻塞,执行任务一”,然后步骤5加一个任务二延时200ms后任务一的延时还没结束?
打洞者
6楼-- · 2019-08-21 02:13
 精彩回答 2  元偷偷看……

一周热门 更多>