OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4679|回复: 14

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

[复制链接]

12

主题

35

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1083
金钱
1083
注册时间
2016-7-22
在线时间
103 小时
发表于 2016-9-6 17:53:07 | 显示全部楼层 |阅读模式
5金钱
#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("\r\n任务  1:\r\n");
                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\r\n",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("\r\n任务  2:\r\n");
                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\r\n",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)不是发生了一次任务调度吗?

最佳答案

查看完整内容[请看2#楼]

板子开始运行代码,串口最开始输出的就是 LCD ID:ffff 任务1: 任务2: First task Running! Second task Running! 任务1: First task Running! 任务2: Second task Running! 任务1: First task Running! 任务2: Second task Running! 任务1: First task Running! 任务2: Second task Running!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

7

主题

60

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
299
金钱
299
注册时间
2015-10-21
在线时间
52 小时
发表于 2016-9-6 17:53:08 | 显示全部楼层
板子开始运行代码,串口最开始输出的就是

LCD ID:ffff

任务1:

任务2:
First task Running!
Second task Running!

任务1:
First task Running!

任务2:
Second task Running!

任务1:
First task Running!

任务2:
Second task Running!

任务1:
First task Running!

任务2:
Second task Running!
回复

使用道具 举报

20

主题

122

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
407
金钱
407
注册时间
2016-3-27
在线时间
104 小时
发表于 2016-10-14 16:34:50 | 显示全部楼层
任务调度发生在信号量发生的时候
回复

使用道具 举报

20

主题

122

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
407
金钱
407
注册时间
2016-3-27
在线时间
104 小时
发表于 2016-10-14 16:35:03 | 显示全部楼层
任务调度发生在信号量发生的时候
回复

使用道具 举报

19

主题

430

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1341
金钱
1341
注册时间
2016-4-22
在线时间
187 小时
发表于 2016-10-14 17:09:34 | 显示全部楼层
两个任务都卡在OSSemPend了吧。
伤情最是晚凉天,憔悴斯人不堪怜。
邀酒摧肠三杯醉,寻香惊梦五更寒。
钗头凤斜卿有泪,荼蘼花了我无缘。
小楼寂寞新雨月,也难如钩也难圆。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2016-10-14 18:28:21 | 显示全部楼层
帮顶
回复

使用道具 举报

7

主题

60

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
299
金钱
299
注册时间
2015-10-21
在线时间
52 小时
发表于 2016-11-29 13:03:51 | 显示全部楼层

delay_ms() 延时引起任务切换,代码运行结果串口打印不应该是:

任务1:
任务2:
First task Running!
Second task Running!
回复

使用道具 举报

12

主题

35

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1083
金钱
1083
注册时间
2016-7-22
在线时间
103 小时
 楼主| 发表于 2016-11-29 22:40:27 | 显示全部楼层
打洞者 发表于 2016-11-29 21:38
板子开始运行代码,串口最开始输出的就是

LCD ID:ffff

复位之后第一次是 但为什么以后的就不是呢?
回复

使用道具 举报

3

主题

401

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1770
金钱
1770
注册时间
2015-6-11
在线时间
313 小时
发表于 2016-11-30 10:57:08 | 显示全部楼层
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);, 就是你想要的答案了
回复

使用道具 举报

12

主题

35

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1083
金钱
1083
注册时间
2016-7-22
在线时间
103 小时
 楼主| 发表于 2016-12-1 20:23:48 | 显示全部楼层
zc123 发表于 2016-11-30 10:57
delay_ms() 就是普通延时,怎么会引发任务切换呢,引发任务切换的是
OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_P ...

delay_ms()y也会引起任务调度吧,delay_us()才是普通延时吧。
回复

使用道具 举报

7

主题

60

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
299
金钱
299
注册时间
2015-10-21
在线时间
52 小时
发表于 2017-1-5 09:21:18 | 显示全部楼层
电子询问 发表于 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
回复

使用道具 举报

12

主题

35

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1083
金钱
1083
注册时间
2016-7-22
在线时间
103 小时
 楼主| 发表于 2017-1-8 16:10:22 | 显示全部楼层
打洞者 发表于 2017-1-5 09:21
上电或是复位,代码从头开始执行:
1. 打印屏幕ID
2. 打印 “任务一”,delay_ms(200),触发任务切换, ...

后面的步骤没什么问题,但步骤2是否应该改为“任务二请求信号量失败,任务二阻塞,执行任务一”,然后步骤5加一个任务二延时200ms后任务一的延时还没结束?
回复

使用道具 举报

7

主题

60

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
299
金钱
299
注册时间
2015-10-21
在线时间
52 小时
发表于 2017-5-8 10:00:24 | 显示全部楼层
电子询问 发表于 2017-1-8 16:10
后面的步骤没什么问题,但步骤2是否应该改为“任务二请求信号量失败,任务二阻塞,执行任务一”,然后步 ...

可以这么说
回复

使用道具 举报

12

主题

35

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1083
金钱
1083
注册时间
2016-7-22
在线时间
103 小时
 楼主| 发表于 2017-5-8 15:59:21 | 显示全部楼层

谢谢
回复

使用道具 举报

12

主题

35

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1083
金钱
1083
注册时间
2016-7-22
在线时间
103 小时
 楼主| 发表于 2017-5-8 16:01:00 | 显示全部楼层
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-8-21 16:23

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表