簡體   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