首先我们打开STM32CubeMX,建立一个新的工程,这里我用的单片机是STM32L476RCTX,点击sys,配置SWD下载模式,如下图:
点击GPIO,配置PA5为GPIO_output模式,作为我们的LED灯引脚:
点击freeRTOS,选择CMSIS_V1版本,其他保持默认即可:
接下来我们配置时钟,打开时钟配置界面,选择HSI作为系统时钟:
点击project manager,工程名我们起为test_freeRTOS,选择合适的路径,由于我们用keil编程,所以选择MDK-ARM,版本最新的V5.32:
,
点击codegenerator,在下边的红框内打勾,为每一个.c和.h文件创建独立的文件夹,这样管理起来更方便:
最后点击generate code,生成代码,我们用keil打开工程后,稍作修改,来实现一个简单的功能,即LED灯的交替闪烁:
我们打开freertos.c文件,添加一个led.h的头文件,定义一个句柄ID:
/* USER CODE BEGIN Includes */
#include "led.h"
/* USER CODE END Includes */
/* USER CODE BEGIN Variables */
osThreadId LED_Task_Handle;//定义一个任务句柄ID
/* USER CODE END Variables */
ThreadID:线程的唯一标识符,可以用来区分不同的线程。
添加一个线程:
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
osThreadDef(LED, LED_Task, osPriorityHigh, 0, 128);
LED_Task_Handle = osThreadCreate(osThread(LED), NULL);
/* USER CODE END RTOS_THREADS */
函数解析:
osThreadDef():创建一个具有函数、优先级和堆栈要求的线程定义。
LED:任务名称;
LED_Task:任务的启动函数,逻辑代码在这里边写;
osOriorityHigh:任务优先级;
0:可能的线程实例数量;
128:线程函数的堆栈大小;
osThreadCreate():创建一个线程并将其添加到活动线程中,并将其设置为READY状态。
在工程文件中新建一个led.c和led.h文件
led.c文件中LED_Task()函数即线程任务的入口,实现了LED每隔500ms翻转一次:
#include "cmsis_os.h"
#include "led.h"
#include "gpio.h"
void LED_Task(void const * argument)
{
for(;;)
{
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
osDelay(500);
}
}
led.h文件中对该函数进行了声明:
#ifndef __LED_H
#define __LED_H
void LED_Task(void const * argument);
#endif /* __LED_H */
在main函数中,有一个最重要的函数,即
osKernelStart():用来开启任务调度,之后程序就交给操作系统了,总是在中断和任务中来回切换,我们会在下一篇文章中加入串口中断,来实现多任务并发运行。