FreeRTOS作業系統學習
文章目錄
- FreeRTOS作業系統學習
- 前言
- 一、中斷管理
- 二、FreeRTOS中斷測驗實驗
- 1.代碼實戰
- 總結
前言
中斷是微控制器一個很常見的特性,中斷由硬體產生,當中斷產生以后 CPU 就會中斷當前
的流程轉而去處理中斷服務,Cortex-M 內核的 MCU 提供了一個用于中斷管理的嵌套向量中斷
控制器(NVIC), Cotex-M3 的 NVIC 最多支持 240 個 IRQ(中斷請求)、1 個不可屏蔽中斷(NMI)、1 個 Systick(滴
答定時器)定時器中斷和多個系統例外,
一、中斷管理

臨界區:
臨界段代碼也叫做臨界區,是指那些必須完整運行,不能被打斷的代碼段,比如有的外設
的初始化需要嚴格的時序,初始化程序中不能被打斷,FreeRTOS 在進入臨界段代碼的時候需要
關閉中斷,當處理完臨界段代碼以后再打開中斷,FreeRTOS 系統本身就有很多的臨界段代碼,
這些代碼都加了臨界段代碼保護,我們在寫自己的用戶程式的時候有些地方也需要添加臨界段
代碼保護,
FreeRTOS 與 臨 界 段 代 碼 保 護 有 關 的 函 數 有 4 個 : taskENTER_CRITICAL() 、taskEXIT_CRITICAL() 、 taskENTER_CRITICAL_FROM_ISR() 和
taskEXIT_CRITICAL_FROM_ISR(),這四個函式其實是宏定義,在 task.h 檔案中有定義,這四個函式的區別是前兩個是任務級的臨界段代碼保護,后兩個是中斷級的臨界段代碼保護,
void taskcritical_test(void)
{
while(1)
{
taskENTER_CRITICAL(); (1)//進入臨界區
total_num+=0.01f;
printf("total_num 的值為: %.4f\r\n",total_num);
taskEXIT_CRITICAL(); (2)//退出臨界區
vTaskDelay(1000);
} }
(1)、進入臨界區,
(2)、退出臨界區,
(1)和(2)中間的代碼就是臨界區代碼,注意臨界區代碼一定要精簡!因為進入臨界區會關閉中斷,這樣會導致優先級低于 configMAX_SYSCALL_INTERRUPT_PRIORITY 的中斷得不到及
時的回應!
只有所有的臨界段代碼都退出以后才會使能中斷!
最低中斷優先級15、最高中斷優先級5
0-4不歸FreeRTOS管理,5-15FreeRTOS可管理

二、FreeRTOS中斷測驗實驗
本實驗設計了兩個任務 start_task()和 interrupt_task(), 這兩個任務的任務功能如下:
start_task():創建另外一個任務,interrupt_task() : 中 斷 測 試 任 務 , 任 務 中 會 調 用 FreeRTOS 的 中 斷 函 數portDISABLE_INTERRUPTS()來將中斷關閉一段時間,
1.代碼實戰



#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "timer.h"
#include "FreeRTOS.h"
#include "task.h"
//è???ó??è??
#define START_TASK_PRIO 1
//è???????′óD?
#define START_STK_SIZE 256
//è?????±ú
TaskHandle_t StartTask_Handler;
//è???oˉêy
void start_task(void *pvParameters);
//è???ó??è??
#define INTERRUPT_TASK_PRIO 2
//è???????′óD?
#define INTERRUPT_STK_SIZE 256
//è?????±ú
TaskHandle_t INTERRUPTTask_Handler;
//è???oˉêy
void interrupt_task(void *p_arg);
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//éè???μí3?D??ó??è??·?×é4
delay_init(); //?óê±oˉêy3?ê??ˉ
uart_init(115200); //3?ê??ˉ′??ú
LED_Init(); //3?ê??ˉLED
TIM3_Int_Init(10000-1,7200-1); //3?ê??ˉ?¨ê±?÷3£??¨ê±?÷?ü?ú1S
TIM5_Int_Init(10000-1,7200-1); //3?ê??ˉ?¨ê±?÷5£??¨ê±?÷?ü?ú1S
//′′?¨?aê?è???
xTaskCreate((TaskFunction_t )start_task, //è???oˉêy
(const char* )"start_task", //è?????3?
(uint16_t )START_STK_SIZE, //è???????′óD?
(void* )NULL, //′?μY??è???oˉêyμ?2?êy
(UBaseType_t )START_TASK_PRIO, //è???ó??è??
(TaskHandle_t* )&StartTask_Handler); //è?????±ú
vTaskStartScheduler(); //?a??è???μ÷?è
}
//?aê?è???è???oˉêy
void start_task(void *pvParameters)
{
taskENTER_CRITICAL(); //??è?áù????
//′′?¨?D??2aê?è???
xTaskCreate((TaskFunction_t )interrupt_task, //è???oˉêy
(const char* )"interrupt_task", //è?????3?
(uint16_t )INTERRUPT_STK_SIZE, //è???????′óD?
(void* )NULL, //′?μY??è???oˉêyμ?2?êy
(UBaseType_t )INTERRUPT_TASK_PRIO, //è???ó??è??
(TaskHandle_t* )&INTERRUPTTask_Handler); //è?????±ú
vTaskDelete(StartTask_Handler); //é?3y?aê?è???
taskEXIT_CRITICAL(); //í?3?áù????
}
//?D??2aê?è???oˉêy
void interrupt_task(void *pvParameters)
{
static u32 total_num=0;
while(1)
{
total_num+=1;
if(total_num==5)
{
portDISABLE_INTERRUPTS(); //1?±??D??
delay_xms(5000); //?óê±5s
portENABLE_INTERRUPTS();
}
LED0=~LED0;
vTaskDelay(1000);
}
}
總結
FreeRTOS中斷,使用時5-15是FreeRTOS可控的中斷,數字越大優先級越低,使用中斷時加入臨界區,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/413982.html
標籤:其他
下一篇:物聯網入門——零成本學習
