当前位置: 首页 > news >正文

织梦手机端网站字体重叠站长平台工具

织梦手机端网站字体重叠,站长平台工具,手机html网站开发工具,医疗做网站开启任务调度器 作用:用于启动任务调度器,任务调度器启动后, FreeRTOS 便会开始进行任务调度 该函数内部实现,如下: 1、创建空闲任务(优先级最低) 2、如果使能软件定时器,则创建定…

开启任务调度器

        作用:用于启动任务调度器,任务调度器启动后, FreeRTOS 便会开始进行任务调度  

该函数内部实现,如下:

        1、创建空闲任务(优先级最低)

        2、如果使能软件定时器,则创建定时器任务(优先级最高)

        3、关闭中断,防止调度器开启之前或过程中,受中断干扰,会在运行第一个任务时打开中断(在SVC中断中,通过设置basepri 为 0 来开启中断)

        4、初始化全局变量,并将任务调度器的运行标志设置为已运行

        5、初始化任务运行时间统计功能的时基定时器

        6、调用函数 xPortStartScheduler()完成启动任务调度器中与硬件架构相关的配置部分,以及启动第一个任务

      xPortStartScheduler()

        作用:该函数用于完成启动任务调度器中与硬件架构相关的配置部分,以及启动第一个任务

该函数内部实现,如下:

        1、检测用户在 FreeRTOSConfig.h 文件中对中断的相关配置是否有误

        2、配置 PendSV SysTick 的中断优先级为最低优先级

        3、调用函数 vPortSetupTimerInterrupt()配置 SysTick

        4、初始化临界区嵌套计数器为 0

        5、调用函数 prvEnableVFP()使能 FPU(M3中不支持FPU浮点单元)

        6、调用函数 prvStartFirstTask()启动第一个任务

        prvStartFirstTask()

        函数 prvStartFirstTask()用于初始化启动第一个任务前的环境,主要是重新设置 MSP 指针,并使能全局中断。

       1. 首先是使用了 PRESERVE8,进行 8 字节对齐,这是因为,栈在任何时候都是需要 4 字节对齐的,而在调用入口得 8 字节对齐,在进行 C 编程的时候,编译器会自动完成的对齐的操作,而对于汇编,就需要开发者手动进行对齐。

        2.获得 MSP 指针的初始值

ldr r0, =0xE000ED08    /* 0xE000ED08 为 VTOR 地址 */
ldr r0, [ r0 ]         /* 获取 VTOR 的值 */
ldr r0, [ r0 ]         /* 获取 MSP 的初始值 */

(1) 什么是 MSP 指针?

        程序在运行过程中需要一定的栈空间来保存局部变量等一些信息。当有信息保存到栈中时, MCU 会自动更新 SP 指针,使 SP 指针指向最后一个入栈的元素,那么程序就可以根据 SP 指针来从栈中存取信息。对于正点原子的 STM32F1、 STM32F4、 STM32F7 和 STM32H7 开发板上使用的 ARM Cortex-M 的 MCU 内核来说, ARM Cortex-M 提供了两个栈空间, 这两个栈空间的堆栈指针分别是 MSP(主堆栈指针) 和 PSP(进程堆栈指针)在 FreeRTOS 中 MSP 是给系统栈空间使用的,而 PSP 是给任务栈使用的,也就是说, FreeRTOS 任务的栈空间是通过 PSP 指向的,而在进入中断服务函数时,则是使用 MSP 指针。当使用不同的堆栈指针时, SP 会等于当前使用的堆栈指针。

        (2) 为什么是 0xE000ED08?

        0xE000ED08 是 VTOR(向量表偏移寄存器)的地址, VTOR 中保存了向量表的偏移地址。一般来说向量表是从其实地址 0x00000000 开始的,但是在有情况下,可能需要修改或重定向向量表的首地址,因此 ARM Corten-M 提供了 VTOR 对向量表进行从定向。而向量表是用来保存中断异常的入口函数地址,即栈顶地址的,并且向量表中的第一个字保存的就是栈底的地址,在 start_stm32xxxxxx.s 文件中有如下定义:

__Vectors DCD __initial_sp ; 栈底指针DCD Reset_Handler ; Reset HandlerDCD NMI_Handler ; NMI HandlerDCD HardFault_Handler ; Hard Fault HandlerDCD MemManage_Handler ; MPU Fault Handler

        以上就是向量表(只列出前几个)的部分内容,可以看到向量表的第一个元素就是栈指针的初始值,也就是栈底指针。

        在了解了这两个问题之后,接下来再来看看代码。首先是获取 VTOR 的地址,接着获取VTOR 的值,也就是获取向量表的首地址,最后获取向量表中第一个字的数据,也就是栈底指针了。

        3. 在获取了栈顶指针后,将 MSP 指针重新赋值为栈底指针。这个操作相当于丢弃了程序之前保存在栈中的数据,因为FreeRTOS从开启任务调度器到启动第一个任务都是不会返回的,是一条不归路,因此将栈中的数据丢弃,也不会有影响。

        4. 重新赋值 MSP 后,接下来就重新使能全局中断,因为之前在函数 vTaskStartScheduler()中关闭了受 FreeRTOS 的中断
        5. 最后使用 SVC 指令,并传入系统调用号 0,触发 SVC 中断。

        SVC中断处理函数vPortSVCHandler()

        当使能了全局中断,并且手动触发 SVC 中断后,就会进入到 SVC 的中断服务函数中。 SVC的中断服务函数为 vPortSVCHandler(),该函数在 port.c 文件中有定义,具体的代码如下所示(这里以正点原子的 STM32F1 系列开发板为例,其他类型的开发板类似):

_asm void vPortSVCHandler( void )
{/* 8 字节对齐 */PRESERVE8/* 获取任务栈地址 */ldr r3, = pxCurrentTCB /* r3 指向优先级最高的就绪态任务的任务控制块 */ldr r1, [ r3 ] /* r1 为任务控制块地址 */ldr r0, [ r1 ] /* r0 为任务控制块的第一个元素(栈顶) *//* 模拟出栈,并设置 PSP */ldmia r0 !, { r4 - r11 } /* 任务栈弹出到 CPU 寄存器 */msr psp, r0 /* 设置 PSP 为任务栈指针 */isb/* 使能所有中断 */mov r0, # 0msr basepri,/* 使用 PSP 指针,并跳转到任务函数 */orr r14, # 0xdbx r14
}

        从上面代码中可以看出,函数 vPortSVCHandler()就是用来跳转到第一个任务函数中去的,该函数的具体解析如下:

        1. 首先通过 pxCurrentTCB 获取优先级最高的就绪态任务的任务栈地址,优先级最高的就绪态任务就是系统将要运行的任务。 pxCurrentTCB 是一个全局变量,用于指向系统中优先级最高的就绪态任务的任务控制块
        举个例子:

        定时器处理任务的任务优先级为 31,是系统中优先级最高的任务,因此当进入 SVC 中断时, pxCurrentTCB 就是指向了定时器处理任务的任务控制块。
        接着通过获取任务控制块中的第一个元素,得到该任务的栈顶指针,任务控制块的相关内容

        2. 接下来通过任务的栈顶指针,将任务栈中的内容出栈到 CPU 寄存器中,任务栈中的内容在调用任务创建函数的时候,已经初始化了。然后再设置 PSP 指针,那么,这么一来,任务的运行环境就准备好了。(这里的任务栈顶指针就是最下图里的pxTopOfStack)

        3. 通过往 BASEPRI 寄存器中写 0,允许中断。

        4. 最后通过两条汇编指令,使 CPU 跳转到任务的函数中去执行,代码如下所示:

orr r14, # 0xd
bx r14

        要弄清楚这两条汇编代码,首先要清楚 r14 寄存器是干什么用的。 通常情况下, r14 为链接寄存器(LR),用于保存函数的返回地址。但是在异常或中断处理函数中, r14 为 EXC_RETURN (关于 r14 寄存器的相关内容,感兴趣的读者请自行查阅相关资料), EXC_RETURN 各比特位的描述如下表所示:

        XC_RETURN 只有 6 个合法的值,如下表所示:

        为此时是在 SVC 的中断服务函数中,因此此时的 r14 应为 EXC_RETURN,将 r14 与 0xd作或操作,然后将值写入 r14,那么就是将 r14 的值设置为了 0xFFFFFFFD 或 0xFFFFFFED(具体看是否使用了浮点单元),即返回后进入线程模式,并使用 PSP。这里要注意的是, SVC 中断服务函数的前面,将 PSP 指向了任务栈。
         说了这么多, FreeRTOS 对于进入中断后 r14 为 EXC_RETURN 的具体应用就是,通过判断EXC_RETURN 的 bit4 是否为 0,来判断任务是否使用了浮点单元。

        最后通过 bx r14 指令,跳转到任务的任务函数中执行,执行此指令, CPU 会自动从 PSP 指向的栈中出栈 R0、 R1、 R2、 R3、 R12、 LR、 PC、 xPSR 寄存器, 并且如果 EXC_RETURN 的bit4 为 0(使用了浮点单元),那么 CPU 还会自动恢复浮点寄存器。

出栈/压栈汇编指令详解

任务栈图解:

http://www.mmbaike.com/news/79454.html

相关文章:

  • 如何创立网址大连做优化网站哪家好
  • 洛阳做网站公司有哪些网站推广方案模板
  • 哪个公司做网站最好深圳军事新闻
  • 做门户网站用什么如何提升百度关键词排名
  • 协会网站建设的优势东莞网站建设seo
  • 中国建设协会官网站seo薪资seo
  • 益阳网站建设公司有哪些广州网站优化服务
  • 网站设计深圳联系电话?友情链接实例
  • 即给做网站又给我们做推广的公司呢手机百度下载免费
  • 网站建设论坛排名seo做什么网站赚钱
  • icp网站备案核验单下载电子商务平台建设
  • 东阿网站建设百度号码认证平台官网
  • 合肥做网站价格西安seo培训学校
  • 大的互联网公司深圳债务优化公司
  • 免费自己做网站电商平台开发需要多少钱
  • 企业网站制作免费网站开发需要哪些技术
  • 绍兴专业网站建设公司网络营销方案策划书
  • 做装修的有那些网站超级外链吧外链代发
  • 黄石网站设计网络广告公司排名
  • 攻击网站的方法实时热搜榜
  • 简述网站开发的5个步骤百度官方电话
  • 安徽美丽乡村建设网站广州网站推广平台
  • xsl做书店网站抖音流量推广神器软件
  • 网站咋做外贸网站营销推广
  • html5公司网站欣赏seo初级入门教程
  • 如何制作网站?建站模板平台
  • 网站内链少改怎么做浙江百度推广开户
  • 建设银行官方网站链接百度allin 人工智能
  • 五金制品东莞网站建设大侠seo外链自动群发工具
  • 做电影下载网站赚钱网站广告调词软件