FreeRTOS での操作で最も一般的なのは、タスクの作成、削除、一時停止、再開です。
この実験の目標:
1. タスク 1 を作成します。LED1 が 1 秒ごとに点滅し、シリアル ポート経由で印刷します。
2. タスク 2 を作成します。LED2 が 0.5 秒ごとに点滅し、シリアル ポート経由で印刷します。
3. タスク 3 の作成: タスク 1 から KEY1 までを作成および削除します。
ボタンを押した後、タスク 1 があればタスク 1 を削除し、タスク 1 がなければタスク 1 を作成します。
4. タスク 4 を作成します。KEY2 を通じてタスク 2 を一時停止および再開します。
ボタンを押すと、タスク 2 が実行中の場合はタスク 2 が一時停止され、タスク 2 が一時停止されたときにタスク 2 がタスク 2 を再開します。
実現方法:
時間厳守の Atom Explorer を使用し、メイン制御チップは STM32F407ZGT6 です。
1. 主な電気回路図は次のとおりです。
2、CubeMX 構成
1.FreeRTOSをセットアップする
2.usart1を設定します
ボーレート 115200
3. クロックを設定し、外部高速クロックを選択します
クロックツリーを次のように設定します
4. タイムベースを必ず変更してください
5. コードを生成する
3. コードを作成します (すべて freertos.c で記述されています)
1. シリアルポートのリダイレクト
#include <stdio.h>// 包含标准输入输出头文件
int fputc(int ch,FILE *f)
{
//采用轮询方式发送1字节数据,超时时间设置为无限等待
HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,HAL_MAX_DELAY);
return ch;
}
int fgetc(FILE *f)
{
uint8_t ch;
// 采用轮询方式接收 1字节数据,超时时间设置为无限等待
HAL_UART_Receive( &huart1,(uint8_t*)&ch,1, HAL_MAX_DELAY );
return ch;
}
2. タスクを実現するコード
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 LED1 */
osThreadDef(LED1, led1, osPriorityNormal, 0, 128);
LED1Handle = osThreadCreate(osThread(LED1), NULL);
/* definition and creation of LED2 */
osThreadDef(LED2, led2, osPriorityIdle, 0, 128);
LED2Handle = osThreadCreate(osThread(LED2), NULL);
/* definition and creation of KEY1 */
osThreadDef(KEY1, key1, osPriorityIdle, 0, 128);
KEY1Handle = osThreadCreate(osThread(KEY1), NULL);
/* definition and creation of KEY2 */
osThreadDef(KEY2, key2, osPriorityIdle, 0, 128);
KEY2Handle = osThreadCreate(osThread(KEY2), NULL);
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
/* USER CODE END RTOS_THREADS */
}
/* USER CODE BEGIN Header_led1 */
/**
* @brief Function implementing the LED1 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_led1 */
void led1(void const * argument)
{
/* USER CODE BEGIN led1 */
/* Infinite loop */
for(;;)
{
printf("led1\n\r");
HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_9);
osDelay(1000);
}
/* USER CODE END led1 */
}
/* USER CODE BEGIN Header_led2 */
/**
* @brief Function implementing the LED2 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_led2 */
void led2(void const * argument)
{
/* USER CODE BEGIN led2 */
/* Infinite loop */
for(;;)
{
printf("led2\n\r");
HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_10);
osDelay(500);
}
/* USER CODE END led2 */
}
/* USER CODE BEGIN Header_key1 */
/**
* @brief Function implementing the KEY1 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_key1 */
void key1(void const * argument)
{
/* USER CODE BEGIN key1 */
/* Infinite loop */
for(;;)
{
if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)==0)
{
osDelay(20);//防误触
if(LED1Handle==NULL)
{
printf("key1==creat\n\r");
osThreadDef(LED1, led1, osPriorityNormal, 0, 128);
LED1Handle = osThreadCreate(osThread(LED1), (void*)"new task1");
}
else
{
vTaskDelete(LED1Handle);
LED1Handle=NULL;
printf("key1==delete\n\r");
}
}
}
/* USER CODE END key1 */
}
/* USER CODE BEGIN Header_key2 */
/**
* @brief Function implementing the KEY2 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_key2 */
void key2(void const * argument)
{
/* USER CODE BEGIN key2 */
char Flag=0;
/* Infinite loop */
for(;;)
{
if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)==0)
{
osDelay(20);//防误触
if(Flag==0)
{
printf("key2 suspend\n\r");
vTaskSuspend(LED2Handle);
Flag=1;
}
else
{
vTaskResume(LED2Handle);
printf("key2 resume \n\r");
Flag=0;
}
}
}
/* USER CODE END key2 */
}
/* Private application code --------------------------------------------------*/
注: タスクが削除されてもハンドルは削除されないため、手動でクリアする必要があります。