繁体   English   中英

FreeRTOS任务不是上下文切换

[英]FreeRTOS tasks are not context switching

我在PIC32MX入门工具包上使用FreeRTOS端口用于PIC32单片机。 只是玩任务但任务不是上下文切换。 这是我的主要配置设置:

#define configMAX_PRIORITIES    ( ( unsigned portBASE_TYPE ) 5 )
#define configKERNEL_INTERRUPT_PRIORITY         0x01
#define configMAX_SYSCALL_INTERRUPT_PRIORITY    0x03
#define configTICK_RATE_HZ              ( ( portTickType ) 100 )

现在我定义了两个闪烁两个LED的任务。 两者的优先级均为4(最高)。 在正常操作下,LED应该每100个刻度闪烁一次。 但这不会发生。 第二个LED闪烁100个刻度,控制进入常规异常处理程序。 为什么会这样? 好像根本没有调度。

FreeRTOS是基于优先级的先发制人调度程序,不会产生处理器时间的相同优先级的任务将被循环调度。 依靠循环调度很少适合实时任务,并且根据配置的时间片,可能会使您的时间陷入困境。 甚至可以禁用时间分片。

您的任务必须进入阻止状态,等待某些事件(例如已用时间)以允许彼此按预期运行。

也就是说,进入异常处理程序而不是简单地一个任务饿死另一个或没有按预期的时间运行是另一回事。 为此,您需要发布其他信息,但第一种方法应该是部署调试器。

首先要检查的是你的“滴答”中断。 通常没有启用中断,定时器设置不正确,在设置PIC32的#pragma中没有正确配置时钟......所有这些问题首先表现为缺少“滴答”。

这是没有任务切换的首要原因:如果你没有得到嘀嗒中断。 这就是正常的先发制人任务切换发生的地方。

假设您正在使用“现成的演示”,在MPLAB中,在void vPortIncrementTick( void )函数中设置断点(在FreeRTOS \\ Source \\ portable \\ _PDF \\ MPLAB \\ PIC32MX \\ port.c中的第177行附近)并运行您的代码。 如果它在那里断点,你的计时器滴答工作正常。

你有循环调度程序吗? 你的任务是否在任何时间内都在睡觉,或只是屈服(或忙着等待)?

嵌入式操作系统中非常常见的问题是调度程序经常不会尝试公平地调度具有相同优先级的多个进程。 也就是说,一旦A产生,如果A是可运行的,即使B没有任何年龄的CPU,A也可能立即再次进行调度。 如果你习惯于那些需要付出很多努力去做公平调度的桌面操作系统(或者至少对我而言),这是非常违反直觉的。

如果你遇到这个问题,你需要确保你的任务看起来像这样:

for (;;)
{
  led(on); sleep(delay);
  led(off); sleep(delay);
}

...确保任务实际上在闪烁之间停止运行。 如果看起来像这样,它将无法工作:

for (;;)
{
  led(on);
  led(off);
}

(另外,作为一般规则,你想使用普通优先级而不是高优先级,除非你知道你真的需要它 - 如果你饿了系统任务,系统会表现得很奇怪或崩溃。)

您确定这两项任务都已完好注册且调度程序已启动吗?

像下面的代码一样可以完成这项工作:

xTaskCreate( yourFirstTask, "firstTask", STACK_SIZE, NULL, TASK_PRIORITY, NULL );
xTaskCreate( yourSecondTask, "secondTask", STACK_SIZE, NULL, TASK_PRIORITY, NULL );
vTaskStartScheduler();

您还可以添加应用程序勾选挂钩,以查看是否正确发生了嘀嗒中断或者是否存在嘀嗒计时器问题。

有一些标准的演示任务只会使FreeRTOS / Demo / Common / Minimal / flash.c源文件中的LED闪烁。 在该文件中创建的任务包含在标准PIC32演示应用程序(面向Microchip Explorer16板)中。

在最简单的形式中,每500毫秒切换一次和LED的任务看起来像这样:

/* Standard task prototype, the parameter is not used in this case. */    
void vADummyTask( void *pvParameters )
{
const portTickType xDelayTime = 500 / portTICK_RATE_MS;

    for( ;; )
    {
        ToggleLED();
        vTaskDelay( xDelayTime );
    }        
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM