硬汉嵌入式论坛

 找回密码
 立即注册
查看: 4689|回复: 3
收起左侧

[FreeRTOS] FreeRTOS使用队列传递复合数据(结构体的问题)

[复制链接]

3

主题

5

回帖

14

积分

新手上路

积分
14
发表于 2018-9-9 18:35:17 | 显示全部楼层 |阅读模式
一、使用队列传递复合数据类型
主函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/*声明一个类型为xQueueHandle的变量,其用于保存队列句柄,以便三个任务都可以引用此队列*/
xQueueHandle xQueue;
/*定义队列传递的结构类型*/
typedef struct
{
  unsigned int ucValue;
  unsigned int ucSource;
}xData;
/*声明两个xData类型的变量,通过队列传递*/
static const xData xStructsToSend[2]=
{
  {100,300},/*被发送任务的实例1使用*/
  {200,400} /*被发送任务的实例2使用*/
};
static void AppTaskCreate (void)
{
        /*创建队列用于保存最多3个xData类型的数据单元*/
        xQueue = xQueueCreate( 3, sizeof( xData ) );
        if( xQueue != NULL )/*非空说明成功创建了队列*/
        {
          /*为写队列任务创建2个实例。
          任务的入口参数用于传递发送到队列中的数据。因为其中一个任务往队列中一直
          写入xStructsToSend[0],而另一个则往队列中写入xStructsToSend[1]。这两个
          任务的优先级都设为2,高于队列任务的优先级*/
          xTaskCreate( vSenderTask, "Sender1", 240, ( void * ) &( xStructsToSend[ 0 ] ), 2, NULL );
          xTaskCreate( vSenderTask, "Sender2", 240, ( void * ) &( xStructsToSend[ 1 ] ), 2, NULL );
          /*创建读队列任务。
            读队列任务优先级设为1,低于写队列任务的优先级*/
          xTaskCreate( vReceiverTask, "Receiver", 240, NULL, 1, NULL );
          /*启动调度器,创建的任务得到执行*/
          vTaskStartScheduler();
        }
        else
        {
          /*创建队列失败,这是理论上不可能发送的*/
          printf( "Queue not created.\n" );
         }
}

发送任务:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
static void vSenderTask( void *pvParameters )
{
  /*队列状态标志*/
  portBASE_TYPE xStatus;
  /*转换为以毫秒为单位的心跳周期*/
  const portTickType xTicksToWait = 100 / portTICK_RATE_MS;
  for( ;; )
  {
  /*第一个参数是要发送的队列
    第二个参数是将要发送的数据结构地址。这个地址是从任务入口参数中传入,所以直接
      使用pvParameters
    第三个参数是阻塞等待时间*/
    xStatus = xQueueSendToBack( xQueue, pvParameters, xTicksToWait );
    /*无法发送成功*/
    if( xStatus != pdPASS )
    {
        printf( "Could not send to the queue.\r\n" );
    }
    /*队列已满*/
    else if( xStatus == errQUEUE_FULL )
    {
        printf( "Queue is full.\r\n" );
    }
    /*发送成功*/
    else if( xStatus == pdPASS )
    {
        printf(" sent\r\n");
    }
    /*立即切出,不用等待阻塞时间耗尽,转而立即执行发送任务的实例2*/
    taskYIELD();
   }
}

接收任务:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
static void vReceiverTask( void *pvParameters )
{
  /*声明结构体变量以保存从队列中读出的数据单元*/
  xData xReceivedStructure;
  /*队列的状态标志*/
  portBASE_TYPE xStatus;
  for( ;; )
  {
  /*读队列任务的优先级最低,所以其只可能在写对垒任务阻塞时得到执行。而写队列任务
    只会在队列写满时才会进入阻塞态,所以读队列任务执行时队列肯定已满。所以队列中
    数据单元的个数应当等于队列深度-本例中队列深度为3*/
    if( uxQueueMessagesWaiting( xQueue ) != 3 ){
        printf( "Queue should have been full!\n" );/*这是不可能发生的*/
    }
    /*第一个参数是需要读取的队列
      第二个参数是存放接收数据的缓存空间-这里简单的采用一个具有足够空间大小的变
        量地址
      第三个参数是阻塞超时时间-本例不需要指定超时时间,因为读队列任务只会在队列
        满时才会得到执行*/
    xStatus = xQueueReceive( xQueue, &xReceivedStructure, 0 );
    if( xStatus == pdPASS )
    {
    /*数据成功读出,打印输出数值及数据来源*/
        if( xReceivedStructure.ucSource ==300)
        {
            printf( "From Sender 1 = %d\r\n", xReceivedStructure.ucValue );
        }
        else
        {
            printf( "From Sender 2 = %d\r\n", xReceivedStructure.ucValue );
        }
    }
    else
    {
      /*没有读到任何数据。这是理论上不可能发生的,因为此任务只有在队列满时才会得
      到执行*/
        printf( "Could not receive from the queue.\r\n" );
    }
}

}

串口打印截图:

分析:略,同上一篇文章类似(但是这次结构体好像很有问题)
见下面几张截图:



现在还是不太明白为什么?(貌似好像是C99标准什么的问题,想问一下大家有没有什么好的解决方案)

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106978
QQ
发表于 2018-9-10 00:17:14 | 显示全部楼层

回帖奖励 +4 个金币

typedef struct
{
  unsigned char ucValue;
  unsigned char *ucSouce;
}xData;

const unsigned char A;
const unsigned char B;

static const xData C[2]=
{
  {100, (unsigned char *)&A},
  {100, (unsigned char *)&B}  
};
回复

使用道具 举报

3

主题

5

回帖

14

积分

新手上路

积分
14
 楼主| 发表于 2018-9-10 18:57:35 | 显示全部楼层
eric2013 发表于 2018-9-10 00:17
typedef struct
{
  unsigned char ucValue;

貌似还是错误的
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106978
QQ
发表于 2018-9-11 02:36:24 | 显示全部楼层
QQ截图20180911025442.png

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-13 02:02 , Processed in 0.157998 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表