微型操作系统内核源码详解系列五(3):cm3下调度的开启

系列一:微型操作系统内核源码详解系列一:rtos内核源码概论篇(以freertos为例)-CSDN博客

系列二:微型操作系统内核源码详解系列二:数据结构和对象篇(以freertos为例)-CSDN博客

系列三:微型操作系统内核源码详解系列三(0):空间存储及内存管理篇(前置篇)-CSDN博客

                微型操作系统内核源码详解系列三(1):任务及切换篇(任务函数定义)-CSDN博客

                微型操作系统内核源码详解系列三(2):任务及切换篇(任务函数定义)-CSDN博客

                微型操作系统内核源码详解系列三(3):任务及切换篇(任务函数定义)-CSDN博客

                微型操作系统内核源码详解系列三(4):arm架构篇-CSDN博客

                微型操作系统内核源码详解系列三(5):进程与线程-CSDN博客

系列四:

 ​​​​​微型操作系统内核源码详解系列四(1):操作系统调度算法(linux0.11版本内核)-CSDN博客

微型操作系统内核源码详解系列四(2):操作系统调度算法(rt-thread内核)-CSDN博客

微型操作系统内核源码详解系列四(3):操作系统调度算法(FreeRTOS内核篇上)-CSDN博客

微型操作系统内核源码详解系列四(4):操作系统调度算法(FreeRTOS内核篇下)-CSDN博客

系列五:

微型操作系统内核源码详解系列五(1):arm cortex m3架构-CSDN博客

微型操作系统内核源码详解系列五(2):cm3下栈的初始化-CSDN博客

微型操作系统内核源码详解系列五(3):cm3下调度的开启-CSDN博客

 

上一篇文章,我们已经完成了栈的初始化,接下来笔者将会讲解调度器是如何配置并且开启第一个任务的。

在此之前,让我们重新看看官方的指导:

2f0a51283a3943f2b647ea25afd1c2f0.png

 

PSP和MSP分别是cm3下的两个堆栈指针,任何情况下只能使用其中一个。

 

笔者在系列五的博客截取了很多张cm3手册中的信息,这些都是至关重要的的信息,是指导如何写出一个月FreeRTOS的蓝图,请读者一定要把这些信息认真看完。

如果读者阅读到某一篇博客时感觉一点都看不懂了,那么笔者推荐把所在系列从头到尾认认真真看一遍,或者把全系列看一遍,因为笔者描述思路时比较零散,你可能要看到后面才能看懂前面的东西。如果发现实在是看不懂,大可不必纠结,可以选择搁置一段时间再来重新阅读。

通过上文,大概可以知道:在cm3下的双堆栈中,特权级别的代码会使用MSP,用户级别的代码会使用PSP。

 

e2156bef0c564eb09e4b5e93318096d7.png

这就是任务的轮转调度中断部分,任务的切换主要是由systick中断和PendSV中断完成。

有读者可能好奇,既然调度器的职责是完成上一个认为与下一个任务的切换,也就是说我们只需要在PendSV中断里面保存上一个任务的状态,再加载下一个任务的状态就行了,那么第一个任务从哪里来呢?

为了开启第一个任务,我们使用SVC调用,SVC调用是特权级的中断,毫无疑问更安全。

SVC系统调用主要职责就是开启os下的第一个任务。

但是调用SVC中断前需要进行配置:


BaseType_t xPortStartScheduler( void )
{#if( configASSERT_DEFINED == 1 ){volatile uint32_t ulOriginalPriority;volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );volatile uint8_t ucMaxPriorityValue;/* Determine the maximum priority from which ISR safe FreeRTOS APIfunctions can be called.  ISR safe functions are those that end in"FromISR".  FreeRTOS maintains separate thread and ISR API functions toensure interrupt entry is as fast and simple as possible.Save the interrupt priority value that is about to be clobbered. */ulOriginalPriority = *pucFirstUserPriorityRegister;/* Determine the number of priority bits available.  First write to allpossible bits. */*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;/* Read the value back to see how many bits stuck. */ucMaxPriorityValue = *pucFirstUserPriorityRegister;/* The kernel interrupt priority should be set to the lowestpriority. */configASSERT( ucMaxPriorityValue == ( configKERNEL_INTERRUPT_PRIORITY & ucMaxPriorityValue ) );/* Use the same mask on the maximum system call priority. */ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;/* Calculate the maximum acceptable priority group value for the numberof bits read back. */ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ){ulMaxPRIGROUPValue--;ucMaxPriorityValue <<= ( uint8_t ) 0x01;}/* Shift the priority group value back to its position within the AIRCRregister. */ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;/* Restore the clobbered interrupt priority register to its originalvalue. */*pucFirstUserPriorityRegister = ulOriginalPriority;}#endif /* conifgASSERT_DEFINED *//* Make PendSV and SysTick the lowest priority interrupts. */portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;/* Start the timer that generates the tick ISR.  Interrupts are disabledhere already. */vPortSetupTimerInterrupt();/* Initialise the critical nesting count ready for the first task. */uxCriticalNesting = 0;/* Ensure the VFP is enabled - it should be anyway. */prvEnableVFP();/* Lazy save always. */*( portFPCCR ) |= portASPEN_AND_LSPEN_BITS;/* Start the first task. */prvStartFirstTask();/* Should not get here! */return 0;
}

上面的函数,宏定义里面的configASSERT_DEFINED是断言,用来调试,让我们关注这些关键部分:

f0499a1440cd4bf29233efe0ef513e6f.png

解释一下,这段代码的作用是:配置pendsv和systck中断的优先级为最低(防止打断其他中断任务),然后设置systck定时器产生ISR(中断服务程序),就是设置SysTick定时器以生成系统tick中断。uxCriticalNesting用来记录进入临界区的次数,prvEnableVFP作用是支持浮点数运算,下一行代码的作用是设置浮点上下文寄存器以启用惰性保存机制,之后就是开启第一个任务的入口函数。

顺便一提,不能使用systick中断进行任务上下文切换的原因是:systick响应会抢占中断,但是OS不允许中断过程中执行上下文切换。

下面这个带firsttask命名的函数的作用还不是开启第一个任务,它的作用是产生SVC调用,SVC调用里面的函数才会把第一个任务的状态加载到CPU,这才是开启第一个任务。

66280367acad447a879096b4af6cccb9.png

 

ldr这三行代码的作用是--找到主栈的栈顶指针:

dad212f16eed4893b3dd528c4932d925.png

关于它是如何找到栈顶指针的,可以参考下图:

 

bea8a5cc452a4a13b6c2f2d1c5562cec.png

简单来说就是,先找到向量表偏移量寄存器,再找到向量表,向量表记录了msp的初始值:

4580158378ca490c85885ea6611b2840.png

svc下是特权模式运行,所以使用msp作为堆栈指针。这段代码将栈顶指针的值存储到msp,现在msp就指向栈顶指针了:

a6ac30ab11aa417f9d5c1e0ae105222f.png

之后的四行代码就是开启全局中断和异常:

6863c6aba6234f609e6cbef277a3cb7d.png

毫无疑问,这里就是开启svc中断响应了,nop指令表示延时,在计算机体系架构中,很多指令并不能持续执行,可能需要延时,如果读者学过流水线这些可能会知道nop的重要性:

20ce8bedb183481399b191c4781b91c7.png

到这里,SVC调用将会被响应,我们将会迎来arm架构下最精彩的部分:任务的开启与切换。

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何使用nginx部署https网站(亲测可行)

公司本来有网站sqlynx.com是http运行的&#xff0c;但因为产品出海&#xff0c;基本上都要求使用https&#xff0c;但又需要兼容已有的http服务&#xff0c;所以我自己尝试做了一次https的部署&#xff0c;目前是正常可用的。 目录 步骤 1&#xff1a;安装 Nginx 步骤 2&…

数据仓库的实际应用示例-广告投放平台为例

数据仓库的数据分层通常包括以下几层&#xff1a; ODS层&#xff1a;存放原始数据&#xff0c;如日志数据和结构化数据。DWD层&#xff1a;进行数据清洗、脱敏、维度退化和格式转换。DWS层&#xff1a;用于宽表聚合值和主题加工。ADS层&#xff1a;面向业务定制的应用数据层。…

node版本过高出现ERR_OSSL_EVP_UNSUPPORTED错误

错误原因&#xff1a; 新版本的nodejs使用的openssl和旧版本不同&#xff0c;导致出错 解决方法&#xff1a; 1.将node版本重新换回16.x 2 windows 下 在package.json文件下添加set NODE_OPTIONS--openssl-legacy-provider && "scripts": {"dev"…

Linux开发讲课8--- linux的5种IO模型

一、这里IO是什么 操作系统为了保护自己&#xff0c;设计了用户态、内核态两个状态。应用程序一般工作在用户态&#xff0c;当调用一些底层操作的时候&#xff08;比如 IO 操作&#xff09;&#xff0c;就需要切换到内核态才可以进行 服务器从网络接收的大致流程如下&#xff1…

非常难找的AI衣服图片处理工具推荐,一键轻松AI编辑

在当今数字化时代&#xff0c;AI技术已经渗透到我们生活的方方面面。特别是在图片处理领域&#xff0c;AI的强大功能让很多原本繁琐复杂的操作变得简单易行。今天&#xff0c;我要为大家推荐一款好用的AI衣服图片处理工具——让你一键轻松完成AI编辑&#xff0c;快速实现专业效…

wordpress站群搭建3api代码生成和swagger使用

海鸥技术下午茶-wordpress站群搭建3api代码生成和swagger使用 目标:实现api编写和swagger使用 0.本次需要使用到的脚手架命令 生成 http server 代码 goctl api go -api all.api -dir ..生成swagger文档 goctl api plugin -plugin goctl-swagger"swagger -filename st…

变电站智能巡检机器人解决方案

我国拥有庞大的电网体系&#xff0c;变电站数量众多&#xff0c;且近年来快速增长。然而目前我国变电站巡检方式仍以人工为主&#xff0c;存在效率低下、监控不全面等问题。变电站通常是一个封闭的系统空间&#xff0c;设备种类繁多、占地面积广阔&#xff0c;这对巡检人员实时…

缓存雪崩(主从复制、哨兵模式(脑裂)、分片集群)

缓存雪崩&#xff1a; 在同一时段大量的缓存key同时失效或者Redis服务宕机&#xff0c;导致大量请求到达数据库&#xff0c;带来巨大压力。 方法一&#xff1a; 给不同key的TTL添加随机值&#xff0c;以此避免同一时间大量key失效。&#xff08;用于解决同一时间大量key过期&…

qt 如何获取磁盘信息、QStorageInfo

以往获取qt磁盘信息&#xff0c;笔者是通过一下API转换的 BOOL GetDiskFreeSpaceExW([in, optional] LPCWSTR lpDirectoryName,[out, optional] PULARGE_INTEGER lpFreeBytesAvailableToCaller,[out, optional] PULARGE_INTEGER lpTotalNumberOfBytes,[out, optional…

excel基本操作

excel 若要取消在数据表中进行的所有筛选 步骤操作&#xff1a; 单击“数据”选项卡。在“排序和筛选”组中&#xff0c;找到“清除”按钮。点击“清除”按钮。 图例&#xff1a; 将文本文件的数据导入到Excel工作表中进行数据处理 步骤&#xff1a; 在Excel中&#xff0c…

java之文件上传代码审计

1 文件上传漏洞审计 1.1 漏洞原理介绍 大部分文件上传漏洞的产生是因为Web应用程序未对文件的格式和进行严格过滤&#xff0c;导致用户可上传jsp、php等webshell代码文件&#xff0c;从而被利用。例如在 BBS发布图片 , 在个人网站发布ZIP压缩包, 在办公平台发布DOC文件等 , 只…

高阶图神经网络 (HOGNN) 的概念、分类和比较

图神经网络&#xff08;GNNs&#xff09;是一类强大的深度学习&#xff08;DL&#xff09;模型&#xff0c;用于对相互连接的图数据集进行分类和回归。它们已被用于研究人类互动、分析蛋白质结构、设计化合物、发现药物、识别入侵机器、模拟单词之间的关系、寻找有效的交通路线…

Vue70-路由的几个注意点

一、路由组件和一般组件 1-1、一般组件 1-2、路由组件 不用写组件标签。靠路由规则匹配出来&#xff0c;由路由器渲染出来的组件。 1-3、注意点1 一般组件和路由组件&#xff0c;一般放在不同的文件夹&#xff0c;便于管理。 一般组件放在components文件夹下。 1-4、注意点…

河南大学24计算机考研数据,有三个学院招收计算机相关专业,都是考的408!

河南大学&#xff08;Henan University&#xff09;&#xff0c;简称“河大”&#xff0c;是河南省人民政府与中华人民共和国教育部共建高校&#xff0c;国家“双一流”建设高校&#xff0c;入选国家“111计划”、中西部高校基础能力建设工程、卓越医生教育培养计划、卓越法律人…

怎么用二维码在线下载视频?视频用二维码下载的制作方法

怎么把视频转换成二维码之后还可以下载视频呢&#xff1f;现在使用二维码的方式来分享视频内容在很多行业和场景中都有应用&#xff0c;这种方式能够更加简单快捷的完成视频的传播分享&#xff0c;那么怎么让扫码者可以自由选择下载视频呢&#xff1f;下面来给大家分享扫码下载…

深入探索C++中的AVL树

引言 在数据结构和算法的世界里&#xff0c;平衡二叉搜索树&#xff08;Balanced Binary Search Tree, BST&#xff09;是一种非常重要的数据结构。AVL树&#xff08;Adelson-Velsky和Landis发明的树&#xff09;就是平衡二叉搜索树的一种&#xff0c;它通过自平衡来维护其性质…

zookeeper + kafka消息队列

zookeeper kafka 消息队列 一、消息队列简介 1、什么是消息队列 消息队列&#xff08;Message Queue&#xff09;是一种用于跨进程或分布式系统中传递消息的通信机制。消息队列在异步通信、系统解耦、负载均衡和容错方面具有重要作用。 &#xff08;1&#xff09;特性 异步…

c++ 里构造函数的形参与数据成员的同名问题

如题&#xff0c;这时&#xff0c;或许在 java 里&#xff0c;会报语法错误。但在 c vs2019 开了 c20语法规范。这不再是错误。这样的好处是解决了咱们的起变量名的麻烦&#xff1a;重名现在已不是错误&#xff0c;编译器可以解决了。测试如下&#xff1a; 我们看看 c 编译器是…

如何正确理解和评估品牌价值?

在当今这个品牌林立的商业世界里&#xff0c;我们常常听到企业家们满怀憧憬地谈论品牌梦想。 但究竟是什么驱使这些企业去打造一个品牌&#xff0c;到底是市场的激烈竞争&#xff0c;还是内心的情感寄托&#xff1f;亦或是社会发展的必然趋势&#xff0c;引领我们追求超越产品…

1969python房屋租赁管理系统mysql数据库Flask结构BootStrap布局计算机软件工程网页

一、源码特点 python Flask房屋租赁管理系统是一套完善的web设计系统mysql数据库 &#xff0c;对理解python编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 python flask 房屋租赁管理系统 开发环境pycharm mysql …