我是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 );
}
}
答案 0 :(得分:0)
我还没有研究过所有的代码,但我看到的第一个问题是你将pxRawData作为参数传递给一个任务,pxRawData是一个指向xRawData的指针,但是xRawData有一个非常窄的块作用域,而堆栈就是声明on与任务使用的堆栈不同,因此当任务开始运行时,指向的变量将不存在 - 或者如果它确实存在则运气好,并且存在被覆盖的风险(取决于正在使用FreeRTOS port。
另外,考虑创建xRawQueue来保存指向RawData的指针,但我认为你在vTask1中对xQueueSend的调用是传递一个指针的地址,所以它将指向一个指向RawData的指针排队,而不是指向RawData的指针。虽然这可能并不重要,因为它也被接收到指针指针,然后就这样访问。