赞
踩
操作系统 (Operating System) 的本质是一个帮助用户进行功能管理的软件。操作系统运行在硬件之上,为其他工作的软件执行资源分配等管理工作。
一般称呼不使用操作系统的单片机开发方式为“裸机开发”,当进行裸机开发时,需要自己设计循环,中断,定时等功能来控制各个任务的执行顺序。而使用操作系统进行开发时,只需要创建任务,操作系统会自动按照一些特定的机制自动进行任务的运行和切换。
除了任务管理之外,操作系统还可以提供许多功能,比如各个任务之间的通信,同步,任务的堆栈管理,控制任务对重要资源的互斥访问等。
由于单片机的资源比较少,显然无法运行如Windows,MacOS等计算机操作系统,一般在单片机上运行的是经过专门设计的嵌入式实时操作系统 (RTOS)。
freeRTOS就是其中一种,其他比较常见的嵌入式实时操作系统还有uCOSⅡ,RTThread等。freeRTOS操作系统是完全免费的操作系统,具有源码公开、可移植、可裁减、调度策略灵活的特点,可以方便地移植到各种单片机上运行,并且有着庞大的社区和生态。
首先在freeRTOS的配置页面中的Configuration下,选中Tasks and Queues标签页,存在一个已经创建的默认任务为“defaultTask”,点击进入配置选项修改为如下图所示。
如果需要增加一个新任务,点击Add,就可以创建一个新的任务。
在弹出的页面中,可以配置任务名称,优先级,栈大小,入口函数等。各个参数的具体功能见下表:
设置完毕之后点击OK,就可以看到列表中多出了自己创建的任务。
在freertos.c中也可以找到修改的默认任务函数。
__weak void red_led_task(void const * argument) {
/* USER CODE BEGIN red_led_task */
/* Infinite loop */
for(;;) {
osDelay(1);
}
/* USER CODE END red_led_task */
}
由于选择了通过__weak修饰符创建一个弱函数,可以再在别处实现该任务函数。程序执行时会自动寻找到这个另外实现的任务函数。
void red_led_task(void const * argument) {
while(1) {
HAL_GPIO_WritePin(LED_R_GPIO_Port, LED_R_Pin, GPIO_PIN_SET);
osDelay(500);
HAL_GPIO_WritePin(LED_R_GPIO_Port, LED_R_Pin, GPIO_PIN_RESET);
osDelay(500);
HAL_GPIO_WritePin(LED_R_GPIO_Port, LED_R_Pin, GPIO_PIN_RESET);
osDelay(500);
}
}
由于新建了任务“LED_GREEN”,并且设置为As external,故而需要再在别处实现任务函数。程序执行时会自动寻找到实现的任务函数。
void green_led_task(void const * argument){
while(1) {
HAL_GPIO_WritePin(LED_G_GPIO_Port, LED_G_Pin, GPIO_PIN_RESET);
osDelay(500);
HAL_GPIO_WritePin(LED_G_GPIO_Port, LED_G_Pin, GPIO_PIN_SET);
osDelay(500);
HAL_GPIO_WritePin(LED_G_GPIO_Port, LED_G_Pin, GPIO_PIN_RESET);
osDelay(500);
}
}
打开freertos.c文件,在MX_FREERTOS_Init中,找到创建两个进程的代码,分别是LED_RED和LED_GREEN。可以看到要创建任务时,只需要调用osThreadDef和osThreadCreate即可,创建“LED_BLUE”任务。
/* Create the thread(s) */
/* definition and creation of LED_RED */
osThreadDef(LED_RED, red_led_task, osPriorityNormal, 0, 128);
LED_REDHandle = osThreadCreate(osThread(LED_RED), NULL);
/* definition and creation of LED_GREEN */
osThreadDef(LED_GREEN, green_led_task, osPriorityHigh, 0, 128);
LED_GREENHandle = osThreadCreate(osThread(LED_GREEN), NULL);
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
osThreadDef(LED_BLUE, blue_led_task, osPriorityHigh, 0, 128);
led_blue_handle = osThreadCreate(osThread(LED_BLUE), NULL);
/* USER CODE END RTOS_THREADS */
首先介绍osThreadDef,实际上这不是一个函数,而是一个由CMSIS提供的宏定义,用于对要创建的任务进行设置
#define osThreadDef(name, thread, priority, instances, stacksz) \
extern const osThreadDef_t os_thread_def_##name
接着通过CMSIS提供的osThreadCreate函数来创建任务
osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument);
通过以上两步,一个任务就成功创建了,创建一个名称和osThreadDef中的thread参数一致的函数,操作系统会自动找到该函数并将其作为一个进程来执行。比如声明thread为blue_led_task,则还需要执行函数void blue_led_task(void const * argument),while(1)循环中的内容为用户自己的代码。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。