基于stm32平台freertos的温度数据采集系统大学论文 下载本文

1、任务堆栈初始化函数(pxPortInitialiseStack)

该函数主要定义了任务堆栈的数据结构,由于不同的CPU,其堆栈的数据结

构也不相同,其STM32 CPU内核的结构如图4.2所示。

图 4.2 STM32 内核结构

按照STM32内核结构,定义函数pxPortInitialiseStack ,该函数主要模拟STM32的内核堆栈结构,创建一个上下文中断切换。其代码如下:

StackType_t* pxPortInitialiseStack (StackType_t * pxStack, TaskFunction _tpxCode,void*pvParameters)

{

pxStack--; //中断指针偏移量

* pxStack =portINITIAL_XPSR; //状态寄存器 pxStack --;

* pxStack =(StackType_t)pxCode; //加载任务代码 pxStack --;

* pxStack =(StackType_t)portTASK_RETURN_ADDRESS; //返回连接地址 pxStack -=5; /* R12, R3, R2 and R1. */ * pxStack =(StackType_t)pvParameters; /* R0 */ pxStack -=8; return pxStack; }

这个初始化堆栈函数主要在建立和退出时进行了调用,主要保存了CPU内核寄存器的相关参数,如堆栈大小,返回地址,函数任务地址等等。

2、任务调度函数(xPortStartScheduler)

24

该函数主要实现任务的调度使能,它负责初始化中断,为FreeRTOS提供时

钟节拍。初始化STM32定时器管理代码,定时时钟节拍时间系数,然后开始执行第一个任务,其代码如下:

portBASE_TYPE xPortStartScheduler(void) {

extern uint32 VECTOR_RAM[]; //定义STM32中断向量表地址 VECTOR_RAM[15]=(UINT32) xPortSysTickHandler; //定义中断服务函数入口 SYST_RVR=(configCPU_CLOCK_HZ/configTICK_RATE_HZ)-1UL;

SYST_CSR=portSYSTICK_CLK|portSYSTICK_INT|portSYSTICK_ENABLE; vPortISRStartFirstTask(); //执行第一个任务 return 0; }

3、系统时钟节拍中断函数 (xPortSysTickHandler)

该函数为中断服务程序,也算回调程序,由于STM32提供一个SysTick定时

器,它的优先级最低,所以,当执行该中断时候,其他中断已经执行完成。因此不需要保存现场。其代码如下:

voidxPortSysTickHandler(void) {

(void)portSET_INTERRUPT_MASK_FROM_ISR();

{ if(xTaskIncrementTick()!=pdFALSE) //RTOS 节拍加 1 { portNVIC_INT_CTRL_REG=portNVIC_PENDSVSET_BIT; } }

portCLEAR_INTERRUPT_MASK_FROM_ISR(0); }

4、软件中断函数(vPortYieldFromISR)。 该函数实现软件陷井中断

void vPortYieldFromISR(void) {

//申请软件中断

SCB_ICSR=portNVIC_PENDSVSET;

25

}

实现了STM32 对应的 portmacro.h、portasm.s 和 port.c 后,然后多次修改调试后,对程序进行编译,FreeRTOS 的移植基本成功了。

4.2.3 FreeRTOS 配置

完成了FreeRTOS的基本移植后,接下来就需要对FreeRTOS进行系统配置了,由于FreeRTOS配置选项比较多,它的定义主要通过定义宏开关来实现,主要配置在FreeRTOSConfig.h 文件中。

其中主要FreeRTOS配置如下:

1、系统时钟节拍,由于系统的节拍时间是通过定时器来实现的,并且任务调度也是通过此来实现的,因此该系统的时钟频率决定了系统的性能,如果该频率越高,系统开销越大;反之,频率过低,在系统实时性能下降,一般设置为合适值既可以,本设计设置为1000HZ,也就是1MS。其定义如下:

#define configCPU_CLOCK_HZ (sysclk_get_cpu_hz()) #define configTICK_RATE_HZ ((portTickType) 1000)

2、定义堆栈的大小,堆栈是每个任务的执行空间,一般堆栈设置不易过大,太大消耗系统内存,本设计定义如下:

#define configMINIMAL_STACK_SIZE ((unsigned short) 70) //#堆栈尺寸的宏定义配置 ((size_t) ( 0x2C00-600 )) #define configMAX_TASK_NAME_LEN ( 16 )

3、任务个数,由于FreeRTOS操作的任务个数,不像UCOS那样,固定为 256个,对于FreeRTOS的任务数量无限制,通过定义宏定义,可以定义任务个数。

#define configMAX_PRIORITIES ((unsigned portBASE_TYPE) 5)

4.2.4 FreeRTOS 移植测试

当完成FreeRTOS 的移植后,接下来需要验证是否移植成功,通过编写测试代码,查看移植是否成功,FreeRTOS 官方提供了很多的测试代码,主要要对测试代码进行修改或者参考自己编写。本文创建2个任务,通过任务之间的不停切换来测试FreeRTOS移植是否成功[11]。

测试代码如下:建立任务1和任务2,然后通过串口显示任务监控任务是否正常。

26

/*任务1测试程序*/

static void vTask1(void *pvParameters) { for(;;) {

printf(“Task1 is Runing \\r\\n”); vTaskDelay(500); } }

/*任务2测试程序*/

static void vTask2(void *pvParameters) { for(;;) {

printf(“Task2 is Runing \\r\\n”); vTaskDelay(500); } }

打开超级终端,设置好端口号和串口波特率,打开串口,输出如图4-3结果。

图4-3 FreeRTOS测试结果

4.3 应用程序设计

27