I'm using kit De10-Nano which has successfully ported uC/OS-II as in the example on the Weston Embedded website. Currently, I'm having a problem with message queue API of the OS.
My program contains two tasks: producer task (priority 5) and consumer task (priority 4). My purpose is that the producer task would send the message to the consumer task via a message queue. In the first time I've tried, the producer task is slower than the consumer task (producer task is delayed for 100ms and consumer task is delayed for 10ms) and the message queu e works fine as every time producer task sends a message (using OSQPost), the consumer task receives it (using OSQPend). However, when I change the time slice for both task to make the consumer task runs slower than the producer task, I've expected that the consumer task can extract data from the message queue in the FIFO order. However, the data extracted by the consumer task is not in that order.
Here is my code:
/* Includes ------------------------------------------------------------------*/
/* Standard C/C++ Library Includes */
#include <stdio.h>
#include <stdint.h>
/* User Library Includes */
/* Altera's Library Includes */
/* uC/OS-II's Library Includes */
extern "C"
{
#include "includes.h"
}
/* End of Includes ------------------------------------------------------------------*/
/* Private defines ---------------------------------------------------------*/
#define PRODUCER_TASK_STK_SIZE (1024)
#define CONSUMER_TASK_STK_SIZE (1024)
#define PRODUCER_TASK_PRIO (5)
#define CONSUMER_TASK_PRIO (4)
#define MSG_QUEUE_SIZE (30)
/* USER CODE BEGIN PD */
static OS_STK ProducerTaskStk[PRODUCER_TASK_STK_SIZE];
static OS_STK ConsumerTaskStk[CONSUMER_TASK_STK_SIZE];
void* myMsgQueue[MSG_QUEUE_SIZE];
static OS_EVENT* msgQueueHandler;
static uint32_t myProducerBuffer = 0;
static uint32_t myConsumerBuffer = 0;
static uint8_t errorCode;
static OS_Q_DATA queue_data;
/* USER CODE END PD */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
static void ProducerTask (void *p_arg);
static void ConsumerTask (void *p_arg);
/* USER CODE END PFP */
static void ProducerTask (void *p_arg)
{
while(1)
{
++myProducerBuffer;
printf("Producer sent value: %d\n", myProducerBuffer);
if(OSQPost(msgQueueHandler, (void*)&myProducerBuffer) != OS_ERR_NONE)
{
printf("Producer sent failed\n");
}
else
{
OSQQuery(msgQueueHandler, &queue_data);
printf("Current queue size in producer: %d\n", queue_data.OSNMsgs);
}
OSTimeDlyHMSM(0u,0u,0u,10u);
}
}
static void ConsumerTask (void *p_arg)
{
uint32_t* pConsumerBuffer;
while(1)
{
pConsumerBuffer = (uint32_t*)OSQPend(msgQueueHandler, 0, &errorCode);
myConsumerBuffer = *pConsumerBuffer;
printf("Consumer get value: %d\n", myConsumerBuffer);
OSQQuery(msgQueueHandler, &queue_data);
printf("Current queue size in consumer: %d\n", queue_data.OSNMsgs);
OSTimeDlyHMSM(0u,0u,0u,100u);
}
}
int main()
{
OSInit();
msgQueueHandler = OSQCreate(&myMsgQueue[0],MSG_QUEUE_SIZE);
OSTaskCreateExt(ProducerTask, /* Create the producer task */
0,
&ProducerTaskStk[PRODUCER_TASK_STK_SIZE - 1u],
PRODUCER_TASK_PRIO,
PRODUCER_TASK_PRIO,
&ProducerTaskStk[0u],
PRODUCER_TASK_STK_SIZE,
0u,
(OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR));
OSTaskCreateExt(ConsumerTask, /* Create the consumer task */
0,
&ConsumerTaskStk[CONSUMER_TASK_STK_SIZE - 1u],
CONSUMER_TASK_PRIO,
CONSUMER_TASK_PRIO,
&ConsumerTaskStk[0u],
CONSUMER_TASK_STK_SIZE,
0u,
(OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR));
OSStart();
while(1); /* Should never get here. */
return -1;
}
And here is my result: enter image description here
At first, producer sends 1 and consumer receives 1. And then, the consumer is delayed for 100ms and producer sends message from 2 to 10 to the message queue during this time. The consumer then extracts from the message queue and get value of 10 instead of 2. So I'm assuming that the message queue is not in FIFO order. Is there anything I've done wrong ? If not, why the message queue does not behave as I've expected ?