本文将介绍: a. 创建任务 b. 任务执行 c. 挂起任务和恢复任务 d. 在一定状态停止任务一段时间
附录: 如何在STM32CubeIDE中加入printf打印 解决STM32CubeIDE 用串口printf 进入hardfault
配置STM32CubeIDE,把vTaskDelayUntil 设置为Enabled
创建任务 分三部: 2.1 创建任务ID 2.2 使用osThreadDef定义线程 2.3 创建线程并将ID分配给任务处理程序。 参照01_FreeRTOS 任务优先级。
任务执行 osDelay()会让当前的线程进入阻塞模式,到时间后就会退出阻塞模式。比如Task2 中延时2s Task1 中延时1s,所以当Taks2进入阻塞状态,Task1此时优先级最高运行一次后,Task1也进入阻塞状态,过去1s后再次运行Task1。当过去2s,两个Task都退出阻塞状态,此时由于Task2的优先级要比Task1的优先级高,故开始先运行Task2。如此往复。
优先级定义部分:
/* definition and creation of Task1 */ osThreadDef(Task1, Task1_init, osPriorityNormal, 0, 512); Task1Handle = osThreadCreate(osThread(Task1), NULL); /* definition and creation of Task2 */ osThreadDef(Task2, Task2_init, osPriorityAboveNormal, 0, 512); Task2Handle = osThreadCreate(osThread(Task2), NULL);printf部分:
uint8_t indx = 0; void send_task1(void){ printf("task1 running...\n"); } void send_task2(void){ printf("task2 indx= %d \n ",indx ++); }输出结果:
挂起任务和恢复任务当Task被挂起后,它一直处于挂起状态,用osThreadSuspend函数挂起一个Task,参数是线程ID,用osThreadResume退出挂起状态。 在Task2 入口函数加入:
void Task2_init(void const * argument) { /* USER CODE BEGIN Task2_init */ /* Infinite loop */ for(;;) { send_task2(); osDelay(2000); if (indx==4) { printf ("suspending Task1Handle\n"); osThreadSuspend(Task1Handle); } if (indx ==7) { printf ("Resuming Task1Handle\n"); osThreadResume(Task1Handle); indx = 0; } } /* USER CODE END Task2_init */ }输出结果:
停止任务一段时间用 osDelayUntil (uint32_t *PreviousWakeTime, uint32_t millisec)函数来实现,PreviousWakeTime指向开始停止的时候。
Task入口函数:
/* USER CODE END Header_Task2_init */ void Task2_init(void const * argument) { /* USER CODE BEGIN Task2_init */ /* Infinite loop */ for(;;) { send_task2(); osDelay(2000); if(indx == 5) { uint32_t PreviousWakeTime = osKernelSysTick(); osDelayUntil(&PreviousWakeTime, 4000); } } /* USER CODE END Task2_init */ }结果:
如何在STM32CubeIDE中加入打印串口printf
只需要在main.c中加入如下部分就可以实现串口printf:
// 把这部分加入主函数初始化中
/* 禁用STDOUT流的I/O 缓冲,以便在打印字符时立即发送。*/ setvbuf(stdout, NULL, _IONBF, 0);// …
/* USER CODE BEGIN 0 */ #include "errno.h" #include "stdio.h" #define STDIN_FILENO 0 #define STDOUT_FILENO 1 #define STDERR_FILENO 2 int _write(int file, char* ptr, int len) { /* 禁用STDOUT流的I/O 缓冲,以便在打印字符时立即发送。*/ if (file == STDOUT_FILENO || file == STDERR_FILENO) { HAL_StatusTypeDef hstatus; hstatus = HAL_UART_Transmit(&huart1, (uint8_t *) ptr, len, HAL_MAX_DELAY); if (hstatus == HAL_OK) return len; else return EIO; } errno = EBADF; return -1; } /* USER CODE END 0 */解决STM32CubeIDE 用串口printf 进入hardfault
分析:由于给Task分配的堆栈太小。 把堆栈加大到512,并且先要在main中执行一次printf才行,否则直接Hard Fault异常。 如图:
STM32CubeIDE其他设置,进入Project->Properties,如下设置: 即可使用printf向串口1打印数据。
Code下载地址