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

求助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管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版