2015-12-02 189 views
0

我是FreeRTOS的新手。我写了一个使用队列在任务之间传输数据的例子。尽管如此,结果显示是错误的。任何人都可以帮我解决这个问题吗?FreeRTOS:队列没有按预期工作

谢谢!要被显示

变量:

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

STRUCT保持指针的上述变量:

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); 
    } 
} 

回答

0

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

此外,考虑到xRawQueue创建持有指针RAWDATA,但我觉得你的电话到vTask1 xQueueSend是传递一个指针的地址,所以它是排队的指针的指针RAWDATA,而不是一个指针原始数据。虽然这可能并不重要,因为它也被接收到一个指向指针的指针中,然后像这样访问。

+0

感谢您的评论! 我将主范围之外的xRawData和pxRawData声明作为全局变量移动,我的代码正常工作。 此外,根据xQueueSend()的定义,第二个参数是指向要放置在队列中的项目的指针。因此,这就是为什么我传递一个指向RawData的指针的原因,因为xRawQueue持有指向RawData的指针。 –