一、實驗
實驗目的:學會使用FreeRTOS的中斷管理
創建兩個定時器,一個優先級為4,另一個優先級為6;注意:系統所管理的優先級范圍 :5~15
現象:兩個定時器每1s,打印一段字符串,當關中斷時,停止打印,開中斷時持續打印。?
實驗設計:創建兩個任務:start_task、task1
2個任務的功能如下:
start_task:用于創建task1任務
task1:中斷測試任務,任務中將調到用關中斷和開中斷函數來體現對中斷的管理。
代碼:
main.c
#include "stm32f10x.h"
#include "FreeRTOS.h"
#include "task.h"
#include "freertos_demo.h"
#include "Delay.h"
#include "sys.h"
#include "usart.h"
#include "Timer.h"
#include "delay.h"int main(void){ uart_init(9600);Timer_Init();delay_init();// 創建任務FrrrRTOS_Demo();
}
freertos_demo.c
#include "FreeRTOS.h"
#include "task.h"
#include "usart.h"
#include "Timer.h"
#include "delay.h"/******************************************************************任務配置****************************************************/
//任務優先級
#define START_TASK_PRIO 1
//任務堆棧大小
#define START_TASK_STACK_SIZE 64
//任務句柄
TaskHandle_t StartTask_Handler;
//任務函數
void start_task(void *pvParameters);//任務優先級
#define TASK1_PRIO 2
//任務堆棧大小
#define TASK1_STACK_SIZE 64
//任務句柄
TaskHandle_t Task1_Handler;
//任務函數
void task1(void *pvParameters);/******************************************************************任務函數****************************************************/
void FrrrRTOS_Demo(void)
{//創建開始任務xTaskCreate((TaskFunction_t )start_task, //任務函數( char* )"start_task", //任務名稱(uint16_t )START_TASK_STACK_SIZE, //任務堆棧大小(void* )NULL, //傳遞給任務函數的參數(UBaseType_t )START_TASK_PRIO, //任務優先級(TaskHandle_t* )&StartTask_Handler); //任務句柄 // 啟動任務調度vTaskStartScheduler();
}void start_task(void *pvParameters)
{taskENTER_CRITICAL(); //進入臨界區//創建LED0任務xTaskCreate((TaskFunction_t )task1, (const char* )"task1", (uint16_t )TASK1_STACK_SIZE, (void* )NULL, (UBaseType_t )TASK1_PRIO, (TaskHandle_t* )&Task1_Handler); vTaskDelete(StartTask_Handler); //刪除開始任務taskEXIT_CRITICAL(); //退出臨界區
}// 任務1函數
void task1(void *pvParameters)
{uint8_t task1_num = 0;while(1){if(++task1_num == 5){task1_num = 0;printf("關中斷\r\n");portDISABLE_INTERRUPTS();delay_xms(5000); //不可以使用vTaskDelay()函數:因為此函數會在內部開啟中斷引起任務切換printf("開中斷\r\n");portENABLE_INTERRUPTS();}vTaskDelay(1000);}
}
Timer.c
#include "stm32f10x.h" // Device header
#include "usart.h"void Timer_Init(void)
{//RCC打開時鐘RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);//選擇時基單元的時鐘,內部時鐘一般默認初始化可以寫可以不寫TIM_InternalClockConfig(TIM2);TIM_InternalClockConfig(TIM3);//配置時基單元TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//TIM_CKD_DIV1代表1分屏TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//代表向上計數TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;//72MHZ分頻7200,就是10k,10k計10000個數就是1sTIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;//高級定時器才有,現在是通用定時器給0TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);//如果不加入這一句,會導致復位之后從1開始計數TIM_ClearFlag(TIM2, TIM_FLAG_Update);TIM_ClearFlag(TIM3, TIM_FLAG_Update);//TIM_IT_Update代表更新中斷,中斷控制,用來控制某個中斷能不能通往NIVCTIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_Init(&NVIC_InitStructure);NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 15; //新版RTOS可管理的NVIC中斷:11~15NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_Init(&NVIC_InitStructure);//啟動定時器TIM_Cmd(TIM2, ENABLE);TIM_Cmd(TIM3, ENABLE);
}void TIM2_IRQHandler(void)
{if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){printf("優先級4\r\n");TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}
}void TIM3_IRQHandler(void)
{if (TIM_GetITStatus(TIM3, TIM_IT_Update) == SET){printf("優先級15\r\n");TIM_ClearITPendingBit(TIM3, TIM_IT_Update);}
}
二、實驗現象
三、重點?
開中斷和關中斷函數:
portDISABLE_INTERRUPTS(); //關中斷
portENABLE_INTERRUPTS(); //開中斷
關中斷之后不能使用vTaskDelay()函數,此函數中會打開中斷。(Delay函數不能使用的可以找找我的文章,有專門修改后適用于FreeRTOS操作系統的延遲函數)
FreeRTOS可管理的中斷優先級,版本不一樣,可管理的優先級就不一樣;
是由FreeRTOSConfig.h文件里面的宏決定:
#define configKERNEL_INTERRUPT_PRIORITY 255 ?// 內核中斷優先級(最低優先級)
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 191 ?// 允許調用 FreeRTOS API 的最高中斷優先級(優先級 11)
//可管理的中斷優先級:11 到 15
?適用于STM32F103C8T6項目帶注釋完整的FreeRTOSConfig.h文件:
/** FreeRTOS V202212.01* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.** Permission is hereby granted, free of charge, to any person obtaining a copy of* this software and associated documentation files (the "Software"), to deal in* the Software without restriction, including without limitation the rights to* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of* the Software, and to permit persons to whom the Software is furnished to do so,* subject to the following conditions:** The above copyright notice and this permission notice shall be included in all* copies or substantial portions of the Software.** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.** https://www.FreeRTOS.org* https://github.com/FreeRTOS**/#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H// 如果需要支持操作系統,可以取消注釋以下宏定義
//#define SYSTEM_SUPPORT_OS 1/*-----------------------------------------------------------* 應用程序特定的定義。** 這些定義應根據您的硬件和應用程序需求進行調整。** 這些參數在 FreeRTOS API 文檔的“配置”部分中有詳細描述,* 文檔可在 FreeRTOS.org 網站上找到。** 參見 http://www.freertos.org/a00110.html*----------------------------------------------------------*/// 將 FreeRTOS 的中斷處理函數映射到 CMSIS 標準的中斷處理函數
#define xPortPendSVHandler PendSV_Handler // PendSV 中斷處理函數
//#define xPortSysTickHandler SysTick_Handler // SysTick 中斷處理函數(注釋掉,使用自定義的 SysTick_Handler)
#define vPortSVCHandler SVC_Handler // SVC 中斷處理函數// 啟用獲取當前任務句柄的 API
#define INCLUDE_xTaskGetCurrentTaskHandle 1/*-------------------------------- FreeRTOS 內核配置 --------------------------------*/
#define configUSE_PREEMPTION 1 // 啟用搶占式調度
#define configUSE_IDLE_HOOK 0 // 禁用空閑任務鉤子函數
#define configUSE_TICK_HOOK 0 // 禁用時鐘節拍鉤子函數
#define configCPU_CLOCK_HZ ( ( unsigned long ) 72000000 ) // CPU 時鐘頻率,72MHz
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) // 系統節拍頻率,1000Hz(1ms 一個節拍)
#define configMAX_PRIORITIES ( 5 ) // 最大任務優先級數
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 ) // 空閑任務的最小堆棧大小
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 17 * 1024 ) ) // 系統堆的總大小,17KB
#define configMAX_TASK_NAME_LEN ( 16 ) // 任務名稱的最大長度
#define configUSE_TRACE_FACILITY 0 // 禁用可視化跟蹤調試功能
#define configUSE_16_BIT_TICKS 0 // 使用 32 位 Tick 計數器
#define configIDLE_SHOULD_YIELD 1 // 空閑任務在有同等優先級的用戶任務時主動讓出 CPU/*-------------------------------- FreeRTOS API 包含配置 --------------------------------*/
// 以下宏定義用于控制是否包含特定的 FreeRTOS API 函數
#define INCLUDE_vTaskPrioritySet 1 // 包含任務優先級設置函數
#define INCLUDE_uxTaskPriorityGet 1 // 包含獲取任務優先級函數
#define INCLUDE_vTaskDelete 1 // 包含任務刪除函數
#define INCLUDE_vTaskCleanUpResources 0 // 不包含任務資源清理函數
#define INCLUDE_vTaskSuspend 1 // 包含任務掛起函數
#define INCLUDE_vTaskDelayUntil 1 // 包含絕對延時函數
#define INCLUDE_vTaskDelay 1 // 包含相對延時函數
#define INCLUDE_vTaskResumeFromISR 1 // 包含從中斷恢復任務函數
#define INCLUDE_xTaskGetSchedulerState 1 // 包含獲取調度器狀態函數/*-------------------------------- 中斷優先級配置 --------------------------------*/
/*-------------------------------- 可管理的中斷優先級:11 到 15(對應 NVIC 優先級 191 到 255) --------------------------------*/// Cortex-M3/M4 的 NVIC 中斷優先級配置
#define configKERNEL_INTERRUPT_PRIORITY 255 // 內核中斷優先級(最低優先級)
// configMAX_SYSCALL_INTERRUPT_PRIORITY 不能設置為 0
// 參見 http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 191 // 允許調用 FreeRTOS API 的最高中斷優先級(優先級 11)// STM32 庫使用的中斷優先級范圍是 0-15,15 對應最低優先級 255
#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 15 // 內核中斷優先級(最低優先級)#endif /* FREERTOS_CONFIG_H */