1899_野火FreeRTOS教程阅读笔记_任务创建

1899_野火FreeRTOS教程阅读笔记_任务创建

全部学习汇总: g_FreeRTOS: FreeRTOS学习笔记 (gitee.com)

关于这部分,从一般前后台程序到RTOS的任务描述了很多。但是我觉得这本书的这部分描述没有描述到关键的信息点。其实,RTOS存在的一个主要的目的就是让各个Task从Task自己的层面能够有一种感觉:Task自己独占了整个CPU。而Task本身是没法独占全部CPU的,我们多个Task都需要运行。这样,就需要从软件的层面来“模拟”的形式让Task能够感受到自己似乎独占了整个CPU一样。而堆栈空间的设计,其实就是为了实现这一点。

这个是一个精简的任务控制块的数据结构,其中比较关键的信息是堆栈信息以及任务节点。其中,任务节点会关联其他的用户代码。还剩下一个任务名字,这个对于RTOS的实现来说并不是那么重要。

书中的例子采用了静态创建任务的方式,这个其实我在自己使用这个OS的时候没用过,我创建任务的时候都用的动态的形式。放一个之前的使用方式代码如下:

xTaskCreate(prvPrintTaskA, "TaskA", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_RECEIVE_TASK_PRIORITY, NULL);
    xTaskCreate(prvPrintTaskB, "TaskB", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL);

这个是动态创建任务时候的接口函数原型。两种方式的差异在于,现在教程中的部分是没有优先级处理的。另外就是静态的方式需要多一部分存储的处理,这个主要是因为静态不会再以内存申请分配的方式给任务分配内存,因此需要用户自己做这个存储的分派。至于句柄的处理,通过指针还是返回值的形式处理其实都差不多。但是,目前的句柄也只能看得出来是一个系统堆栈空间中的一个临时变量数值。而这个数值,应该会在进一步的初始化中进行修改。

要进一步了解这部分功能,得借助以SICP提到的黑盒抽象。需要知道,prvInitialiseNewTask()接口会完成实际的任务创建的工作,而这个创建接口会同时给出是否创建成功的一个提示。而这个接口用的句柄处理形式,其实是跟我之前使用的动态创建是类似的。

static void prvInitialiseNewTask(TaskFunction_t pxTaskCode,         /* 任务入口 */
                                 const char *const pcName,          /* 任务名称,字符串形式 */
                                 const uint32_t ulStackDepth,       /* 任务栈大小,单位为字 */
                                 void *const pvParameters,          /* 任务形参 */
                                 TaskHandle_t *const pxCreatedTask, /* 任务句柄 */
                                 TCB_t *pxNewTCB)                   /* 任务控制块指针 */{
    StackType_t *pxTopOfStack;
    UBaseType_t x;    /* 获取栈顶地址 */
    pxTopOfStack = pxNewTCB->pxStack + (ulStackDepth - (uint32_t)1);
    /* 向下做8字节对齐 */
    pxTopOfStack = (StackType_t *)(((uint32_t)pxTopOfStack) & (~((uint32_t)0x0007)));    /* 将任务的名字存储在TCB中 */
    for (x = (UBaseType_t)0; x < (UBaseType_t)configMAX_TASK_NAME_LEN; x++)
    {
        pxNewTCB->pcTaskName[x] = pcName[x];        if (pcName[x] == 0x00)
        {
            break;
        }
    }
    /* 任务名字的长度不能超过configMAX_TASK_NAME_LEN */
    pxNewTCB->pcTaskName[configMAX_TASK_NAME_LEN - 1] = '\0';    /* 初始化TCB中的xStateListItem节点 */
    vListInitialiseItem(&(pxNewTCB->xStateListItem));
    /* 设置xStateListItem节点的拥有者 */
    listSET_LIST_ITEM_OWNER(&(pxNewTCB->xStateListItem), pxNewTCB);    /* 初始化任务栈 */
    pxNewTCB->pxTopOfStack = pxPortInitialiseStack(pxTopOfStack, pxTaskCode, pvParameters);    /* 让任务句柄指向任务控制块 */
    if ((void *)pxCreatedTask != NULL)
    {
        *pxCreatedTask = (TaskHandle_t)pxNewTCB;
    }
}

上面是这个新任务初始化接口prvInitialiseNewTask()的实现。既然,处理的主要元素信息是堆栈以及任务控制块。那么具体的操作是做了什么呢?

先看堆栈。堆栈在这个接口中其实主要的处理是做了一个对齐的处理,对齐处理的操作是:根据静态任务创建接口xTaskCreateStatic()中传入的静态创建所分配的存储buffer所指向的内存做一个对齐的处理。而这个buffer的信息,在上一层的接口中已经完成了与TCB的信息绑定。这个对齐的要求主要是MCU的架构决定的,这里是按照8个字节来对齐,主要就是考虑了浮点运算时候的一个对齐。关于这个原因,我之前的确是没有弄清楚,还是从这个教材中学来的。这个对齐,进一步划定了这个任务堆栈所用的RAM范围。至于下一步的堆栈如何处理,再一步采用黑盒抽象。

任务控制块的处理,是把任务控制块中绑定的链表节点信息进行初始化,之后设置链表元素节点的处理对象绑定关系。即把TCB的信息绑定到这个链表节点上。不过,到此为止看得出来,暂时这个节点还是没有形成链表关系。因为少了插入的操作。

关于句柄的处理,可以看得出来这个句柄最终被处理成了指向TCB的指针的数值,也可以理解为是TCB的地址数值。

这样,如果要理解任务的创建,我们就还需要进一步分析前面黑盒抽象接口:堆栈的初始化处理接口pxPortInitialiseStack()

StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters)
{
    /* 异常发生时,自动加载到CPU寄存器的内容 */
    pxTopOfStack--;
    *pxTopOfStack = portINITIAL_XPSR; /* xPSR的bit24必须置1 */
    pxTopOfStack--;
    *pxTopOfStack = ((StackType_t)pxCode) & portSTART_ADDRESS_MASK; /* PC,即任务入口函数 */
    pxTopOfStack--;
    *pxTopOfStack = (StackType_t)prvTaskExitError; /* LR,函数返回地址 */
    pxTopOfStack -= 5;                             /* R12, R3, R2 and R1 默认初始化为0 */
    *pxTopOfStack = (StackType_t)pvParameters;     /* R0,任务形参 */    /* 异常发生时,手动加载到CPU寄存器的内容 */
    pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4默认初始化为0 */    /* 返回栈顶指针,此时pxTopOfStack指向空闲栈 */
    return pxTopOfStack;
}

首先要理解这个栈的处理方式,栈的增长是从上到下的,因此上面的地址会是一个递减的处理过程。

至于堆栈中存储了什么内容,这里有一个具体的说明。为什么这么安排,之前的经验是直接看ARM相关内核手册中的编程模型。这样,这段处理把指针挪到了这一堆寄存器镜像的最后面,也就是图中空闲堆栈的最上面。该信息记录在任务控制块中,后续在任务执行的时候使用。

至此为止,整个操作其实还只是准备了数据结构的信息。暂时,相应的TCB还没有任何与链表产生关联的动作。而任务调度其实是基于链表的,因此到此还看不出任何调度可能出现的痕迹。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2777962.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL篇----第八篇

系列文章目录 文章目录 系列文章目录前言一、存储过程优化思路二、触发器(一段能自动执行的程序)三、数据库并发策略四、MySQL 中有哪几种锁?五、MySQL 中有哪些不同的表格?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳…

创建自己的系统创富法则,做个轻松赚钱的甩手掌柜

一、教程描述 本套系统创富教程&#xff0c;大小744.80M&#xff0c;共有28个文件。 二、教程目录 01.走遍全球四十多个国家&#xff0c;我才发现赚钱的本质如此雷同.mp4 02.靠工资技术赚钱太慢&#xff0c;想赚到自己的第一个一百万的方法是&#xff1f;.mp4 03.不服暴发…

CSP-202112-2-序列查询新解

CSP-202112-2-序列查询新解 【70分思路】 【暴力枚举】按照题目思路遍历一遍f(x)和g(x)&#xff0c;计算error(A)&#xff0c;时间复杂度为O(N)&#xff0c;时间超限。 #include <iostream> using namespace std; int main() {long long n, N, sum 0;cin >> n …

【c++基础】骑士的金币(coin)(NOIP2015)

说明 国王将金币作为奖励&#xff0c;发放给忠诚的骑士。第一天&#xff0c;骑士收到一枚金币&#xff1b;之后两天&#xff08;第二天和第三天&#xff09;里&#xff0c;每天收到两枚金币&#xff1b;之后三天&#xff08;第四、五、六天&#xff09;里&#xff0c;每天收到…

微软 CMU - Tag-LLM:将通用大语言模型改用于专业领域

文章目录 一、前言二、主要内容三、总结 &#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 一、前言 论文地址&#xff1a;https://arxiv.org/abs/2402.05140 Github 地址&#xff1a;https://github.com/sjunhongshen/Tag-LLM 大语言模型&#xff08…

ChatGPT高效提问—prompt常见用法

ChatGPT高效提问—prompt常见用法 1.1 角色扮演 ​ prompt最为常见的用法是ChatGPT进行角色扮演。通常我们在和ChatGPT对话时&#xff0c;最常用的方式是一问一答&#xff0c;把ChatGPT当作一个单纯的“陪聊者”。而当我们通过prompt为ChatGPT赋予角色属性后&#xff0c;即使…

SpringIOC之support模块PropertySourcesPlaceholderConfigurer

博主介绍&#xff1a;✌全网粉丝5W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

LeetCode Python - 6.Z字形变换

文章目录 题目答案运行结果 题目 将一个给定字符串 s 根据给定的行数 numRows &#xff0c;以从上往下、从左到右进行 Z 字形排列。 比如输入字符串为 “PAYPALISHIRING” 行数为 3 时&#xff0c;排列如下&#xff1a; P A H N A P L S I I G Y I R 之后&#xff0c;你的输…

STM32 FSMC (Flexible static memory controller) 灵活静态内存控制器介绍

文章目录 1. 介绍FSMC2. FSMC特点3. Block示意图4. AHB接口4.1 Supported memories and transactionsGeneral transaction rulesConfiguration registers 5. 外部设备地址映射5.1 NOR/PSRAM地址映射将NOR Flash/PSRAM的支持进行封装 5.2 NAND/PC Card地址映射 1. 介绍FSMC 说到…

【正在更新】从零开始认识语音识别:DNN-HMM混合系统语音识别(ASR)模型原理

摘要 | Abstract TO-BE-FILLED 前言 | Introduction 近期想深入了解HMM隐马尔可夫模型和DNN-HMM混合模型&#xff0c;但是尽管网络上有许多关于DNN-HMM的介绍&#xff0c;如李宏毅教授的《深度学习人类语言处理》[1]&#xff0c;一些博主的语音识别系列文章[2]&#xff0c;斯坦…

4核8g服务器能支持多少人访问?- 腾讯云

腾讯云轻量4核8G12M轻量应用服务器支持多少人同时在线&#xff1f;通用型-4核8G-180G-2000G&#xff0c;2000GB月流量&#xff0c;系统盘为180GB SSD盘&#xff0c;12M公网带宽&#xff0c;下载速度峰值为1536KB/s&#xff0c;即1.5M/秒&#xff0c;假设网站内页平均大小为60KB…

机器学习系列——(十八)K-means聚类

引言 在众多机器学习技术中&#xff0c;K-means聚类以其简洁高效著称&#xff0c;成为了数据分析师和算法工程师手中的利器。无论是在市场细分、社交网络分析&#xff0c;还是图像处理等领域&#xff0c;K-means都扮演着至关重要的角色。本文旨在深入解析K-means聚类的原理、实…

Sodinokibi(REvil)黑客组织发起大规模供应链攻击

前言 Sodinokibi勒索病毒黑客组织获取了远程管理解决方案提供商Kaseya基础设施的访问权限&#xff0c;并使用VSA软件的恶意升级执行程序在企业网络上部署Sodinokibi(REvil)勒索病毒&#xff0c;据报道该事件已经影响了全球数千家公司&#xff0c;相关受害者发布的信息&#xf…

WWW 2024 | 时间序列(Time Series)和时空数据(Spatial-Temporal)论文总结

WWW 2024已经放榜&#xff0c;本次会议共提交了2008篇文章&#xff0c;research tracks共录用约400多篇论文&#xff0c;录用率为20.2%。本次会议将于2024年5月13日-17日在新加坡举办。 本文总结了WWW 2024有关时间序列&#xff08;Time Series&#xff09;和时空数据&#xf…

编译环境搭建及基础实验

1.VS code安装 Linux 版本安装 把资料盘里的安装包.deb拷贝到Ubuntu中&#xff0c; 使用如下命令安装&#xff1a; 软件图标都在目录/usr/share/applications 中&#xff0c;如图路径 复制到桌面中 Visual Studio Code 插件的安装 我们需要按照的插件有下面几个&#xff1a;…

【后端高频面试题--Mybatis篇】

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;后端高频面试题 &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; 后端高频面试题--Mybatis篇 什么是Mybatis&#xff1f;Mybatis的优缺点&#xff1f;Mybatis的特点…

Netty源码系列 之 HashedWheelTimer源码

Netty优化方案 之前总结NioEventLoop以及其他内容时&#xff0c;已经总结了Netty许多优化的设计方案。 1.Selector的优化 (1) 为epoll空转问题提供了解决思路&#xff0c;虽然并没有从根本上解决epoll空转问题&#xff0c;但是使用一个计数器的方式可以减少空转所带来的性能…

BestEdrOfTheMarket:一个针对AVEDR绕过的训练学习环境

关于BestEdrOfTheMarket BestEdrOfTheMarket是一个针对AV/EDR绕过的训练学习环境&#xff0c;广大研究人员和信息安全爱好者可以使用该项目研究和学习跟AV和EDR绕过相关的技术知识。 支持绕过的防御技术 1、多层API钩子&#xff1b; 2、SSH钩子&#xff1b; 3、IAT钩子&#x…

【MySQL】-12 MySQL索引(上篇MySQL索引类型前置-1)

MySQL索引 索引1 索引基础2 索引与优化1 选择索引的数据类型1.1 选择标识符 2 索引入门2.1 索引的类型2.1.1 B-Tree索引2.1.2 Hash索引2.1.3 空间(R-Tree)索引2.1.4 全文(Full-text)索引 索引的优点&#xff1a;索引是最好的解决方案吗&#xff1f; 索引 索引&#xff08;在MYS…

fast.ai 深度学习笔记(五)

深度学习 2&#xff1a;第 2 部分第 10 课 原文&#xff1a;medium.com/hiromi_suenaga/deep-learning-2-part-2-lesson-10-422d87c3340c 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 来自 fast.ai 课程的个人笔记。随着我继续复习课程以“真正”理解它&#xff0c;…