使用STM32CubeMX 配置Freertos 生成一个任务点亮LED
stm32cubemx
STM32CubeMX 是 ST 意法半导体近几年来大力推荐的STM32 芯片图形化配置工具, 允许用户使用图形化向导生成C 初始化代码,可以大大减轻开发工作,时间和费用。STM32CubeMX几乎覆盖了STM32 全系列芯片。
1.新建项目文件
2.本例子需要使用到的外设只有GPIO点亮LED
LED端口为PC13 ,点击PC13选择GPIO_OUTPUT
配置GPIO端口为输出。
3.配置Freertos
选择middleware ,点击freertos interface 选择CMSISV1 或者V2
选择task and Queue,点击add
在出现的对话框中对任务进行设置,若无其他需求可以点击确定使用默认配置。
点击project manager
设置项目名称,目录
tool-Chain选择MDK-ARM(如果你用keil5开发的话)
勾选code Generator 如图所示的条目
点击生成代码。
使用MDK 打开所创建的项目(刚才设了项目目录)
打开main.c
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Call init function for freertos objects (in freertos.c) */
MX_FREERTOS_Init();
/* Start scheduler */
osKernelStart();
/* We should never get here as control is now taken by the scheduler */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
/*Configure GPIO pin : PC13 */
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}
以上是自动生成的main函数
在函数 MX_FREERTOS_Init(); 中是对用户函数的初始化,也就是创建任务阶段。
这里会比较晕,和freertos 内核代码的样式会有很大区别,都是CMSIS定义的又包一层。
void MX_FREERTOS_Init(void) {
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* USER CODE BEGIN RTOS_MUTEX */
/* add mutexes, ... */
/* USER CODE END RTOS_MUTEX */
/* USER CODE BEGIN RTOS_SEMAPHORES */
/* add semaphores, ... */
/* USER CODE END RTOS_SEMAPHORES */
/* USER CODE BEGIN RTOS_TIMERS */
/* start timers, add new ones, ... */
/* USER CODE END RTOS_TIMERS */
/* USER CODE BEGIN RTOS_QUEUES */
/* add queues, ... */
/* USER CODE END RTOS_QUEUES */
/* Create the thread(s) */
/* definition and creation of defaultTask */
osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
/* definition and creation of myTask02 */
osThreadDef(myTask02, StartTask02, osPriorityIdle, 0, 128);
myTask02Handle = osThreadCreate(osThread(myTask02), NULL);
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
/* USER CODE END RTOS_THREADS */
}
osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
使用宏定义创建了一个任务结构体,对结构体进行初始化。
#define osThreadDef(name, thread, priority, instances, stacksz) \
const osThreadDef_t os_thread_def_##name = \
{ #name, (thread), (priority), (instances), (stacksz)}
os_pthread pthread; ///< start address of thread function
这个就是函数的入口
defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
这行目的是把刚才创建的任务结构体带入到任务的创建函数中
osThreadCreate 调用Freertos 的任务创建函数。
StartDefaultTask
StartTask02
一个是系统默认创建的任务,一个是我们STM32CubeMX中创建的任务。
在我们创建的函数中加入LED翻转
void StartTask02(void const * argument)
{
/* USER CODE BEGIN StartTask02 */
/* Infinite loop */
for(;;)
{
osDelay(300);
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
}
/* USER CODE END StartTask02 */
}