gentleman 发表于 2024-3-11 11:01:57

FreeRTOS for STC32G12K128内核代码解读(三)队列(1)

本帖最后由 gentleman 于 2024-3-11 11:56 编辑

FreeRTOS for STC32G12K128内核代码解读
    第三章队列(1)                -Gentleman



这期先给大家介绍一下 FreeRTOS 中的队列,下期再读队列相关代码


1.1 全局变量的缺点
      通过前面的内容,我们了解了,在操作系统中,任务调度是过程比较复杂的。
一旦任务数量增多,我们很难判断出任务执行的顺序。
      而我们在任务与任务,或者中断之间,经常需要 数据的传递
      在裸机程序中,我们往往采用全局变量的方式传递数据。
      但在操作系统中,由于任务执行顺序的不确定,导致全局变量的值,可能被其他任务使用/修改。导致程序逻辑出现问题
       所以,RTOS 中提供了队列来解决这个问题
1.2 队列
      直接写一个例程 ,来带大家了解 队列
      
   1.2.1创建队列xQueueCreate()
               先定义一个队列 和一个对照用的全局变量

         
               在main中 创建队列 (函数内部下期在分析)
               
                xQueueCreate() 的两个参数一个是队列长度,一个是队列中一项的大小
               
         写几个任务
                  发送任务
      1.2.2发送到队列xQueueSend()      默认是插队尾
portTASK_FUNCTION( vTaskSend, pvParameters )

{
   
    UNUSED( pvParameters );
    while(1)
    {
      int value_loacl = 10;                     
      value_global = 10;                                    //全局变量
      if (queue != NULL)
      {            
            xQueueSend(queue, &value_loacl, 100);               //队列
      }
      vTaskDelay(50);
    }
    vTaskDelete(NULL);
}

          解释一下,这里定义一个局部变量 value_local =10
                   如果队列申请成功,就把 局部变量 value_local 送进队列
                  xQueueSend()   
             参数1队列
             参数2发送到队列内值的地址
             参数3如果队列满则阻塞的时间
                   给全局变量也赋值 对照用
         
         修改了全局变量的其他任务(模拟操作系统运行中,各种可能影响全局变量的情况):
         portTASK_FUNCTION( vTaskOther, pvParameters )

{
   
    UNUSED( pvParameters );
    while(1)
    {
      value_global = 20;                                     //全局变量

      vTaskDelay(10);
    }
    vTaskDelete(NULL);
}

         
       1.2.3队列接收xQueueReceive()      
                  接受任务:      
            portTASK_FUNCTION( vTaskRec, pvParameters )

{
   
    UNUSED( pvParameters );
    while(1)
    {
      int value_Rec;
      if (queue != NULL)
      {
            xQueueReceive(queue, &value_Rec, 20);
            
            printf("队列接收:%d\r\n", value_Rec);
            printf("全局变量:%d\r\n", value_global);

      }
      vTaskDelay(20);
    }
    vTaskDelete(NULL);
}

         
            接收队列中的数据
            xQueueReceive();
      参数1 队列;
      参数2 接受数据存放的地址;
      参数3队列空则阻塞的时间;
            打印队列接收的数据和全局变量的数据



      在main中建立任务
void main( void )

{
    /* 系统初始化 */
    vSystemInit();

    /* 创建任务 */
    queue = xQueueCreate( 100, sizeof( int ) );

    if (queue != NULL)
    {
      xTaskCreate( vTaskSend, "TaskSend", 100, NULL, 1, NULL );         //发送任务
      xTaskCreate( vTaskOther, "TaskOther", 100, NULL, 1, NULL );         //修改变量的其他任务
      xTaskCreate( vTaskRec, "TaskRec", 100, NULL, 2, NULL );             //接受任务
    }

    /* 启动任务调度器开始任务调度 */
    vTaskStartScheduler();

    /* 正常情况下不会运行到此处 */
    while (1);
}

       让接受任务的优先级高一点
1.3 串口打印信息
      
       看一下运行结果
      
          可以看到 队列接收的值 一直为10
       全局变量的值 由于其他任务的影响是10 或者20

gentleman 发表于 2024-3-11 11:40:45

本帖最后由 gentleman 于 2024-3-14 11:33 编辑

以后二楼就不放目录了,只放 上/下一期的链接(双向链表{:4_174:})

总目录在第一章第一期更新 (或者单独做个 目录的帖子)


上一期FreeRTOS for STC32G12K128内核代码解读(二)任务调度(下) - FreeRTOS/实时操作系统/文件系统/嵌入式系统软件,TFT-GUI/uGFX - 国芯论坛-STC全球32位8051爱好者互助交流社区 - STC全球32位8051爱好者互助交流社区 (stcaimcu.com)
下一期FreeRTOS for STC32G12K128内核代码解读(三)队列(2) - FreeRTOS/实时操作系统/文件系统/嵌入式系统软件,TFT-GUI/uGFX - 国芯论坛-STC全球32位8051爱好者互助交流社区 - STC全球32位8051爱好者互助交流社区 (stcaimcu.com)

gentleman 发表于 2024-3-11 11:41:01

页: [1]
查看完整版本: FreeRTOS for STC32G12K128内核代码解读(三)队列(1)