当前位置:   article > 正文

STM32基于HAL库和STM32CubeMX的实时操作系统FreeRtOS开发_freertos hal库

freertos hal库

一、基础概念

1、FreeRTOS

RTOS是一类操作系统,µC/OS,FreeRTOS,RTX,RT-Thread 等这些都是RTOS 类的操作系统

FreeRTOS 是众多RTOS 类操作系统中的一种,FreeRTOS 十分的小巧,可以在资源有限的微控制器中运行,FreeRTOS 也不仅仅局限于在微控制器中使用。就单从文件数量上来看FreeRTOS 要比µC/OS 少得多。

RTOS是实时操作系统,例如汽车的操控:必须要在规定时间内完成响应。我们日常使用的Windows、IOS、Android等都是非实时操作系统,这些系统对任务响应时间没有严格要求,例如网页打开时可能会很久或者直接闪退等。

RTOS的最大特征就是“实时性”。所有实时操作系统中都要包含一个实时任务调度器,这个任务调度器与其它操作系统的最大不同是强调严格按照优先级来分配CPU时间。

FreeRTOS 操作系统是一个功能强大的RTOS 操作系统,并且能够根据需求进行功能裁剪,
以满足各种环境的要求、高效、开源、免费。

2、单片机编程的系统概念

a、裸机系统,包括轮询系统(不包括中断)和前后台系统(中断为前台,轮询为后台)
在顺序执行后台程序的时候,如果有中断来临,那么中断会打断后台程序的正常执行流,转而去执行中断服务程序,在中断服务程序里面标记事件,如果事件要处理的事情很简短,则可在中断服务程序里面处理,如果事件要处理的事情比较多,则返回到后台程序里面处理。虽然事件的响应和处理是分开了,但是事件的处理还是在后台里面顺序执行的,但相比轮询系统,前后台系统确保了事件不会丢失,再加上中断具有可嵌套的功能,这可以大大的提高程序的实时响应能力。在大多数的中小型项目中,前后台系统运用的好,堪称有操作系统的效果。

b、多任务系统
相比前后台系统,多任务系统的事件响应也是在中断中完成的,但是事件的处理是在任务中完成的。在多任务系统中, 任务跟中断一样,也具有优先级,优先级高的任务会被优先执行。当一个紧急的事件在中断被标记之后,如果事件对应的任务的优先级足够高,就会立马得到响应。相比前后台系统,多任务系统的实时性又被提高了。

在裸机系统中,程序的主体是 CPU 按照顺序执行的。而在多任务系统中, 任务的执行是由系统调度的。

3、FreeRTOS编程风格


数据类型
在 FreeRTOS 中, 使用的数据类型虽然都是标准 C 里面的数据类型,但是针对不同的处理器,对标准 C 的数据类型又进行了重定义,给它们取了一个新的名字, 比如 char 重新定义了一个名字 portCHAR, 这里面的 port 表示接口的意思,就是 FreeRTOS 要移植到这些处理器上需要这些接口文件来把它们连接在一起。但是用户在写程序的时候并非一定要遵循 FreeRTOS 的风格, 我们还是可以直接用 C 语言的标准类型。在 FreeRTOS 中, int 型从不使用, 只使用 short 和 long型。 在 Cortex-M 内核的 MCU 中, short 为 16 位, long 为 32位。

FreeRTOS 中详细的数据类型重定义在 portmacro.h 这个头文件中实现

58a8a6fffbdf43b8a291e32ec5279f05.png

二、Cubemx创建工程

1.创建任务

89b4c84ca7fb4e9fbc23fe5edd113e22.png

8e117f3dc02649e5aa916ea002aa47a7.png

任务名执行任务的名称
优先级类似于中断优先级,共7个等级
栈空间根据自己需要的空间决定占空间大小
进入函数名任务要执行的函数名,cubemx自动生成
任务类型有静态生成和动态生成,初学者默认就好

 

2.创建队列

8ea734bee4284bda8fb76404d537eccf.png

队列名队列的名称
队列长度队列的长度,根据自己需要设定
队列元素类型队列所存储的数据类型,根据自己需要设定

 

3.创建信号量和互斥量

adf4d674f2ad4283aef98b09bb50d17e.pngec7ca2a1756849498c6ae7934f626b95.png

4.时钟源设置

当使用了FreeRtos的时候,强烈建议HAL库使用除了Systick以外的时钟源。

防止在高优先级(优先级高于systick)中断服务中调用HAL_Delay(),导致中断服务忙等待,这样任何优先级低于该中断的中断都得不到服务。

把HAL库的时钟源设置为TIM1

51e89ad7e41f4f4b8a5ac3b61e1e3d2d.png

9824f8d485c544ab8a77505dec12578b.png

以上步骤完成后,配置好自己需要使用的外设,就可以生成代码了。

三.简单的代码解析(请看注释)

1.main.h

  1. int main(void)
  2. {
  3. HAL_Init();
  4. SystemClock_Config();
  5. /*硬件初始化*/
  6. MX_GPIO_Init();
  7. MX_DMA_Init();
  8. MX_TIM2_Init();
  9. MX_TIM3_Init();
  10. MX_USART1_UART_Init();
  11. MX_USART2_UART_Init();
  12. MX_USB_Device_Init();
  13. MX_CRC_Init();
  14. MX_SPI1_Init();
  15. MX_SPI2_Init();
  16. MX_SPI3_Init();
  17. MX_SPI4_Init();
  18. MX_TIM4_Init();
  19. /* 调用任务初始化函数 */
  20. MX_FREERTOS_Init();
  21. /* 开启调度器 */
  22. osKernelStart();
  23. /* 任务调度器开启后,就不会进入while循环了,自己的应用代码在app_freertos.c中实现 */
  24. /* Infinite loop */
  25. while (1)
  26. {
  27. }
  28. }

2.app_freertos.c

  1. /*初始化函数*/
  2. void MX_FREERTOS_Init(void) {
  3. /* 创建线程 */
  4. /* definition and creation of defaultTask */
  5. osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
  6. defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
  7. /* definition and creation of cpu */
  8. osThreadDef(cpu, cpuTask02, osPriorityIdle, 0, 128);
  9. cpuHandle = osThreadCreate(osThread(cpu), NULL);
  10. /* definition and creation of dataProceTask */
  11. osThreadDef(dataProceTask, dataProce, osPriorityIdle, 0, 128);
  12. dataProceTaskHandle = osThreadCreate(osThread(dataProceTask), NULL);
  13. }
  14. /*线程函数1,在这里实现自己的功能,注意任务优先级和栈空间!!!!!!!!!!!*/
  15. void StartDefaultTask(void const * argument)
  16. {
  17. /* USER CODE BEGIN StartDefaultTask */
  18. /* Infinite loop */
  19. for(;;)
  20. {
  21. osDelay(1);
  22. }
  23. /* USER CODE END StartDefaultTask */
  24. }
  25. /*线程函数2,在这里实现自己的功能,注意任务优先级和栈空间!!!!!!!!!!!*/
  26. void cpuTask02(void const * argument)
  27. {
  28. /* USER CODE BEGIN cpuTask02 */
  29. /* Infinite loop */
  30. for(;;)
  31. {
  32. osDelay(1);
  33. }
  34. /* USER CODE END cpuTask02 */
  35. }
  36. /*线程函数3,在这里实现自己的功能,注意任务优先级和栈空间!!!!!!!!!!!*/
  37. void dataProce(void const * argument)
  38. {
  39. /* USER CODE BEGIN dataProce */
  40. /* Infinite loop */
  41. for(;;)
  42. {
  43. osDelay(1);
  44. }
  45. /* USER CODE END dataProce */
  46. }

作者水平有限,欢迎提出意见,进行指正。

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/719448
推荐阅读
相关标签
  

闽ICP备14008679号