找回密码
 立即注册
查看: 705|回复: 2

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

[复制链接]
  • 打卡等级:以坛为家I
  • 打卡总天数:217
  • 最近打卡:2024-11-15 09:12:27

29

主题

722

回帖

2790

积分

荣誉版主

积分
2790
发表于 2024-3-11 11:01:57 | 显示全部楼层 |阅读模式
本帖最后由 gentleman 于 2024-3-11 11:56 编辑

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



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


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

            截图202403111032069236.jpg
               在main中 创建队列 (函数内部下期在分析)
                截图202403111028355525.jpg
                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 串口打印信息
      
       看一下运行结果

       截图202403111053226445.jpg
          可以看到 队列接收的值 一直为10
       全局变量的值 由于其他任务的影响是  10 或者20

demo2.7z

1.92 MB, 下载次数: 83

回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:217
  • 最近打卡:2024-11-15 09:12:27

29

主题

722

回帖

2790

积分

荣誉版主

积分
2790
发表于 2024-3-11 11:40:45 | 显示全部楼层
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:217
  • 最近打卡:2024-11-15 09:12:27

29

主题

722

回帖

2790

积分

荣誉版主

积分
2790
发表于 2024-3-11 11:41:01 | 显示全部楼层
回复

使用道具 举报 送花

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

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-2 08:46 , Processed in 0.124074 second(s), 57 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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