OpenEdv-开源电子网

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

FREERTOS第一个例程的任务优先级问题

[复制链接]

3

主题

5

帖子

0

精华

新手入门

积分
17
金钱
17
注册时间
2019-7-26
在线时间
5 小时
发表于 2019-7-26 18:29:20 | 显示全部楼层 |阅读模式
1金钱
我将原例程的vTaskDelay函数注释掉,换成delay函数,led1的优先级比led0的优先级高,为什么代码执行的效果仍然是两个线程“同时”在执行,即两个灯都在闪烁,而不是只执行优先级高的led1程序,从而达到只有一个灯亮的效果。

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "FreeRTOS.h"
#include "task.h"


//任务优先级
#define START_TASK_PRIO                1
//任务堆栈大小       
#define START_STK_SIZE                 128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);

//任务优先级
#define LED0_TASK_PRIO                2
//任务堆栈大小       
#define LED0_STK_SIZE                 50  
//任务句柄
TaskHandle_t LED0Task_Handler;
//任务函数
void led0_task(void *pvParameters);

//任务优先级
#define LED1_TASK_PRIO                3
//任务堆栈大小       
#define LED1_STK_SIZE                 50
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void led1_task(void *pvParameters);

int main(void)
{
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4         
        delay_init();                                            //延时函数初始化                 
        uart_init(115200);                                        //初始化串口
        LED_Init();                                                          //初始化LED
         
        //创建开始任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();          //开启任务调度
}

//开始任务任务函数
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区
    //创建LED0任务
    xTaskCreate((TaskFunction_t )led0_task,            
                (const char*    )"led0_task",          
                (uint16_t       )LED0_STK_SIZE,
                (void*          )NULL,                               
                (UBaseType_t    )LED0_TASK_PRIO,       
                (TaskHandle_t*  )&LED0Task_Handler);   
    //创建LED1任务
    xTaskCreate((TaskFunction_t )led1_task,     
                (const char*    )"led1_task",   
                (uint16_t       )LED1_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )LED1_TASK_PRIO,
                (TaskHandle_t*  )&LED1Task_Handler);         
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
}

//LED0任务函数
void led0_task(void *pvParameters)
{
    while(1)
    {
        LED0=~LED0;
        //vTaskDelay(500);
                delay_ms(500);
    }
}   

//LED1任务函数
void led1_task(void *pvParameters)
{
    while(1)
    {
        LED1=0;
        //vTaskDelay(200);
                delay_ms(500);
        LED1=1;
        //vTaskDelay(800);
                delay_ms(500);

    }
}


最佳答案

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

原子的delay_ms是调用了vTaskDelay的,vTaskDelay会引起任务调度,肯定连个灯都闪啊
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

26

主题

1533

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6369
金钱
6369
注册时间
2015-8-25
在线时间
1004 小时
发表于 2019-7-26 18:29:21 | 显示全部楼层
原子的delay_ms是调用了vTaskDelay的,vTaskDelay会引起任务调度,肯定连个灯都闪啊
He who fights with monsters should look to it that he himself does not become a monster, when you gaze long into the abyss, the abyss also gazes into you.
过于执着就会陷入其中,迷失自己,困住自己。
回复

使用道具 举报

3

主题

5

帖子

0

精华

新手入门

积分
17
金钱
17
注册时间
2019-7-26
在线时间
5 小时
 楼主| 发表于 2019-7-26 18:40:06 | 显示全部楼层
szczyb1314 发表于 2019-7-26 18:38
原子的delay_ms是调用了vTaskDelay的,vTaskDelay会引起任务调度,肯定连个灯都闪啊

是吗?我没仔细看delay那里的,我再去看看
回复

使用道具 举报

12

主题

32

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2018-11-22
在线时间
24 小时
发表于 2019-7-29 15:12:10 | 显示全部楼层
试试delay_xms
回复

使用道具 举报

6

主题

64

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
320
金钱
320
注册时间
2017-10-14
在线时间
80 小时
发表于 2019-8-31 10:27:09 | 显示全部楼层
//延时nms,会引起任务调度
//nms:要延时的ms数
//nms:0~65535
void delay_ms(u32 nms)
{       
        if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)//系统已经运行
        {               
                if(nms>=fac_ms)                                                //延时的时间大于OS的最少时间周期
                {
                           vTaskDelay(nms/fac_ms);                         //FreeRTOS延时
                }
                nms%=fac_ms;                                                //OS已经无法提供这么小的延时了,采用普通方式延时   
        }
        delay_us((u32)(nms*1000));                                //普通方式延时
}
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-22 22:19

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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