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

营销型网站规划建设的七大要素网站联系方式模板

营销型网站规划建设的七大要素,网站联系方式模板,剪辑素材网站免费,企业网站网页设计的步骤文章目录 一、任务调度器开启函数 vTaskStartScheduler()二、内核相关硬件初始化函数 xPortStartScheduler()三、启动第一个任务 prvStartFirstTask()四、中断服务函数 xPortPendSVHandler()五、空闲任务 一、任务调度器开启函数 vTaskStartScheduler() 这个函数的功能就是开启… 文章目录 一、任务调度器开启函数 vTaskStartScheduler()二、内核相关硬件初始化函数 xPortStartScheduler()三、启动第一个任务 prvStartFirstTask()四、中断服务函数 xPortPendSVHandler()五、空闲任务 一、任务调度器开启函数 vTaskStartScheduler() 这个函数的功能就是开启任务调度器的这个函数在文件 tasks.c中有定义缩减后的函数代码如下 void vTaskStartScheduler( void ) {BaseType_t xReturn;xReturn xTaskCreate( prvIdleTask, (1)IDLE, configMINIMAL_STACK_SIZE,( void * ) NULL,( tskIDLE_PRIORITY | portPRIVILEGE_BIT ),xIdleTaskHandle );#if ( configUSE_TIMERS 1 ) //使用软件定时器使能{if( xReturn pdPASS ){xReturn xTimerCreateTimerTask(); (2)}else{mtCOVERAGE_TEST_MARKER();}}#endif /* configUSE_TIMERS */if( xReturn pdPASS ) //空闲任务和定时器任务创建成功。{portDISABLE_INTERRUPTS(); (3)#if ( configUSE_NEWLIB_REENTRANT 1 ) //使能 NEWLIB{_impure_ptr ( pxCurrentTCB-xNewLib_reent );}#endif /* configUSE_NEWLIB_REENTRANT */xNextTaskUnblockTime portMAX_DELAY;xSchedulerRunning pdTRUE; (4)xTickCount ( TickType_t ) 0U;portCONFIGURE_TIMER_FOR_RUN_TIME_STATS(); (5)if( xPortStartScheduler() ! pdFALSE ) (6){//如果调度器启动成功的话就不会运行到这里函数不会有返回值的}else{//不会运行到这里除非调用函数 xTaskEndScheduler()。}}else{//程序运行到这里只能说明一点那就是系统内核没有启动成功导致的原因是在创建//空闲任务或者定时器任务的时候没有足够的内存。configASSERT( xReturn ! errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY );}//防止编译器报错比如宏 INCLUDE_xTaskGetIdleTaskHandle 定义为 0 的话编译器就会提//示 xIdleTaskHandle 未使用。( void ) xIdleTaskHandle; }(1)、创建空闲任务如果使用静态内存的话使用函数 xTaskCreateStatic()来创建空闲任务优先级为 tskIDLE_PRIORITY宏 tskIDLE_PRIORITY 为 0也就是说空闲任务的优先级为最低。 (2)、如果使用软件定时器的话还需要通过函数xTimerCreateTimerTask()来创建定时器服务任务。定时器服务任务的具体创建过程是在函数 xTimerCreateTimerTask()中完成的。 (3)、关闭中断在 SVC 中断服务函数 vPortSVCHandler()中会打开中断。 (4)、变量 xSchedulerRunning 设置为 pdTRUE表示调度器开始运行。 (5)、当宏 configGENERATE_RUN_TIME_STATS 为 1 的时候说明使能时间统计功能此时需要用户实现宏 portCONFIGURE_TIMER_FOR_RUN_TIME_STATS此宏用来配置一个定时器/计数器。 (6)、调用函数 xPortStartScheduler()来初始化跟调度器启动有关的硬件比如滴答定时器、FPU 单元和 PendSV 中断等等。 二、内核相关硬件初始化函数 xPortStartScheduler() FreeRTOS 系统时钟是由滴答定时器来提供的而且任务切换也会用到 PendSV 中断这些硬件的初始化由函数 xPortStartScheduler()来完成缩减后的函数代码如下 BaseType_t xPortStartScheduler( void ) {/******************************************************************//****************此处省略一大堆的条件编译代码**********************//*****************************************************************/portNVIC_SYSPRI2_REG | portNVIC_PENDSV_PRI; (1)portNVIC_SYSPRI2_REG | portNVIC_SYSTICK_PRI; (2)vPortSetupTimerInterrupt(); (3)uxCriticalNesting 0; (4)prvStartFirstTask(); (5)//代码正常执行的话是不会到这里的return 0; }(1)、设置 PendSV 的中断优先级为最低优先级。 (2)、设置滴答定时器的中断优先级为最低优先级。 (3)、调用函数 vPortSetupTimerInterrupt()来设置滴答定时器的定时周期并且使能滴答定时器的中断函数比较简单大家自行查阅分析。 (4)、初始化临界区嵌套计数器。 (5)、调用函数 prvStartFirstTask()开启第一个任务。 三、启动第一个任务 prvStartFirstTask() 经过上面的操作以后我们就可以启动第一个任务了函数 prvStartFirstTask()用于启动第一个任务这是一个汇编函数函数源码如下 __asm void prvStartFirstTask( void ) {PRESERVE8ldr r0, 0xE000ED08 ;R00XE000ED08 (1)ldr r0, [r0] ;取 R0 所保存的地址处的值赋给 R0 (2)ldr r0, [r0] ;获取 MSP 初始值 (3)msr msp, r0 ;复位 MSP (4)cpsie I ;使能中断(清除 PRIMASK) (5)cpsie f ;使能中断(清除 FAULTMASK) (6)dsb ;数据同步屏障 (7)isb ;指令同步屏障 (8)svc 0 ;触发 SVC 中断(异常) (9)nopnop }(1)、将 0XE000ED08 保存在寄存器 R0 中。一般来说向量表应该是从起始地址(0X00000000)开始存储的不过有些应用可能需要在运行时修改或重定义向量表Cortex-M 处理器为此提供了一个叫做向量表重定位的特性。向量表重定位特性提供了一个名为向量表偏移寄存器(VTOR)的可编程寄存器。VTOR 寄存器的地址就是 0XE000ED08通过这个寄存器可以重新定义向量表比如在 STM32F103 的 ST 官方库中会通过函数 SystemInit()来设置 VTOR 寄存器 代码如下 SCB-VTOR FLASH_BASE | VECT_TAB_OFFSET; //VTOR0x080000000X00通过上面一行代码就将向量表开始地址重新定义到了0X08000000向量表的起始地址存储的就是 MSP 初始值。 (2)、读取 R0 中存储的地址处的数据并将其保存在 R0 寄存器也就是读取寄存器 VTOR中的值并将其保存在 R0 寄存器中。这一行代码执行完就以后 R0 的值应该为 0X08000000。 (3)、读取 R0 中存储的地址处的数据并将其保存在 R0 寄存器也就是读取地址 0X08000000处存储的数据并将其保存在 R0 寄存器中。我们知道向量表的起始地址保存的就是主栈指针MSP 的初始值这一行代码执行完以后寄存器 R0 就存储 MSP 的初始值。现在来看(1)、(2)、(3)这三步起始就是为了获取 MSP 的初始值而已 (4)、复位 MSPR0 中保存了 MSP 的初始值将其赋值给 MSP 就相当于复位 MSP。 (5)和(6)、使能中断。 (7)和(8)、数据同步和指令同步屏障。 (9)、调用 SVC 指令触发 SVC 中断SVC 也叫做请求管理调用SVC 和 PendSV 异常对于OS 的设计来说非常重要。SVC 异常由 SVC 指令触发。在 FreeRTOS 中仅仅使用 SVC 异常来启动第一 个任务后面的程序中就再也用不到 SVC 了。 四、中断服务函数 xPortPendSVHandler() 在函数 prvStartFirstTask()中通过调用 SVC 指令触发了 SVC 中断而第一个任务的启动就是在 SVC 中断服务函数中完成的SVC 中断服务函数应该为 SVC_Handler()但是 FreeRTOSConfig.h 中通过#define 的方式重新定义为了 xPortPendSVHandler()如下 #define xPortPendSVHandler PendSV_Handler函数 vPortSVCHandler()在文件 port.c 中定义这个函数也是用汇编写的函数源码如下 __asm void vPortSVCHandler( void ) {PRESERVE8ldr r3, pxCurrentTCB ;R3pxCurrentTCB 的地址 (1)ldr r1, [r3] ;取 R3 所保存的地址处的值赋给 R1 (2)ldr r0, [r1] ;取 R1 所保存的地址处的值赋给 R0 (3)ldmia r0!, {r4-r11, r14} ;出栈 R4~R11 和 R14 (4)msr psp, r0 ;进程栈指针 PSP 设置为任务的堆栈 (5)isb ;指令同步屏障mov r0, #0 ;R00 (6)msr basepri, r0 ;寄存器 basepri0开启中断 (7)orr r14, #0xd ; (8)bx r14 (9) }(1)、获取 pxCurrentTCB 指针的存储地址pxCurrentTCB 是一个指向 TCB_t 的指针这个指针永远指向正在运行的任务。这里先获取这个指针存储的地址比如我现在的代码测试出来这个指针是存放在 0X20000044如下图所示。 (2)、取 R3 所保存的地址处的值赋给 R1。通过这一步就获取到了当前任务的任务控制块的存储地址。比如当前我的程序中这个地址就为 0X20000EE8如下图所示 (3)、取 R3 所保存的地址处的值赋给 R0我们知道任务控制块的第一个字段就是任务堆栈的栈顶指针 pxTopOfStack 所指向的位置所以读取任务控制块所在的首地址(0X20000EE8)得到 的就是栈顶指针所指向的地址当前我的程序中这个栈顶指针(pxTopOfStack)所指向的地址为0X20000E98如下图所示 可以看出(1)、(2)和(3)的目的就是获取要切换到的这个任务的任务栈顶指针因为任务所对应的寄存器值也就是现场都保存在任务的任务堆栈中所以需要获取栈顶指针来恢复这些寄存器值 (4)、R4~R11R14 这些寄存器出栈。这里使用了指令 LDMIALDMIA 指令是多加载/存储指令不过这里使用的是具有回写的多加载/存储访问指令用法如下 LDMIA Rn! , {reg list}表示从 Rn 指定的存储器位置读取多个字地址在每次读取后增加(IA),Rn 在传输完成以后写回。对于 STM32 来说地址一次增加 4 字节比如如下代码 LDR R0, 0X800 LDMIA R0!, {R2~R4}上面两行代码就是将 0X800 地址的数据赋值给寄存器 R20X804 地址的数据赋值给寄存器 R30X8008 地址的数据赋值给 R4 寄存器然后重点来了此时 R0 为 800A通过这一步我们就从任务堆栈中将 R4~R11 这几个寄存器的值给恢复了。这里有朋友就要问了R0~R3R12PC,xPSR 这些寄存器怎么没有恢复这是因为这些寄存器会在退出中断的时候 MCU 自动出栈(恢复)的而 R4~R11 需要由用户手动出栈。这个我们在分析 PendSV 中断服务函数的时候会讲到。到这步以后我们来看一下堆栈的栈顶指针指到哪 里了如下图所示 从上图可以看出恢复 R4~R11 和 R14 以后堆栈的栈顶指针应该指向地址 0X20000EB8也就是保存寄存器 R0 值的存储地址。退出中断服务函数以后进程栈指针 PSP 应该从这个地址开始恢复其他的寄存器值。 (5)、设置进程栈指针 PSPPSPR00X20000EB8如下图所示 (6)、设置寄存器 R0 为 0。 (7)、设置寄存器 BASEPRI 为 R0也就是 0打开中断 (8)、R14 寄存器的值与 0X0D 进行或运算得到的结果就是 R14 寄存器的新值。表示退出异常以后 CPU 进入线程模式并且使用进程栈 (9)、执行此行代码以后硬件自动恢复寄存器 R0~R3、R12、LR、PC 和 xPSR 的值堆栈使用进程栈 PSP然后执行寄存器 PC 中保存的任务函数。至此FreeRTOS 的任务调度器正式开始运行 五、空闲任务 在前面讲解函数 vTaskStartScheduler()说过此函数会创建一个名为“IDLE”的任务这个任务叫做空闲任务。顾名思义空闲任务就是空闲的时候运行的任务也就是系统中其他的任务由于各种原因不能运行的时候空闲任务就在运行。空闲任务是 FreeRTOS 系统自动创建的不需要用户手动创建。任务调度器启动以后就必须有一个任务运行但是空闲任务不仅仅是为了满足任务调度器启动以后至少有一个任务运行而创建的空闲任务中还会去做一些其他 的事情如下 1、判断系统是否有任务删除如果有的话就在空闲任务中释放被删除任务的任务堆栈和任务控制块的内存。 2、运行用户设置的空闲任务钩子函数。 3、判断是否开启低功耗 tickless 模式如果开启的话还需要做相应的处理空闲任务的任务优先级是最低的为 0任务函数为 prvIdleTask()。
http://www.hkea.cn/news/14494047/

相关文章:

  • 互联网网站建设维护湛江市建设局官方网站
  • 精品建站公司天津市建设工程管理信息网
  • 地图 添加到网站如何建设网站安全
  • 什么网站可以做旅行行程单营销型网站 典型案例
  • 网站搭建要多少钱相城区住房建设局网站
  • 网站遮罩是什么seo技术培训沈阳
  • 福州帮人建网站公司阿里云做网站买什么
  • 有创意的30个网站wordpress导航站模版
  • 嘉鱼网站建设公司百度官方网平台
  • 上百度首页舟山网站seo
  • 网站建设哪里最好接单子冠县网站建设多少钱
  • 网站建设方案平台架构南宁网站建设公司seo优化
  • 护肤品网站优化案例做网站一定要有服务器吗
  • 电商平台网站有哪些ext做的网站有那些
  • 做网站html和asp网站开发创业计划书模板
  • 论坛网站建设推广优化wordpress logo 字体
  • 思坎普网站建设网站建设属于移动互联网
  • 网站建设的违约责任怎么写正规的跨境电商平台有哪些
  • 东明县住房和城乡建设局网站seo网站优化是什么
  • 网站 logfiles国外域名免费注册
  • 网站管理助手未找到iismrskinlove wordpress
  • 上海外贸营销网站建设网站泰州网站建设策划方案
  • 网站查询系统迅睿cms和帝国哪个好
  • 江津做网站锦州建设银行网站
  • 嘉定企业网站制作微信网站合同
  • 网站文字大小东莞市一箭天网络科技有限公司
  • asp.net mvc网站开发有网站地图的网站
  • 北京网站建设乐云seo学校网站建设招标公告
  • 做文字头像的网站洛阳霞光网络建站公司
  • 做隐私的网站百度商桥怎么和网站