找回密码
 立即注册
查看: 629|回复: 6

FreeRTOS for STC32G12K128内核代码解读(一)任务建立(上),后续文章见二楼的链接

[复制链接]
  • TA的每日心情
    奋斗
    前天 08:47
  • 签到天数: 142 天

    [LV.7]常住居民III

    29

    主题

    559

    回帖

    2116

    积分

    荣誉版主

    积分
    2116
    发表于 2024-2-28 11:38:18 | 显示全部楼层 |阅读模式
    FreeRTOS for STC32G12K128内核代码解读(一)任务建立(上)
    ===后续文章二楼的链接

    本篇核心内容
    截图202402290838544035.jpg


    源码工程为  官网下载的 FreeRTOS 库函数版本



    一 任务建立函数参数


              截图202402281106433531.jpg

          这就是今天的主角

          任务建立函数
          跳进去 函数定义


       BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,
                                const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
                                const configSTACK_DEPTH_TYPE usStackDepth,
                                void * const pvParameters,
                                UBaseType_t uxPriority,
                                TaskHandle_t * const pxCreatedTask )




           解释一下这些参数
           参数1pxTaskCode    任务函数名   
           参数2pcName        任务名字 (就是个字符串,别和参数1搞混)
           参数3usStackDepth堆) 栈深度
           参数4pvParameters  任务函数参数

           参数5uxPriority    任务优先级

           参数6pxCreatedTask 任务句柄(这个是传出来的,不是传进去的)

              截图202402281120034865.jpg
    二 TCB 任务控制块 结构
            函数内 建了一个TCB (任务控制块)  的指针
            我们跳转,查看这个数据结构的内容

             截图202402281121448681.jpg


           条件编译我们先跳过
           需要时再看

            解释一下这个数据结构的内容
           截图202402281125423648.jpg


           看不懂没关系,后面的代码会 给结构体赋值的
    三 TCB 申请(堆)栈空间
           回到 函数体
           截图202402281129298263.jpg


        pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );

         上面这行,给新的TCB 分配了一块空间
         如何分配的 有点长 暂时先不看 -属于内存管理的内容了
          继续阅读
         753 行 pxNewTCB->pxStack =  给TCB 的栈 分配了一块(堆)栈空间

             截图202402281134551908.jpg
    四 初始化新任务
          如果 (堆)栈申请成功了
          调用            prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL );
        初始化新任务,看到 这堆参数 基本能猜到 要给TCB 赋值了
           截图202402281319452316.jpg

         跳转到该函数
        876行             pxTopOfStack = pxNewTCB->pxStack;
        先配置一下(堆)栈顶,栈顶指向起始栈
          条件编译先跳过
          888行 开始     if( pcName != NULL )  判断一下名字是否为空
        非空就赋值给TCB的pcTaskName[]任务名字             pxNewTCB->pcTaskName[ x ] = pcName[ x ];


       

       938行     vListInitialiseItem( &( pxNewTCB->xStateListItem ) );
              vListInitialiseItem( &( pxNewTCB->xEventListItem ) );

          这两行初始化了 状态链表 和事件链表
          之前这两个链表没有展开
         现在展开看一下
           截图202402281350015741.jpg

         常见的双向链表
         前三个是 项值, 前项与后项指针
         pvOwner         链表持有者指针(TCB)
         pxContainer     项所在的链表指针(如果有)

          看看初始化函数
           截图202402281418145111.jpg


        pxItem->pxContainer = NULL;

         把pxContainer  项所在的链表指针设为空
       返回到  prvInitialiseNewTask()

           截图202402281422279650.jpg



              调查宏定义 发现这几行是给 链表项/持有者赋值
        #define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner )    ( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) )
        #define listSET_LIST_ITEM_VALUE( pxListItem, xValue )     ( ( pxListItem )->xItemValue = ( xValue ) )
          


        listSET_LIST_ITEM_OWNER( &( pxNewTCB->xStateListItem ), pxNewTCB );

        /* Event lists are always in priority order. */
        listSET_LIST_ITEM_VALUE( &( pxNewTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
        listSET_LIST_ITEM_OWNER( &( pxNewTCB->xEventListItem ), pxNewTCB );

       即:
        给两个链表的pvOwner 赋值为 pxNewTCB 我们刚刚建立的新TCB任务控制块
       给事件链表xEventListItem 的项值xItemValue 赋值为 uxPriority 优先级
       跳过中间的条件编译


       1052行 pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters );
       初始化 (堆)栈
      
    截图202402281433516456.jpg

        看第76行:

        ulAddress = ( uint32_t ) pxCode;
        *pxTopOfStack = ( StackType_t ) ( ulAddress >> 16 );    /* PC[23:16] */
        pxTopOfStack++;
        *pxTopOfStack = ( StackType_t ) ( ulAddress >> 8 );     /* PC[15:8] */
        pxTopOfStack++;
        *pxTopOfStack = ( StackType_t ) ( ulAddress );          /* PC[7:0] */

        把函数名(地址) 先存到(堆)栈
           c251地址总线是24位
           这里函数的地址 也是24位
           下面补充两个关于函数调用的基础知识 (知道的可以跳过)
              1.pc指针
              这里解释一下 pc指针 就是指向当前所运行代码  的地址
                                      我们调用函数        =》     将pc指针 指向被调函数的地址
                  下图是调用函数时PC 指针的值  与函数地址
                                截图202402281508214804.jpg

                   

             
                    2. 栈(保存现场)
                           大家都知道 cpu运行时离不开寄存器

                            截图202402281510368208.jpg
                           而调用函数时,这些寄存器的值怎么办
                           这些值要保存到内存中,这个内存空间叫栈

                         
                        
                      

          继续看代码
                  
    截图202402281524406391.jpg
                 PSW DPTR DR28~DR4 的(堆)栈空间初始化
                 继续
                  
    截图202402281526122931.jpg    
                 这几行把 函数的参数存起来了
                 将会占用DR0 这个四字节的寄存器
        return pxTopOfStack;

                 返回栈顶,该函数结束

          回到xTaskCreate()
    五 添加任务
            第805行
                prvAddNewTaskToReadyList( pxNewTCB );
         添加任务到就绪链表(数组)函数
         跳进去

                截图202402281533311348.jpg

          1077行        uxCurrentNumberOfTasks++;
          当前任务数+1
                pxCurrentTCB = pxNewTCB;
          如果新任务 不是空的  
          将新任务设置为 当前任务
                if( uxCurrentNumberOfTasks == ( UBaseType_t ) 1 )
          如果第一个任务
                    prvInitialiseTaskLists();
          初始化任务链表  
         跳进去

        for( uxPriority = ( UBaseType_t ) 0U; uxPriority < ( UBaseType_t ) configMAX_PRIORITIES; uxPriority++ )
        {
            vListInitialise( &( pxReadyTasksLists[ uxPriority ] ) );
        }

        vListInitialise( &xDelayedTaskList1 );
        vListInitialise( &xDelayedTaskList2 );
        vListInitialise( &xPendingReadyList );


    内容有点多  
    分两期吧
















    截图202402281332532635.jpg
    截图202402281524494934.jpg
    截图202402281530289853.jpg
    1 喜欢他/她就送朵鲜花吧,赠人玫瑰,手有余香!
    回复 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    前天 08:47
  • 签到天数: 142 天

    [LV.7]常住居民III

    29

    主题

    559

    回帖

    2116

    积分

    荣誉版主

    积分
    2116
     楼主| 发表于 2024-2-28 11:39:17 | 显示全部楼层
    本帖最后由 gentleman 于 2024-3-28 10:46 编辑

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

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

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

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

    9.队列3FreeRTOS for STC32G12K128内核代码解读(三)队列(3) - FreeRTOS/uCOS,GUI-uGFX/U8g2,文件系统/嵌入式系统/实时操作系统 - 国芯论坛-STC全球32位8051爱好者互助交流社区 - STC全球32位8051爱好者互助交流社区 (stcaimcu.com)
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    前天 08:47
  • 签到天数: 142 天

    [LV.7]常住居民III

    29

    主题

    559

    回帖

    2116

    积分

    荣誉版主

    积分
    2116
     楼主| 发表于 2024-2-28 17:05:05 | 显示全部楼层
    再占一层
    二楼改目录了
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    1 小时前
  • 签到天数: 47 天

    [LV.5]常住居民I

    15

    主题

    221

    回帖

    1163

    积分

    金牌会员

    积分
    1163
    发表于 2024-3-9 14:17:47 | 显示全部楼层
    学习中,感谢分享经验
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情

    3 小时前
  • 签到天数: 102 天

    [LV.6]常住居民II

    5

    主题

    61

    回帖

    499

    积分

    中级会员

    积分
    499
    发表于 2024-3-13 11:08:49 | 显示全部楼层
    请问这是什么编译器,不像KEIL啊
    711.jpg

    点评

    VSCODE VSCode 开发51单片机 简单教程(欢迎回帖分享优质插件/技巧) - SDCC, IAR C++ for STC8, GCC, VSCode,Linux, MacOS - 国芯论坛-STC全球32位8051爱好者互助交流社区 - STC全球32位8051爱好者互助交流社区  详情 回复 发表于 2024-3-13 11:46
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    前天 08:47
  • 签到天数: 142 天

    [LV.7]常住居民III

    29

    主题

    559

    回帖

    2116

    积分

    荣誉版主

    积分
    2116
     楼主| 发表于 2024-3-13 11:46:22 | 显示全部楼层
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情

    3 小时前
  • 签到天数: 102 天

    [LV.6]常住居民II

    5

    主题

    61

    回帖

    499

    积分

    中级会员

    积分
    499
    发表于 2024-3-13 19:44:17 | 显示全部楼层
    gentleman 发表于 2024-3-13 11:46
    VSCODE

    VSCode 开发51单片机 简单教程(欢迎回帖分享优质插件/技巧) - SDCC, IAR C++ for STC8, GCC, ...

    十分感谢
    回复 支持 反对 送花

    使用道具 举报

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

    本版积分规则

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

    GMT+8, 2024-5-2 12:22 , Processed in 0.112020 second(s), 60 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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