OpenEdv-开源电子网

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

FreeRTOS互斥信号量实验结果和二值信号量实验结果一样,这个是怎么回事呢??

[复制链接]

5

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
124
金钱
124
注册时间
2019-10-14
在线时间
24 小时
发表于 2020-3-11 16:14:51 | 显示全部楼层 |阅读模式
5金钱
本帖最后由 超级无敌磊果果 于 2020-3-11 16:17 编辑

这是程序,就一个互斥信号量的基础运用实验,但是他硬是不行,high_task请求高优先级任务的时候 low_task占用互斥信号量,那他的优先级应该会被临时拉高到high_task一样的优先级,使得medium_task任务阻塞,但是程序跑起来,中等优先级任务并未被阻塞

  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "usart.h"
  4. #include "led.h"
  5. #include "FreeRTOS.h"
  6. #include "task.h"
  7. #include "./KEY/key.h"
  8. #include "./TIM_Basic/tim_basic.h"
  9. #include "semphr.h"

  10. //任务优先级
  11. #define START_TASK_PRIO                1
  12. //任务堆栈大小        
  13. #define START_STK_SIZE                 128  
  14. //任务句柄
  15. TaskHandle_t StartTask_Handler;
  16. //任务函数
  17. void Start_Task(void *pvParameters);

  18. //任务优先级
  19. #define LOW_TASK_PRIO                2
  20. //任务堆栈大小        
  21. #define LOW_STK_SIZE                 256
  22. //任务句柄
  23. TaskHandle_t Low_Handler;
  24. //任务函数
  25. void Low_Task(void *pvParameters);

  26. //任务优先级
  27. #define MEDIUM_TASK_PRIO                3
  28. //任务堆栈大小        
  29. #define MEDIUM_STK_SIZE                 256
  30. //任务句柄
  31. TaskHandle_t Medium_Task_Handler;
  32. //任务函数
  33. void Medium_Task(void *pvParameters);

  34. //任务优先级
  35. #define HIGH_TASK_PRIO                        4
  36. //任务堆栈大小        
  37. #define HIGH_STK_SIZE                         256
  38. //任务句柄
  39. TaskHandle_t High_Task_Handler;
  40. //任务函数
  41. void High_Task(void *pvParameters);

  42. //定义互斥信号量
  43. SemaphoreHandle_t mutexsemaphore;

  44. int main(void)
  45. {
  46.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
  47.         delay_init();                                            //延时函数初始化
  48.         uart_init(115200);                                //初始化串口
  49.         LED_Init();                                                          //初始化LED
  50.         KEY_Config();                                                        //初始化按键
  51.         
  52.         printf("\r\n互斥信号量操作实验\r\n\r\n");
  53.         
  54.         //创建开始任务
  55.         xTaskCreate((TaskFunction_t )Start_Task,            //任务函数
  56.                                                         (const char*    )"start_task",          //任务名称
  57.                                                         (uint16_t       )START_STK_SIZE,        //任务堆栈大小
  58.                                                         (void*          )NULL,                  //传递给任务函数的参数
  59.                                                         (UBaseType_t    )START_TASK_PRIO,       //任务优先级
  60.                                                         (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
  61.         vTaskStartScheduler();          //开启任务调度
  62. }

  63. //开始任务任务函数
  64. void Start_Task(void *pvParameters)
  65. {
  66.         taskENTER_CRITICAL();           //进入临界区

  67.         //创建互斥信号量
  68.         mutexsemaphore=xSemaphoreCreateMutex();
  69.         if(mutexsemaphore==NULL)
  70.                 printf("semaphorebinary Create Failed in start_task()!\r\n");

  71.         //创建Low任务
  72.         xTaskCreate((TaskFunction_t )Low_Task,            
  73.                                                         (const char*    )"Task1_Task",           
  74.                                                         (uint16_t       )LOW_STK_SIZE,
  75.                                                         (void*          )NULL,                                
  76.                                                         (UBaseType_t    )LOW_TASK_PRIO,        
  77.                                                         (TaskHandle_t*  )&Low_Handler);
  78.         //创建Medium任务
  79.         xTaskCreate((TaskFunction_t )Medium_Task,            
  80.                                                         (const char*    )"Medium_task",           
  81.                                                         (uint16_t       )MEDIUM_STK_SIZE,
  82.                                                         (void*          )NULL,                                
  83.                                                         (UBaseType_t    )MEDIUM_TASK_PRIO,        
  84.                                                         (TaskHandle_t*  )&Medium_Task_Handler);
  85.         //创建High任务
  86.         xTaskCreate((TaskFunction_t )High_Task,            
  87.                                                         (const char*    )"High_task",           
  88.                                                         (uint16_t       )HIGH_STK_SIZE,
  89.                                                         (void*          )NULL,                                
  90.                                                         (UBaseType_t    )HIGH_TASK_PRIO,        
  91.                                                         (TaskHandle_t*  )&High_Task_Handler);
  92.                                                         
  93.         vTaskDelete(StartTask_Handler); //删除开始任务
  94.         taskEXIT_CRITICAL();            //退出临界区
  95. }

  96. //Low任务函数
  97. void Low_Task(void *pvParameters)
  98. {
  99.         uint8_t i=0;
  100.         while(1)
  101.         {
  102.                 if(mutexsemaphore!=NULL)
  103.                         xSemaphoreTake(mutexsemaphore,portMAX_DELAY);        //获取互斥信号量
  104.                 printf("Low Priority Task Running!\r\n");
  105.                 for(i=0;i<20;i++)
  106.                 {
  107.                         delay_ms(300);
  108.                 }
  109.                 xSemaphoreGive(mutexsemaphore);        //释放互斥信号量
  110.                 vTaskDelay(1000);
  111.         }
  112. }

  113. //Medium_Task任务函数
  114. void Medium_Task(void *pvParameters)
  115. {
  116.         while(1)
  117.         {
  118.                 printf("Medium Priority Task Running!\r\n");
  119.                 vTaskDelay(1000);
  120.         }
  121. }


  122. //High_Task任务函数
  123. void High_Task(void *pvParameters)
  124. {
  125.         while(1)
  126.         {
  127.                 printf("High Priority Task apply Semaphare!\r\n");
  128.                 xSemaphoreTake(mutexsemaphore,portMAX_DELAY);        //获取互斥信号量
  129.                 printf("High Priority Task Running!\r\n");
  130.                 xSemaphoreGive(mutexsemaphore);        //释放互斥信号量
  131.                 vTaskDelay(1000);
  132.         }
  133. }

复制代码



批注 2020-03-11 161009.jpg

最佳答案

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

自己写一个for死循环,不要用原子例程里的delay_ms(300),因为它那个可能是调用了系统的api函数把cpu释放掉了. 自己写个真正把cpu完全吃死的.
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

114

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2583
金钱
2583
注册时间
2019-10-18
在线时间
414 小时
发表于 2020-3-11 16:14:52 | 显示全部楼层
自己写一个for死循环,不要用原子例程里的delay_ms(300),因为它那个可能是调用了系统的api函数把cpu释放掉了.
自己写个真正把cpu完全吃死的.
回复

使用道具 举报

5

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
124
金钱
124
注册时间
2019-10-14
在线时间
24 小时
 楼主| 发表于 2020-3-11 17:11:05 | 显示全部楼层
发现只要把low_task的for循环改一下
                for(i=0;i<40000;i++)
                {
                        delay_us(100);        //注意这里时间要短一些
                }
改成这样子,增加循环的次数,但是减少每次循环的时间就可以了,这是为什么呢?求解
回复

使用道具 举报

0

主题

114

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2583
金钱
2583
注册时间
2019-10-18
在线时间
414 小时
发表于 2020-3-12 10:38:15 | 显示全部楼层
300ms的延时函数里有系统阻塞的api函数,你可以跟踪进去看看
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-22 08:11

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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