FreeRTOS:队列没有按预期工作

时间:2015-12-02 12:45:19

标签: queue freertos

我是FreeRTOS的新手。我编写了一个使用队列在任务之间传输数据的示例。然而,显示的结果是错误的。愿任何人帮我解决这个问题吗?

谢谢!

要显示的变量:

unsigned int temperatureRaw = 25;
unsigned int flowRateRaw = 30;
unsigned int carbonLevelRaw = 250;
unsigned int salinityLevelRaw = 75;

结构保持指向上述变量的指针:

struct RawData {
  unsigned int *temperatureRaw;
  unsigned int *flowRateRaw;
  unsigned int *carbonLevelRaw;
  unsigned int *salinityLevelRaw;
};
typedef struct RawData RawData;

任务'原型

static void vOLEDTask( void *pvParameters );
static void vTask1( void *pvParameters );
static void prvSetupHardware( void );

队列处理:

QueueHandle_t xOLEDQueue, xRawQueue;

主:

int main( void )
{
    prvSetupHardware();

    /* Create queues */
    xOLEDQueue = xQueueCreate( mainOLED_QUEUE_SIZE, sizeof( xOLEDMessage * ) );
    xRawQueue = xQueueCreate( 3, sizeof( RawData * ) );

    /* Check if queues are successfully created */
    if( ( xOLEDQueue != 0 ) && ( xRawQueue != 0 ) ) {
        // Declare variables
        RawData xRawData = { &temperatureRaw, &flowRateRaw, &carbonLevelRaw, &salinityLevelRaw };
        RawData *pxRawData = &xRawData;

        /* Start the tasks defined within this file/specific to this demo. */
        xTaskCreate( vOLEDTask, "OLED", mainOLED_TASK_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
        xTaskCreate( vTask1, "Task1", 1000, ( void * )pxRawData, 1, NULL );

        /* Start the scheduler. */
        vTaskStartScheduler();

    }

    return 0;
}

任务'定义:

void prvSetupHardware( void )
{
    /* If running on Rev A2 silicon, turn the LDO voltage up to 2.75V.  This is
    a workaround to allow the PLL to operate reliably. */
    if( DEVICE_IS_REVA2 )
    {
        SysCtlLDOSet( SYSCTL_LDO_2_75V );
    }

    /* Set the clocking to run from the PLL at 50 MHz */
    SysCtlClockSet( SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_8MHZ );
}
void vOLEDTask( void *pvParameters )
{
  RawData *pxRawData = NULL;
  unsigned long ulMaxY;
  static char cMessage[ mainMAX_MSG_LEN ];
  extern volatile unsigned long ulMaxJitter;
  const unsigned char *pucImage;

  /* Functions to access the OLED.  The one used depends on the dev kit
  being used. */
  void ( *vOLEDInit )( unsigned long ) = NULL;
  void ( *vOLEDStringDraw )( const char *, unsigned long, unsigned long, unsigned char ) = NULL;
  void ( *vOLEDImageDraw )( const unsigned char *, unsigned long, unsigned long, unsigned long, unsigned long ) = NULL;
  void ( *vOLEDClear )( void ) = NULL;

    /* Map the OLED access functions to the driver functions that are appropriate
    for the evaluation kit being used. */
    switch( HWREG( SYSCTL_DID1 ) & SYSCTL_DID1_PRTNO_MASK )
    {
        case SYSCTL_DID1_PRTNO_6965 :
        case SYSCTL_DID1_PRTNO_2965 :   vOLEDInit = OSRAM128x64x4Init;
                            vOLEDStringDraw = OSRAM128x64x4StringDraw;
                            vOLEDImageDraw = OSRAM128x64x4ImageDraw;
                            vOLEDClear = OSRAM128x64x4Clear;
                            ulMaxY = mainMAX_ROWS_64;
                            pucImage = pucBasicBitmap;
                            break;

        case SYSCTL_DID1_PRTNO_1968 :
        case SYSCTL_DID1_PRTNO_8962     :   vOLEDInit = RIT128x96x4Init;
                            vOLEDStringDraw = RIT128x96x4StringDraw;
                            vOLEDImageDraw = RIT128x96x4ImageDraw;
                            vOLEDClear = RIT128x96x4Clear;
                            ulMaxY = mainMAX_ROWS_96;
                            pucImage = pucBasicBitmap;
                            break;

        default             :   vOLEDInit = vFormike128x128x16Init;
                            vOLEDStringDraw = vFormike128x128x16StringDraw;
                            vOLEDImageDraw = vFormike128x128x16ImageDraw;
                            vOLEDClear = vFormike128x128x16Clear;
                            ulMaxY = mainMAX_ROWS_128;
                            pucImage = pucGrLibBitmap;
                            break;

    }

    /* Initialise the OLED and display a startup message. */
    vOLEDInit( ulSSI_FREQUENCY );

    for( ;; )
    {
        xQueueReceive( xRawQueue, ( void * )&pxRawData, portMAX_DELAY );

        /* Display the message. */
        sprintf( cMessage, "%s %u C", "Temperature", *(pxRawData->temperatureRaw) );
        vOLEDStringDraw( cMessage, 0, 10, mainFULL_SCALE );

        sprintf( cMessage, "%s %u LPS", "Flow Rate", *(pxRawData->flowRateRaw) );
        vOLEDStringDraw( cMessage, 0, 20, mainFULL_SCALE );

        sprintf( cMessage, "%s %u ppm", "Carbon Level", *(pxRawData->carbonLevelRaw) );
        vOLEDStringDraw( cMessage, 0, 30, mainFULL_SCALE );

        sprintf( cMessage, "%s %u ppt", "Salinity Level", *(pxRawData->salinityLevelRaw) );
        vOLEDStringDraw( cMessage, 0, 40, mainFULL_SCALE );
    }
}
/*-----------------------------------------------------------*/

static void vTask1( void *pvParameters )
{
  RawData *pxRawData = ( RawData * )pvParameters;

  for( ;; ) {
    xQueueSend( xRawQueue, ( void * )&pxRawData, portMAX_DELAY );
    vTaskDelay( 1000/portTICK_RATE_MS );
  }
}

1 个答案:

答案 0 :(得分:0)

我还没有研究过所有的代码,但我看到的第一个问题是你将pxRawData作为参数传递给一个任务,pxRawData是一个指向xRawData的指针,但是xRawData有一个非常窄的块作用域,而堆栈就是声明on与任务使用的堆栈不同,因此当任务开始运行时,指向的变量将不存在 - 或者如果它确实存在则运气好,并且存在被覆盖的风险(取决于正在使用FreeRTOS port

另外,考虑创建xRawQueue来保存指向RawData的指针,但我认为你在vTask1中对xQueueSend的调用是传递一个指针的地址,所以它将指向一个指向RawData的指针排队,而不是指向RawData的指针。虽然这可能并不重要,因为它也被接收到指针指针,然后就这样访问。