我已經使用FreeRTOS
一些嵌入式項目的一年時間,它的工作非常完美,直到現在。目前我正面臨一個難題,涉及使用高速中斷FreeRTOS
移植到PIC24H
,希望大家能幫助我解決這個問題。在此先感謝FreeRTOS錯誤與高速UART中斷在PIC24H
我創建了簡單的測試一個小的演示項目:
兩個任務:
// Task 1
if (xTaskCreate(RTOSTask_1, (signed char) "[T1]", configMINIMAL_STACK_SIZE2, NULL, tskIDLE_PRIORITY + 1, &hTask1) == errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY)
{
LREP("\r\nCannot create Task 1.");
Display_Error(1000);
}
// Task 2
if (xTaskCreate(RTOSTask_2, (signed char) "[T2]", configMINIMAL_STACK_SIZE2, NULL, tskIDLE_PRIORITY + 2, &hTask2) == errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY)
{
LREP("\r\nCannot create Task 2.");
Display_Error(1000);
}
執行的任務:
void RTOSTask_1(void* pvParameter)
{
while(1)
{
if (xSemaphoreTake(hTask1Semaphore, portMAX_DELAY) == pdTRUE)
{
putchar1('1');
}
}
}
void RTOSTask_2(void* pvParameter)
{
while(1)
{
if (xSemaphoreTake(hTask2Semaphore, portMAX_DELAY) == pdTRUE)
{
putchar1('2');
}
}
}
爲了讓上述兩個任務運行我使用一個Timer
&一個UART
給他們信號量:
void attribute((interrupt, auto_psv)) _T2Interrupt (void)
{
_T2IF = 0;
static signed portBASE_TYPE xTaskWoken = pdFALSE;
xSemaphoreGiveFromISR(hTask1Semaphore, &xTaskWoken);
if(xTaskWoken != pdFALSE)
{
taskYIELD();
}
}
void attribute((interrupt, auto_psv)) _U1TXInterrupt()
{
_U1TXIF = 0;
putchar1('E');
}
void attribute((interrupt, auto_psv)) _U1RXInterrupt()
{
_U1RXIF = 0;
if(U1STAbits.URXDA == 1)
{
uint8 u8Recv = U1RXREG;
}
static signed portBASE_TYPE xTaskWoken;
xTaskWoken = pdFALSE;
xSemaphoreGiveFromISR(hTask2Semaphore, &xTaskWoken);
if(xTaskWoken != pdFALSE)
{
taskYIELD();
}
}
我的計時器每100us中斷一次,UART以230400bps的波特率工作。
運行一些秒或分鐘的程序崩潰,程序跳轉到陷阱後:
_AddressError
或
_StackError
我不知道怎麼會發生這個問題。經過長期調查&測試我認爲當運行在中斷服務例程(ISR)的&程序運行時出現問題。看來我們需要幾個SAVE_CONTEXT()
& RESTORE_CONTEXT()
函數。但在PIC24端口上沒有這樣的人。
請你請給我一些建議針對此問題
謝謝大家!
我已經發現我的問題了,我想。當PIC24H進入&時出現中斷服務程序,在這裏它們是UART RX,TX,定時器中斷。
目前我不這樣使用ISR:
無效屬性((中斷,auto_psv)時)
,而不是它我創建了一個機制,我自己用匯編代碼:
__U1RXInterrupt: ;將CPU寄存器推入堆棧
PUSH SR
PUSH W0
PUSH W1
PUSH.D W2
PUSH.D W4
PUSH.D W6
PUSH.D W8
PUSH.D W10
PUSH.D W12
PUSH W14
PUSH RCOUNT
PUSH TBLPAG
PUSH CORCON
PUSH PSVPAG
; Call my ISR
call _UART1_RxISRHandler
; Pop out CPU registers
POP PSVPAG
POP CORCON
POP TBLPAG
POP RCOUNT
POP W14
POP.D W12
POP.D W10
POP.D W8
POP.D W6
POP.D W4
POP.D W2
POP.D W0
POP SR
retfie
UART1_RxISRHandler是我的ISR實現。我對TX,Timer中斷做了同樣的處理。
結果是我的程序運行得更順利,時間更長1小時(程序在1-5分鐘後崩潰之前)。但最終在運行1-2小時後仍會崩潰。這意味着我的方法是正確的,但仍然有問題。可能是我錯過了上面的代碼。
如果您對這種情況都有任何理想,請告訴我。
謝謝
好,通過230400波特信令每一個字符一個信號煽動線程切換是一個相當加載。你可以緩衝rx字符,並減少信號量信號? –
親愛的詹姆斯我知道這是更好,但我認爲這個演示案例的FreeRTOS仍然應該正常工作。 –
一個字符,一個調度運行,每43us :(什麼是putchar1()做什麼? –