STM32标准库的部署和FreeRTOS的移植(适用各类开发板) |
您所在的位置:网站首页 › freertos官方网站 › STM32标准库的部署和FreeRTOS的移植(适用各类开发板) |
FreeRTOS的移植
一、准备1.下载源文件2. 文件内容2.1 include文件2.2 portable文件
二、STM32工程部署1. 标准库1.1 下载标准库1.2 标准库简介内核文件库文件配置文件和中断函数文件
2. keil设置2.1 为什么要添加STM32F10X_HD,USE_STDPERIPH_DRIVER宏定义2.1.1 USE_STDPERIPH_DRIVER2.1.1 STM32F10X_HD
三、移植FreeRTOS到工程1. 复制文件2. 在keil工程中添加FreeRTOS内容3. 修改FreeRTOSConfig.h文件4. 修改stm32f10x_it.c文件
四、编写程序
一、准备
1.下载源文件
FreeRTOS Real Time Kernel Files 下载V9.0.0下的FreeRTOSv9.0.0.zip 下载完成解压后 2. 文件内容双击打开FreeRTOS文件夹,这就是FreeRTOS V9.0.0的源文件了 2.1 include文件在include文件夹中是一些头文件,这是需要移植到嵌入式平台的部分 2.2 portable文件这个文件夹下需要关注的是移植哪种编译环境的文件和管理内存的文件 在本次的学习中使用的是keil环境,“See-also-the-RVDS-directory”其主要参照是在RVDS文件夹中的ARM系列CM3 二、STM32工程部署在keil中创建一个STM32的工程首先开始部署STM32的标准库环境。 1. 标准库 1.1 下载标准库STM32F10x标准外设库 可以选择注册一个stm32的账号来下载该固件库 下载并解压后得到如下 1.2 标准库简介在上图中需要的标准库内容只在Libraries文件夹中,为了方便管理将该文件夹分类 内核文件内核文件在Libraries\CMSIS\CM3\CoreSupport 将这两个文件复制到刚刚创建的keil工程下的CORE文件夹(自己创建的文件夹)下 并且内核文件只是一些对动作的具体描述,比如数据的压栈等等,但这并不能使单片机真正运行起来,还需要单片机的启动程序,这个启动程序也是内核的一部分 在Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm下选择合适的启动文件也放入到CORE中 复制合适的启动文件 库文件Libraries\STM32F10x_StdPeriph_Driver 在工程下新建一个STM32_Libraries文件夹将ku文件全部存入 配置文件和中断函数文件是在例程中,打开任意例程就可以找到这两个文件(外加一个头文件) Project\STM32F10x_StdPeriph_Examples\ADC\ADC1_DMA 将他们复制到STM32_Config中 并且在Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x找到系统文件也一并存入STM32_Config中 说明:system_stm32f10x.c .h是系统的初始化程序包括系统的基础时钟初始化 至此STM32的标准库部署基本完成 下面是对keil工程的设置和文件的添加了 2. keil设置向keil中添加文件夹及添加文件,文件夹按照创建的文件夹名创建文件夹 最重要的是要在编译器中添加宏定义,要让编译器明确单片机容量类型STM32F10X_HD,USE_STDPERIPH_DRIVER 并且将头文件地址加入到头文件地址框中 2.1 为什么要添加STM32F10X_HD,USE_STDPERIPH_DRIVER宏定义 2.1.1 USE_STDPERIPH_DRIVER在main函数中需要在开头包含stm32f10x.h这个文件 在该文件中搜索USE_STDPERIPH_DRIVER宏,可以发现这个宏是决定是否要包含stm32f10x_conf.h这个头文件的一个标识 而打开stm32f10x_conf.h这个文件可以发现,在这个文件里面包含了所有的标准库的头文件,这也是为什么在main.c中只引入了一个stm32f10x.h文件的原因 2.1.1 STM32F10X_HD同理也在stm32f10x.h这个文件中搜索STM32F10X_HD宏,可以看到有对中断的描述,也有对内核链接外设的描述 三、移植FreeRTOS到工程 1. 复制文件在工程下新建一个文件夹叫FreeRTOS 将FreeRTOS的源文件FreeRTOSv9.0.0\FreeRTOS\Source下的内容复制到FreeRTOS中 打开portable文件夹删除我们不需要的内容 打开FreeRTOSv9.0.0\FreeRTOS\Demo\CORTEX_STM32F103_Keil文件 将这个文件复制到工程文件夹中的FreeRTOS/include文件夹下 2. 在keil工程中添加FreeRTOS内容在keil中新建两个文件夹FreeRTOS_CORE和FreeRTOS_PORT,并在这两个文件夹下添加文件 接下来将头文件地址加入到keil的头文件寻址框中 3. 修改FreeRTOSConfig.h文件在FreeRTOSConfig.h中添加如下内容 #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler 4. 修改stm32f10x_it.c文件将以下三个函数注释 至此FreeRTOS的移植和STM32标准库的部署基本完工 四、编写程序 #include "stm32f10x.h" #include "FreeRTOS.h" #include "task.h" //任务优先级 #define START_TASK_PRIO 1 //任务堆栈大小 #define START_STK_SIZE 128 //任务句柄 TaskHandle_t StartTask_Handler; //任务函数 void start_task(void *pvParameters); //任务优先级 #define LED0_TASK_PRIO 2 //任务堆栈大小 #define LED0_STK_SIZE 50 //任务句柄 TaskHandle_t LED0Task_Handler; //任务函数 void led0_task(void *pvParameters); //任务优先级 #define LED1_TASK_PRIO 3 //任务堆栈大小 #define LED1_STK_SIZE 50 //任务句柄 TaskHandle_t LED1Task_Handler; //任务函数 void led1_task(void *pvParameters); void GPIO_INIT() { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE); //使能PB,PE端口时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED0-->PB.5 端口配置 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB.5 GPIO_SetBits(GPIOB,GPIO_Pin_5); //PB.5 输出高 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED1-->PE.5 端口配置, 推挽输出 GPIO_Init(GPIOE, &GPIO_InitStructure); //推挽输出 ,IO口速度为50MHz GPIO_SetBits(GPIOE,GPIO_Pin_5); //PE.5 输出高 } void start_task(void *pvParameters) { taskENTER_CRITICAL(); //进入临界区 //创建LED0任务 xTaskCreate((TaskFunction_t )led0_task, (const char* )"led0_task", (uint16_t )LED0_STK_SIZE, (void* )NULL, (UBaseType_t )LED0_TASK_PRIO, (TaskHandle_t* )&LED0Task_Handler); //创建LED1任务 xTaskCreate((TaskFunction_t )led1_task, (const char* )"led1_task", (uint16_t )LED1_STK_SIZE, (void* )NULL, (UBaseType_t )LED1_TASK_PRIO, (TaskHandle_t* )&LED1Task_Handler); vTaskDelete(StartTask_Handler); //删除开始任务 taskEXIT_CRITICAL(); //退出临界区 } //LED0 任务函数 void led0_task(void *pvParameters) { while(1) { GPIO_SetBits(GPIOE,GPIO_Pin_5); vTaskDelay(500); GPIO_ResetBits(GPIOB,GPIO_Pin_5); vTaskDelay(500); } } //LED1 任务函数 void led1_task(void *pvParameters) { while(1) { GPIO_ResetBits(GPIOE,GPIO_Pin_5); vTaskDelay(300); GPIO_SetBits(GPIOB,GPIO_Pin_5); vTaskDelay(300); } } int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组 4 GPIO_INIT(); //创建开始任务 xTaskCreate((TaskFunction_t )start_task, //任务函数 (const char* )"start_task", //任务名称 (uint16_t )START_STK_SIZE, //任务堆栈大小 (void* )NULL, //传递给任务函数的参数 (UBaseType_t )START_TASK_PRIO, //任务优先级 (TaskHandle_t* )&StartTask_Handler); //任务句柄 vTaskStartScheduler(); //开启任务调度 } |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |