3

我正在构建一个 FreeRTOS 应用程序。我创建了一个模块,它从另一个模块注册一个 freeRTOS 队列句柄,当这个模块模块发生中断时,它会向所有注册的队列发送一条消息。但似乎我能够从队列中发送消息,但无法在另一个模块中接收它。

这是我的代码。

远程模块:-

  CanRxMsg RxMessage;
  can_rx0_queue = xQueueCreate( 10, sizeof(CanRxMsg) ); // can_rx0_queue is globally defined 
  // Register my queue with can module
  if (registerRxQueueWithCAN(can_rx0_queue) == -1)
  {
    TurnLedRed();
  }  

  while(1)
  {
        if(can_rx0_queue){
      while( xQueueReceive( can_rx0_queue, ( void * ) &RxMessage, portMAX_DELAY))
      {
}
.....

这是注册模块

#define MAX_NUMBER_OF_RX_QUEUES 2

//xQueueHandle rxQueueStore[MAX_NUMBER_OF_RX_QUEUES];

typedef struct QUEUE_REGISTRY_ITEM
{
//  signed char *pcQueueName;
  xQueueHandle xHandle;
} xQueueRegistryItem;

xQueueRegistryItem rxQueueStore[MAX_NUMBER_OF_RX_QUEUES];

int numberOfQueuesRegistered;

#define cError -1

#define cSuccess 0

void processInterrupt()
{
 for(int i=0; i < numberOfQueuesRegistered; i++)
  {
    if(xQueueSendFromISR(rxQueueStore[i].xHandle,(void *) &RxMessage,&tmp) != pdTRUE)
        TurnLedRed();
    if(tmp)resched_needed = pdTRUE;
  }

  portEND_SWITCHING_ISR(resched_needed);
}

int registerRxQueueWithCAN(xQueueHandle myQueue)
{
  if(numberOfQueuesRegistered == MAX_NUMBER_OF_RX_QUEUES)
  {
    // Over Flow of registerations
    TurnLedRed();
    return cError; 
  }else 
  {
    rxQueueStore[numberOfQueuesRegistered].xHandle = myQueue;
    numberOfQueuesRegistered++;
  }
  return cSuccess;
}

几点:-

  1. xQuehandle 的类型定义为“void *”
  2. 如果删除注册的东西,并且如果我通过外部获取指针,则代码可以直接使用 xQueueSendFromISR 中的队列指针。

需要任何建议或信息吗?

4

3 回答 3

1

我认为理查德是对的。问题可能不在您在此处发布的代码中。

您是否对正在等待队列的接收任务调用任何形式的暂停?当您在阻塞等待队列的任务上调用 vTaskSuspend() 时,暂停的任务将被移动到 pxSuspendedTaskList 并且它将“忘记”它正在等待事件队列,因为 xEventListItem 的 pvContainer 在任务将设置为 NULL。

您可能想检查您的接收任务是否在等待队列时被挂起。希望有帮助。干杯!

于 2011-04-30T18:02:17.293 回答
1

您的共享内存至少应该被声明为 volatile:

volatile xQueueRegistryItem rxQueueStore[MAX_NUMBER_OF_RX_QUEUES] ;
volatile int numberOfQueuesRegistered ;

否则编译器可能会优化对这些的读取或写入,因为它没有不同执行线程的概念(在 ISR 和主线程之间)。

我还记得一些 PIC C 运行时启动选项不应用静态数据的零初始化以最小化启动时间,如果您正在使用这样的启动,您应该明确地初始化numberOfQueuesRegistered. 我建议这样做无论如何都是一个好主意。

从您的代码中不清楚RxMessageISRRxMessage“远程模块”中的不同;它们不应该被共享,因为这将允许 ISR 在接收线程处理数据时潜在地修改数据。如果它们可以共享,那么一开始就没有理由拥有队列,因为共享内存和信号量就足够了。

作为旁注,永远不需要将指针转换为 void*,并且您通常应该避免这样做,因为如果您要传递的不是指针,它会阻止编译器发出错误。a 的全部意义void*在于它可以接受任何指针类型。

于 2011-05-02T18:51:16.043 回答
1

乍一看,我看不出有什么明显的错误。问题可能在您显示的代码之外,例如 can_rx0_queue 是如何声明的、中断是如何输入的、您使用的是哪个端口等。

有一个 FreeRTOS 支持论坛,链接自 FreeRTOS 主页http://www.FreeRTOS.org

问候。

于 2011-04-01T12:32:09.297 回答