你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

求助STM32F103 FreeRTOS任务调度异常问题

[复制链接]
pretty868 提问时间:2018-10-8 10:03 /
系统设置2个任务,系统运行时出现一些异常现象,请问有没有遇到过?是什么原因引起的?

方式1:系统运行正常
void Task1_Task(void * pvParameters)
{
                        while(1)
                        {
                                                vTaskDelay(500);                      //延时函数(任务调度)
                                                printf("Task1\r\n");                  //串口打印
                        }
}
void Task2_Task(void * pvParameters)
{
                        while(1)
                        {
                                                Delay_Ms(500);                        //延时函数(无任务调度)
                                                LED_TOGGLE;                          //LED闪烁(取反)
                        }
}


方式2:任务1正常,任务2没反应,LED不闪烁
void Task1_Task(void * pvParameters)
{
                        while(1)
                        {
                                                Delay_Ms(500);                        //延时函数(无任务调度)
                                                printf("Task1\r\n");                  //串口打印
                        }
}
void Task2_Task(void * pvParameters)
{
                        while(1)
                        {
                                                vTaskDelay(500);                      //延时函数(任务调度)
                                                LED_TOGGLE;                          //LED闪烁(取反)
                        }
}


方式3:任务1正常,任务2没反应,LED不闪烁
void Task1_Task(void * pvParameters)
{
                        while(1)
                        {
                                                Delay_Ms(500);                        //延时函数(无任务调度)
                                                printf("Task1\r\n");                  //串口打印
                        }
}
void Task2_Task(void * pvParameters)
{
                        while(1)
                        {
                                                Delay_Ms(500);                        //延时函数(无任务调度)
                                                LED_TOGGLE;                          //LED闪烁(取反)
                        }
}

收藏 评论20 发布时间:2018-10-8 10:03

举报

20个回答
pretty868 回答时间:2018-10-8 15:07:56
toofree 发表于 2018-10-8 12:21
Delay_Ms()是软件延时,死等吗?
在操作系统中最好不要用死等,除非任务之间有些条件,不得不这么做。
vTa ...

我系统里面有个创建任务的函数(创建任务1和任务2),必须把它的优秀级调高(大于任务1和任务2),系统才能正常,才能跟你的描述相一致!谢谢您的指教

创建任务的函数如下:
void Create_Task(void * pvParameters)
{
                  xTaskCreate((TaskFunction_t) Task1_Task,
                                                                        (char*         ) "Task1_Task",               
                                                                        (uint16_t      ) TASK1_STK_SIZE,
                                                                        (void*                                 ) NULL,
                                                                        (UBaseType_t         ) TASK1_TASK_PRIO,
                                                                        (TaskHandle_t* ) &Task1_Handle);
                                                                  
                  xTaskCreate((TaskFunction_t) Task2_Task,
                                                                        (char*         ) "Task2_Task",               
                                                                        (uint16_t      ) TASK2_STK_SIZE,
                                                                        (void*                                 ) NULL,
                                                                        (UBaseType_t         ) TASK2_TASK_PRIO,
                                                                        (TaskHandle_t* ) &Task2_Handle);
                                                                  
                        vTaskDelete(TaskCreate_Handle);               
}
轩辕紫木 回答时间:2018-10-8 14:25:28
你是刚弄RTOS吗?看看操作系统的基础书籍,有一些概念的认识
while(1)
                        {
                                                Delay_Ms(500);                        //延时函数(无任务调度)
                                                printf("Task1\r\n");                  //串口打印
                        }
这个不会引起任务调度,会一直执行这个while循环。vTaskDelay会引起任务的调度,任务会交替执行。所以你如果想交替执行,你在上面的任务里加一个vTaskDelay()也可以。
pretty868 回答时间:2018-10-8 12:33:38
toofree 发表于 2018-10-8 12:21
Delay_Ms()是软件延时,死等吗?
在操作系统中最好不要用死等,除非任务之间有些条件,不得不这么做。
vTa ...

Delay_Ms()是软件延时,死循环等待。
原来的优先级:
#define                  TASK1_TASK_PRIO        2
#define                  TASK2_TASK_PRIO        3

改为如下:问题依旧
#define                  TASK1_TASK_PRIO        3
#define                  TASK2_TASK_PRIO        2

改为如下:问题依旧
#define                  TASK1_TASK_PRIO        2
#define                  TASK2_TASK_PRIO        2
程序员 回答时间:2018-10-8 11:46:01
你可以试试把延迟  Delay_Ms(500);      改短,看一下结果吗?

评分

参与人数 1蝴蝶豆 +1 收起 理由
STMCU + 1

查看全部评分

pretty868 回答时间:2018-10-8 12:02:01
程序员 发表于 2018-10-8 11:46
你可以试试把延迟  Delay_Ms(500);      改短,看一下结果吗?

改为延时50和延时100均不行,异常问题依旧,任务1能正常,任何2不执行
七哥 回答时间:2018-10-8 12:21:00
本帖最后由 toofree 于 2018-10-8 12:29 编辑

Delay_Ms()是软件延时,死等吗?
在操作系统中最好不要用死等,除非任务之间有些条件,不得不这么做。
vTaskDelay()是任务阻塞时间,也就是释放当前任务时间,可以在这段时间内可以去执行别的任务。

任务优先级高的,可以打断优先级低的;但是不能打断同级别或高级别的。
一旦高优先级任务,来一个死等,那么其它同级或低级别的只能干瞪眼,执行不上任务。

你把两个任务的优先级掉换一下试试,数值大的优先级高,小的优先级低

评分

参与人数 1蝴蝶豆 +3 收起 理由
STMCU + 3

查看全部评分

cos12a-21701 回答时间:2018-10-8 12:33:04
楼上的正解。
轩辕紫木 回答时间:2018-10-8 14:11:13
我觉得你的方式2和方式3的结果正常。反而方式1的两个任务都会执行,有点问题。你试一下将LED反转的函数换成printf,在看看结果

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

pretty868 回答时间:2018-10-8 14:18:10
hu9977 发表于 2018-10-8 14:11
我觉得你的方式2和方式3的结果正常。反而方式1的两个任务都会执行,有点问题。你试一下将LED反转的函数换成 ...

为什么方式2和方式3的结果是正常呢?能否解析一下。我把LED反转的函数换成printf,任务1正常,任务2依然没执行,没有串口数据输出
pretty868 回答时间:2018-10-8 14:31:37
hu9977 发表于 2018-10-8 14:25
你是刚弄RTOS吗?看看操作系统的基础书籍,有一些概念的认识
while(1)
                        {

嗯嗯,我是刚接触RTOS。
按照您的意思,是不是所有的任务里面都需要有vTaskDelay才会以前任务调度,系统才能正常的跑起来?
轩辕紫木 回答时间:2018-10-8 14:35:39
pretty868 发表于 2018-10-8 14:31
嗯嗯,我是刚接触RTOS。
按照您的意思,是不是所有的任务里面都需要有vTaskDelay才会以前任务调度,系统 ...

vTaskDelay可以引起调度,这个是入门最容易弄的,后面还有信号量,队列,邮箱等等都可以引起调度
pretty868 回答时间:2018-10-8 15:12:25
hu9977 发表于 2018-10-8 14:35
vTaskDelay可以引起调度,这个是入门最容易弄的,后面还有信号量,队列,邮箱等等都可以引起调度 ...

明白了,谢谢
程序员 回答时间:2018-10-8 15:30:09
pretty868 发表于 2018-10-8 12:02
改为延时50和延时100均不行,异常问题依旧,任务1能正常,任何2不执行

你看你的中断触发时间,同时也要保证一点单个任务运行的时间不能大于你的时标间隔。所以如果你的时标是us级的,你可以尝试将Delay_Ms(500);改为Us级。或者直接使用vTaskDelay()。
xiaojie0513 回答时间:2018-10-9 13:09:42
用   vTaskDelay()   啊,,,你这是死等,建议看看我的文章
12下一页
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版