c - PIC24H 中的高速 UART 中断导致 FreeRTOS 错误

标签 c multithreading stm32 mplab freertos

我已经在一些嵌入式项目中使用 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 的波特率速度工作。

运行几秒钟或几分钟后,程序崩溃并跳转到陷阱:

_AddressError

_StackError

我不知道怎么会出现这个问题。经过长时间的调查和测试,我认为问题发生在程序运行在中断服务例程 (ISR) 中或运行完时。看来我们需要几个 SAVE_CONTEXT()RESTORE_CONTEXT() 函数。但在 PIC24 端口上没有这样的端口。

请你给我一些关于这个问题的建议

谢谢大家!


我想我已经找到了我的问题。当 PIC24H 进入和退出中断服务程序时会出现问题,这里是 UART RX、TX、定时器中断。

目前我没有像这样使用 ISR:

void 属性((中断, 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 小时后仍然崩溃。这意味着我的方法是正确的,但仍然有问题。可能是我错过了上面代码的一些东西。

如果你们对这种情况有什么理想,请告诉我。

谢谢

最佳答案

我遇到了类似的问题。

你的 uart 中断的优先级是多少?

它不应高于 FreeRTOSConfig.h 中设置的 RTOS 内核中断优先级,后者的默认优先级为 1,而 PIC 中断的默认优先级为 3。

这似乎偶尔会导致崩溃。

对于 PIC,SAVE_CONTEXT() 和 RESTORE_CONTEXT() 不是必需的,因为编译器会处理它,至少如果您使用编译器函数声明并避免使用 _FASTISR 或隐藏。

关于c - PIC24H 中的高速 UART 中断导致 FreeRTOS 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19701246/

相关文章:

c - Project Euler #97 模幂运算不工作

c - 傅里叶级数系数​​ gnuplot

c - 如何检查一个字符串是否包含在另一个字符串中?

microcontroller - STM32L1 的直接内存访问 RX

stm32 - FreeRTOS STM32 集成

c - STM32 DMA传输错误

c - 通过字符串的结构引用

c# - 在 TPL 数据流循环中完成

multithreading - 当线程消耗大量CPU时,如何打印线程的执行堆栈?

java - 我必须关心 ThreadPoolExecutor 的关闭吗?