我已经FreeRTOS
在一些嵌入式项目中使用了一年的时间,直到现在它工作得非常完美。目前我面临一个与使用高速中断FreeRTOS
移植到相关的难题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 以 230400 bps 的波特率工作。
运行几秒钟或几分钟后,程序崩溃并且程序跳转到 Traps:
_AddressError
或者
_StackError
我不知道这个问题怎么会发生。经过长时间的调查和测试,我认为问题发生在程序运行和运行中断服务例程(ISR)时。看来我们需要几个SAVE_CONTEXT()
&RESTORE_CONTEXT()
函数。但是在 PIC24 端口上没有这样的。
请你给我一些关于这个问题的建议
谢谢你们 !
我想我已经发现了我的问题。当 PIC24H 进入和退出中断服务程序时会引入问题,这里它们是 UART RX、TX、定时器中断。
目前我不使用这样的 ISR:
无效属性((中断,auto_psv))
我用汇编代码自己创建了一个机制,而不是它:
__U1RX中断:;将 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、定时器中断也是如此。
结果是我的程序运行更顺畅,时间更长 1 小时(仅在 1-5 分钟后程序崩溃)。但最后它在运行1-2小时后仍然崩溃。这意味着我的方法是正确的,但仍然有问题。可能是我错过了上面的代码。
如果大家对这种情况有任何理想,请告诉我。
谢谢