介绍freertos在stm32上的移植说明,每一步都很详细,让你学会在stm32+freeRTOS的平台上开发应用程序
一、各文件关键部分的实现:1、PORTMACRO.H宏定义部分1)定义编译器相关的各种数据类型#defineportCHARchar#defineportFLOATfloat#defineportDOUBLEdouble#defineportLONGlong#defineportSHORTshort#defineportSTACK_TYPEunsignedportLONG#defineportBASE_TYPElong2)架构相关的定义Cortex-M3的堆栈增长方向为高地址向低地址增长#defineportSTACK_GROWTH(-1)每毫秒的心跳次数#defineportTICK_RATE_MS((portTickType)1000/configTICK_RATE_HZ)访问SRAM的字节对齐#defineportBYTE_ALIGNMENT83)定义用户主动引起内核调度的2个函数强制上下文切换,用在任务环境中调用#defineportYIELD()vPortYieldFromISR()强制上下文切换,用在中断处理环境中调用#defineportEND_SWITCHING_ISR(xSwitchRequired)if(xSwitchRequired)vPortYieldFromISR()4)定义临界区的管理函数中断允许和关闭#defineportDISABLE_INTERRUPTS()vPortSetInterruptMask()#defineportENABLE_INTERRUPTS()vPortClearInterruptMask()临界区进入和退出#defineportENTER_CRITICAL()vPortEnterCritical()#defineportEXIT_CRITICAL()vPortExitCritical()用于在中断环境的中断允许和关闭#defineportSET_INTERRUPT_MASK_FROM_ISR()0;vPortSetInterruptMask()#defineportCLEAR_INTERRUPT_MASK_FROM_ISR(x)vPortClearInterruptMask();(void)x2、PORT.CC接口部分1)堆栈初始化portSTACK_TYPE*pxPortInitialiseStack(portSTACK_TYPE*pxTopOfStack,pdTASK_CODEpxCode,void*pvParameters){*pxTopOfStack=portINITIAL_XPSR;/*程序状态寄存器*/pxTopOfStack--;*pxTopOfStack=(portSTACK_TYPE)pxCode;/*任务的入口点*/pxTopOfStack--;*pxTopOfStack=0;/*LR*/pxTopOfStack-=5;/*R12,R3,R2andR1.*/*pxTopOfStack=(portSTACK_TYPE)pvParameters;/*任务的参数*/pxTopOfStack-=8;/*R11,R10,R9,R8,R7,R6,R5andR4.*/returnpxTopOfStack;}2)启动任务调度portBASE_TYPExPortStartScheduler(void){让任务切换中断和心跳中断位于最低的优先级,使更高优先级可以抢占mcu*(portNVIC_SYSPRI2)|=portNVIC_PENDSV_PRI;*(portNVIC_SYSPRI2)|=portNVIC_SYSTICK_PRI;设置并启动系统的心跳时钟prvSetupTimerInterrupt();初始化临界区的嵌套的个数uxCriticalNesting=0;启动第一个任务vPortStartFirstTask();执行到vPortStartFirstTask函数,内核已经开始正常的调度return0;}3)主动释放mcu使用权voidvPortYieldFromISR(void){触发PendSV系统服务中断,中断到来时由汇编函数xPortPendSVHandler()处理*(portNVIC_INT_CTRL)=portNVIC_PENDSVSET;}进入临界区时,首先关闭中断;当退出所以嵌套的临界区后再使能中断voidvPortEnterCritical(void){portDISABLE_INTERRUPTS();uxCriticalNesting++;}voidvPortExitCritical(void){uxCriticalNesting--;if(uxCriticalNesting==0){portENABLE_INTERRUPTS();}}4)心跳时钟处理函数voidxPortSysTickHandler(void){unsignedportLONGulDummy;如果是抢占式调度,首先看一下有没有需要调度的任务#ifconfigUSE_PREEMPTION==1*(portNVIC_INT_CTRL)=portNVIC_PENDSVSET;#endifulDummy=portSET_INTERRUPT_MASK_FROM_ISR();{通过task.c的心跳处理函数vTaskIncrementTick(),进行时钟计数和延时任务的处理vTaskIncrementTick();}portCLEAR_INTERRUPT_MASK_FROM_ISR(ulDummy);}3、PORTASM.S汇编处理部分1)请求切换任务xPortPendSVHandler:保存当前任务的上下文到其任务控制块mrsr0,pspldrr3,=pxCurrentTCB获取当前任务的任务控制块指针ldrr2,[r3]stmdbr0!,{r4-r11}保存R4-R11到该任务的堆栈strr0,[r2]将最后的堆栈指针保存到任务控制块的pxTopOfStackstmdbsp!,{r3,r14}关闭中断movr0,#configMAX_SYSCALL_INTERRUPT_PRIORITYmsrbasepri,r0切换任务的上下文,pxCurrentTCB已指向新的任务blvTaskSwitchContextmovr0,#0msrbasepri,r0ldmiasp!,{r3,r14}恢复新任务的上下文到各寄存器ldrr1,[r3]ldrr0,[r1]/*ThefirstiteminpxCurrentTCBisthetasktopofstack.*/ldmiar0!,{r4-r11}/*Poptheregisters.*/msrpsp,r0bxr142.)中断允许和关闭的实现,通过BASEPRI屏蔽相应优先级的中断源vPortSetInterruptMask:push{r0}movR0,#configMAX_SYSCALL_INTERRUPT_PRIORITYmsrBASEPRI,R0pop{R0}bxr14vPortClearInterruptMask:PUSH{r0}MOVR0,#0MSRBASEPRI,R0POP{R0}bxr143)直接切换任务,用于vPortStartFirstTask第一次启动任务时初始化堆栈和各寄存器vPortSVCHandler;ldrr3,=pxCurrentTCBldrr1,[r3]ldrr0,[r1]ldmiar0!,{r4-r11}msrpsp,r0movr0,#0msrbasepri,r0orrr14,r14,#13bxr144)启动第一个任务的汇编实现vPortStartFirstTask通过中断向量表的定位堆栈的地址ldrr0,=0xE000ED08向量表偏移量寄存器(VTOR)ldrr0,[r0]ldrr0,[r0]msrmsp,r0将堆栈地址保存到主堆栈指针msp中触发SVC软中断,由vPortSVCHandler()完成第一个任务的具体切换工作svc0FreeRTOS内核调度器启动的流程如下:以上3个文件实现了FreeRTOS内核调度所需的底层接口,相关代码十分精简。
二、创建测试任务:下面创建第一个测试任务,LED测试intmain(void){设置系统时钟,中断向量表和LED使用的GPIO使用stm32的固件包提供的初始化函数,具体说明见相关手册prvSetupHardware();通过xTaskCreate()创建4个LED任务vLEDFlashTask(),每个任务根据各自的频率闪烁,分别对应开发板上的4个LEDvStartLEDFlashTasks(mainFLASH_TASK_PRIORITY);?创建一个IDLE任务后,通过xPortStartScheduler启动调度器vTaskStartScheduler();调度器工作不正常时返回return0;}portTASK_FUNCTION()是FreeRTOS定义的函数声明,没特殊作用staticportTASK_FUNCTION(vLEDFlashTask,pvParameters){……省略……,具体为计算各LED的闪烁频率for(;;){vTaskDelayUntil(&xLastFlashTime,xFlashRate);vParTestToggleLED(uxLED);vTaskDelayUntil()的延时时间xFlashRate,是从上一次的延时时间xLastFlashTime算起的,相对vTaskDelay()的直接延时更为精准。vTaskDelayUntil(&xLastFlashTime,xFlashRate);vParTestToggleLED(uxLED);}}FreeRTOS的任务创建与UC/OSII差异不大,主要参数为任务函数,堆栈大小和任务的优先级。如:xTaskCreate(vLEDFlashTask,(signedportCHAR*)"LEDx",ledSTACK_SIZE,NULL,uxPriority,(xTaskHandle*)NULL);下面再创建一个LCD显示任务,以最低优先级运行:xTaskCreate(vLCDTask,(signedportCHAR*)"LCD",configMINIMAL_STACK_SIZE,NULL,tskIDLE_PRIORITY,NULL);voidvLCDTask(void*pvParameters){……省略……for(;;){vTaskDelay(1000);printf("%c",usDisplayChar);}}该任务很简单,每隔1000个ticks(就是1000ms),从LCD上刷新一个数字。至此,FreeRTOS在STM32上的移植基本完成。与UC/OSII相比,FreeRTOS精简的实现更适合用来学习实时操作系统的工作原理,对其进行剖析也相对容易。接下来,我们将会移植CAN,RS485,SD卡和USB等接口到FreeRTOS,使其在STM32平台上更加完善。
Tags:FreeRTOS.
小编点评:Free3DVideoMaker是.
下载小编点评:小黑裙瑜伽ios版是一款手机上的健身软件,在小.
下载小编点评:视频大拍档剪辑助手是一款好用的电脑端短视.
下载小编点评:《折磨:扭蒙拉之潮》故事发生于人类文明没落.
下载小编点评:子弹风暴:完全版在近期终于正式发行的了,相.
下载小编点评:铲子骑士磨难之灵是经典游戏铲子骑士.
下载小编点评:精易论坛皮肤修改源码,一款精易论坛版块推出的皮肤.
下载小编点评:百度站长平台原创提交工具是一款可以.
下载小编点评:倩女幽魂应用宝版本是一款新一代玄幻唯.
下载小编点评:斗阵无双2手游是一款经典三国题材的手.
下载小编点评:神仙与妖怪果盘版是一款可玩性非常高.
下载小编点评:梦幻千炮捕鱼微信版一款多人实时在线.
下载小编点评:集装箱交通3d游戏是一款模拟开车的休闲.
下载az火箭队游戏下载-az火箭队手机游戏最新版下载v1.2.1 安卓版
把它们全部砍掉安卓下载-把它们全部砍掉下载v1.0 安卓版
琪琪和菲菲宠物美容院手游下载-琪琪和菲菲宠物美容院游戏下载v1.0 安卓版
popularwars破解版下载-popular wars中文破解版下载v1.1.0 安卓内购版
海底猎杀模拟器游戏下载-海底猎杀模拟器手机版下载v1.0.9 安卓版
仙梦奇缘幽游百景手游下载-仙梦奇缘幽游百景官方版下载v1.3.4 安卓版
神舰传说游戏下载-神舰传说手游下载v1.0.0 安卓版
qq你画我猜画画接龙官方版免费下载-你画我猜qq游戏手机版下载v10.82.2 安卓最新版
侠客恩仇录手游下载-侠客恩仇录官方版下载v1.5.3.000 安卓版
飞吧西游九游手游下载-飞吧西游九游最新版下载v1.0 安卓版
僵尸病毒3手游下载-僵尸病毒3游戏下载v17 安卓版
猎人斗技场之战游戏下载-猎人斗技场之战正式版下载v1.0 安卓版
诸世王者华为手游下载-诸世王者华为版本下载v3.0.3 安卓最新版