【CW32饭盒派开发板试用体验】2. 使用扩展板串口UART3以及scanf重定向到串口
【CW32饭盒派开发板试用体验】3. 使用BTIM实现任务调度器
【CW32饭盒派开发板试用体验】4. ADC采样摇杆模块X轴和Y轴输出
FreeRTOS作为一款开源的嵌入式实时操作系统,广泛的运用在嵌入式行业,在芯片中集成嵌入式系统也是很有必要的一件事,可以方便的处理各个任务之间的关系,进行精确地时间控制等。本文将讲解如何在CW32F030中集成FreeRTOS OS。
开发环境:
前两天也是采用这种使用CMSIS-FreeRTOS的方式移植,但是没成功,是因为在配置的时候选择了使用CMSIS RTOS2,对工程有一定的影响,但是systick进不去,这一次直接选择FreeRTOS,移植成功,而且简洁很多。
KEIL中是集成了FreeRTOS系统的,可以直接在 Pack Installer
中安装,如下图,点击 Install
即可。这样就不用去freeRTOS官网下载整个freeRTOS包了。简单方便快捷
下载过程中可能出现超时的问题,导致下载不成功,因为keil官网从国内访问不是很稳定。
出现上述情况,可以直接在keil官网去下载,使用迅雷要快很多,下载好了之后直接双击pack包安装即可。
官方地址:http://www.keil.com/pack/
下载好freeRTOS的pack包之后,双击安装即可。
安装完成之后,选择官方工程,在官方提供的工程基础上进行移植,选择了 实验一 流水灯实验
。
打开工程,选择 Manage Run-Time Environment
,选择 RTOS
,配置相关信息,见下图:
之后会上报如下几个函数的重定义:
在 interrupts_cw32f030.c
文件中将函数实现 SVC_Handler
, PendSV_Handler
注释掉,在 cw32f030_systick.c
中将函数 SysTick_Handler
注释掉即可。
之后编译不会再报错
到此为止表示移植完成了,接下来就是写两个任务测试一下功能是否正常了
代码如下,创建了两个任务,分别为led1_task和led2_task,分别驱动LED2和LED3闪烁,led1_task的工作周期为500ms,led2_task的工作周期为1000ms。
#include "main.h"
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#define LED1_TASK_PRIO 3 //任务优先级
#define LED1_STK_SIZE 50 //任务堆栈大小
TaskHandle_t LED1Task_Handler; //任务句柄
void led1_task(void *pvParameters); //任务函数
#define LED2_TASK_PRIO 3 //任务优先级
#define LED2_STK_SIZE 50 //任务堆栈大小
TaskHandle_t LED2Task_Handler; //任务句柄
void led2_task(void *pvParameters); //任务函数
void GPIO_Configuration(void);
void RCC_Configuration(void);
int main()
{
// uint32_t i;
RCC_Configuration(); //时钟配置64M
GPIO_Configuration();//LED初始化
//创建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); //任务句柄
xTaskCreate((TaskFunction_t )led2_task, //任务函数
(const char* )"led2_task", //任务名称
(uint16_t )LED2_STK_SIZE, //任务堆栈大小
(void* )NULL, //传递给任务函数的参数
(UBaseType_t )LED2_TASK_PRIO, //任务优先级
(TaskHandle_t* )&LED2Task_Handler); //任务句柄
vTaskStartScheduler(); //开启任务调度
while(1)
{
}
}
void led1_task(void *pvParameters)
{
while(1)
{
PA07_TOG();
vTaskDelay(500);
}
}
void led2_task(void *pvParameters)
{
while(1)
{
PA08_TOG();
vTaskDelay(1000);
}
}
void RCC_Configuration(void)
{
/* 0. HSI使能并校准 */
RCC_HSI_Enable(RCC_HSIOSC_DIV6);
/* 1. 设置HCLK和PCLK的分频系数 */
RCC_HCLKPRS_Config(RCC_HCLK_DIV1);
RCC_PCLKPRS_Config(RCC_PCLK_DIV1);
/* 2. 使能PLL,通过PLL倍频到64MHz */
RCC_PLL_Enable(RCC_PLLSOURCE_HSI, 8000000, 8); // HSI 默认输出频率8MHz
// RCC_PLL_OUT(); //PC13脚输出PLL时钟
///< 当使用的时钟源HCLK大于24M,小于等于48MHz:设置FLASH 读等待周期为2 cycle
///< 当使用的时钟源HCLK大于48MHz:设置FLASH 读等待周期为3 cycle
__RCC_FLASH_CLK_ENABLE();
FLASH_SetLatency(FLASH_Latency_3);
/* 3. 时钟切换到PLL */
RCC_SysClk_Switch(RCC_SYSCLKSRC_PLL);
RCC_SystemCoreClockUpdate(64000000);
}
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
__RCC_GPIOB_CLK_ENABLE();
__RCC_GPIOC_CLK_ENABLE();
__RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.IT = GPIO_IT_NONE; //LED
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pins = GPIO_PIN_7|GPIO_PIN_8;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_Init(CW_GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pins = GPIO_PIN_13; // LED4
GPIO_Init(CW_GPIOC, &GPIO_InitStruct);
GPIO_WritePin(CW_GPIOA,GPIO_PIN_7|GPIO_PIN_8,GPIO_Pin_RESET); //LED灯拉高
GPIO_WritePin(CW_GPIOC,GPIO_PIN_13,GPIO_Pin_RESET);
}
见文末视频,LED2闪烁两次,LED3才会闪烁一次,而且是按照预定时间闪烁,实验成功。
使用KEIL集成的CMSIS-FreeRTOS移植FreeRTOS简直是事半功倍。只需要话费很少的时候就可以完成移植,极大地提高了效率。
后边就可以使用freeRTOS愉快的玩耍了。
更多回帖