FreeRTOS中斷管理
什麼是中斷?
中斷優先順序分組設定
不同時發生具有相同搶佔優先順序的兩個中斷時,順序執行
中斷相關暫存器
每個地址儲存8位
FreeRTOS如何配置PendSV和Systick中斷優先順序?
FreeRTOS中斷管理實驗
程式碼
btim.c
/**
****************************************************************************************************
* @file btim.c
* @author 正點原子團隊(ALIENTEK)
* @version V1.0
* @date 2021-10-15
* @brief 基本定時器 驅動程式碼
* @license Copyright (c) 2020-2032, 廣州市星翼電子科技有限公司
****************************************************************************************************
* @attention
*
* 實驗平臺:正點原子 探索者 F407開發板
* 線上影片:www.yuanzige.com
* 技術論壇:www.openedv.com
* 公司網址:www.alientek.com
* 購買地址:openedv.taobao.com
*
* 修改說明
* V1.0 20211015
* 第一次釋出
*
****************************************************************************************************
*/
#include "./BSP/LED/led.h"
#include "./BSP/TIMER/btim.h"
#include "./SYSTEM/usart/usart.h"
TIM_HandleTypeDef g_timx_handler; /* 定時器引數控制代碼 */
TIM_HandleTypeDef g_tim7_handler; /* 定時器引數控制代碼 */
/**
* @brief 基本定時器TIMX定時中斷初始化函式
* @note
* 基本定時器的時鐘來自APB1,當PPRE1 ≥ 2分頻的時候
* 基本定時器的時鐘為APB1時鐘的2倍, 而APB1為42M, 所以定時器時鐘 = 84Mhz
* 定時器溢位時間計算方法: Tout = ((arr + 1) * (psc + 1)) / Ft us.
* Ft=定時器工作頻率,單位:Mhz
*
* @param arr : 自動重灌值。
* @param psc : 時鐘預分頻數
* @retval 無
*/
void btim_timx_int_init(uint16_t arr, uint16_t psc)
{
g_timx_handler.Instance = BTIM_TIMX_INT; /* 定時器x */
g_timx_handler.Init.Prescaler = psc; /* 分頻 */
g_timx_handler.Init.CounterMode = TIM_COUNTERMODE_UP; /* 遞增計數模式 */
g_timx_handler.Init.Period = arr; /* 自動裝載值 */
HAL_TIM_Base_Init(&g_timx_handler);
HAL_TIM_Base_Start_IT(&g_timx_handler); /* 使能定時器x和定時器更新中斷 */
}
/* TIM7初始化函式 */
void btim_tim7_int_init(uint16_t arr, uint16_t psc)
{
g_tim7_handler.Instance = BTIM_TIM7_INT; /* 定時器x */
g_tim7_handler.Init.Prescaler = psc; /* 分頻 */
g_tim7_handler.Init.CounterMode = TIM_COUNTERMODE_UP; /* 遞增計數模式 */
g_tim7_handler.Init.Period = arr; /* 自動裝載值 */
HAL_TIM_Base_Init(&g_tim7_handler);
HAL_TIM_Base_Start_IT(&g_tim7_handler); /* 使能定時器x和定時器更新中斷 */
}
/**
* @brief 定時器底層驅動,開啟時鐘,設定中斷優先順序
此函式會被HAL_TIM_Base_Init()函式呼叫
* @param 無
* @retval 無
*/
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{
if (htim->Instance == BTIM_TIMX_INT)
{
BTIM_TIMX_INT_CLK_ENABLE(); /* 使能TIMx時鐘 */
HAL_NVIC_SetPriority(BTIM_TIMX_INT_IRQn, 6, 0); /* 搶佔6,子優先順序0 */
HAL_NVIC_EnableIRQ(BTIM_TIMX_INT_IRQn); /* 開啟ITMx中斷 */
}
if (htim->Instance == BTIM_TIM7_INT)
{
BTIM_TIM7_INT_CLK_ENABLE(); /* 使能TIM7時鐘 */
HAL_NVIC_SetPriority(BTIM_TIM7_INT_IRQn, 4, 0); /* 搶佔4,子優先順序0 */
HAL_NVIC_EnableIRQ(BTIM_TIM7_INT_IRQn); /* 開啟ITM7中斷 */
}
}
/**
* @brief 基本定時器TIMX中斷服務函式
* @param 無
* @retval 無
*/
void BTIM_TIMX_INT_IRQHandler(void)
{
HAL_TIM_IRQHandler(&g_timx_handler); /* 定時器回撥函式 */
}
/* 基本定時器TIM7中斷服務函式 */
void BTIM_TIM7_INT_IRQHandler(void)
{
HAL_TIM_IRQHandler(&g_tim7_handler); /* 定時器回撥函式 */
}
/**
* @brief 回撥函式,定時器中斷服務函式呼叫
* @param 無
* @retval 無
*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == BTIM_TIMX_INT)
{
printf("TIM6正在執行\r\n");
}
else if (htim->Instance == BTIM_TIM7_INT)
{
printf("TIM7正在執行\r\n");
}
}
btim.h
/**
****************************************************************************************************
* @file btim.h
* @author 正點原子團隊(ALIENTEK)
* @version V1.0
* @date 2021-10-15
* @brief 基本定時器 驅動程式碼
* @license Copyright (c) 2020-2032, 廣州市星翼電子科技有限公司
****************************************************************************************************
* @attention
*
* 實驗平臺:正點原子 探索者 F407開發板
* 線上影片:www.yuanzige.com
* 技術論壇:www.openedv.com
* 公司網址:www.alientek.com
* 購買地址:openedv.taobao.com
*
* 修改說明
* V1.0 20211015
* 第一次釋出
*
****************************************************************************************************
*/
#ifndef __BTIM_H
#define __BTIM_H
#include "./SYSTEM/sys/sys.h"
/******************************************************************************************/
/* 基本定時器 定義 */
/* TIMX 中斷定義
* 預設是針對TIM6/TIM7
* 注意: 透過修改這4個宏定義,可以支援TIM1~TIM8任意一個定時器.
*/
#define BTIM_TIMX_INT TIM6
#define BTIM_TIMX_INT_IRQn TIM6_DAC_IRQn
#define BTIM_TIMX_INT_IRQHandler TIM6_DAC_IRQHandler
#define BTIM_TIMX_INT_CLK_ENABLE() do{ __HAL_RCC_TIM6_CLK_ENABLE(); }while(0) /* TIM6 時鐘使能 */
#define BTIM_TIM7_INT TIM7
#define BTIM_TIM7_INT_IRQn TIM7_IRQn
#define BTIM_TIM7_INT_IRQHandler TIM7_IRQHandler
#define BTIM_TIM7_INT_CLK_ENABLE() do{ __HAL_RCC_TIM7_CLK_ENABLE(); }while(0) /* TIM7 時鐘使能 */
/******************************************************************************************/
void btim_timx_int_init(uint16_t arr, uint16_t psc); /* 基本定時器 定時中斷初始化函式 */
void btim_tim7_int_init(uint16_t arr, uint16_t psc); /* 基本定時器 定時中斷初始化函式 */
#endif
main.c
/**
****************************************************************************************************
* @file main.c
* @author 正點原子團隊(ALIENTEK)
* @version V1.0
* @date 2021-11-04
* @brief 任務掛起和恢復 實驗
* @license Copyright (c) 2020-2032, 廣州市星翼電子科技有限公司
****************************************************************************************************
* @attention
*
* 實驗平臺:正點原子 探索者 F407開發板
* 線上影片:www.yuanzige.com
* 技術論壇:www.openedv.com
* 公司網址:www.alientek.com
* 購買地址:openedv.taobao.com
*
****************************************************************************************************
*/
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
#include "./BSP/SRAM/sram.h"
#include "./MALLOC/malloc.h"
#include "freertos_demo.h"
#include "./BSP/TIMER/btim.h"
int main(void)
{
HAL_Init(); /* 初始化HAL庫 */
sys_stm32_clock_init(336, 8, 2, 7); /* 設定時鐘,168Mhz */
delay_init(168); /* 延時初始化 */
usart_init(115200); /* 串列埠初始化為115200 */
led_init(); /* 初始化LED */
lcd_init(); /* 初始化LCD */
key_init(); /* 初始化按鍵 */
sram_init(); /* SRAM初始化 */
btim_timx_int_init(10000-1,8400-1);
btim_tim7_int_init(10000-1,8400-1);
my_mem_init(SRAMIN); /* 初始化內部SRAM記憶體池 */
my_mem_init(SRAMEX); /* 初始化外部SRAM記憶體池 */
my_mem_init(SRAMCCM); /* 初始化內部CCM記憶體池 */
freertos_demo();
}
freertos_demo.c
/**
****************************************************************************************************
* @file freertos.c
* @author 正點原子團隊(ALIENTEK)
* @version V1.4
* @date 2022-01-04
* @brief FreeRTOS 移植實驗
* @license Copyright (c) 2020-2032, 廣州市星翼電子科技有限公司
****************************************************************************************************
* @attention
*
* 實驗平臺:正點原子 探索者F407開發板
* 線上影片:www.yuanzige.com
* 技術論壇:www.openedv.com
* 公司網址:www.alientek.com
* 購買地址:openedv.taobao.com
*
****************************************************************************************************
*/
#include "freertos_demo.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
#include "./SYSTEM/delay/delay.h"
/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
/******************************************************************************************************/
/*FreeRTOS配置*/
/* START_TASK 任務 配置
* 包括: 任務控制代碼 任務優先順序 堆疊大小 建立任務
*/
#define START_TASK_STACK_SIZE 128
#define START_TASK_PRIO 1
TaskHandle_t start_task_handler;
#define TASK1_STACK_SIZE 128
#define TASK1_PRIO 2
TaskHandle_t task1_handler;
void start_task( void * pvParameters );
void task1( void * pvParameters )
{
uint8_t task1_num = 0;
while(1)
{
if(++task1_num == 5)
{
task1_num = 0;
printf("關中斷\r\n");
portDISABLE_INTERRUPTS();
delay_ms(5000);
printf("開中斷\r\n");
portENABLE_INTERRUPTS();
}
vTaskDelay(1000);
}
}
/******************************************************************************************************/
/**
* @brief FreeRTOS例程入口函式
* @param 無
* @retval 無
*/
void freertos_demo(void)
{
xTaskCreate(start_task, "start_task", START_TASK_STACK_SIZE, NULL, START_TASK_PRIO, &start_task_handler);
vTaskStartScheduler();
}
void start_task( void * pvParameters )
{
taskENTER_CRITICAL(); //進入臨界區
xTaskCreate(task1, "task1", TASK1_STACK_SIZE, NULL, TASK1_PRIO, &task1_handler);
vTaskDelete(NULL);
taskEXIT_CRITICAL(); //退出臨界區
}