我正在构建一个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;
}
几点: -
是否需要任何建议或信息?
答案 0 :(得分:1)
有一个FreeRTOS支持论坛,链接到FreeRTOS主页http://www.FreeRTOS.org
问候。
答案 1 :(得分:1)
我认为理查德是对的。问题可能是您在此处发布的代码中不存在的问题。
您是否在正在等待队列的接收任务上调用任何形式的暂停?当你在一个被阻塞等待队列的Task上调用vTaskSuspend()时,被挂起的Task将被移动到pxSuspendedTaskList并且它将“忘记”它正在等待事件队列,因为xEventListItem的pvContainer在那里任务将设置为NULL。
您可能想要检查在等待队列时是否曾暂停您的接收任务。希望有所帮助。干杯!
答案 2 :(得分:1)
你的共享内存至少应该被声明为volatile:
volatile xQueueRegistryItem rxQueueStore[MAX_NUMBER_OF_RX_QUEUES] ;
volatile int numberOfQueuesRegistered ;
否则编译器可能会优化对这些的读取或写入,因为它没有不同的执行线程的概念(在ISR和主线程之间)。
我还记得一些PIC C运行时启动选项不应用静态数据的零初始化以便最小化启动时间,如果使用这样的启动,则应明确初始化{{1 }}。我建议在任何情况下这样做都是个好主意。
从您的代码中可以看出,ISR中的numberOfQueuesRegistered
与“远程模块”中的RxMessage
不相同;它们不应该被共享,因为这将允许ISR在接收线程处理它时可能修改数据。如果它们可以共享,那么首先就没有理由建立队列,因为共享内存和信号量就足够了。
作为旁注,从来没有必要将指针转换为 RxMessage
,并且通常应该避免这样做,因为它会阻止编译器发出错误如果你要传递指针以外的东西。 void*
的重点在于它可以接受任何指针类型。