FreeRTOS中断管理及中断测试实验(三)

FreeRTOS学习


前言

Cotex-M3 的 NVIC 最多支持 240 个 IRQ(中断请求)、1 个不可屏蔽中断(NMI)、1 个 Systick(滴
答定时器)定时器中断和多个系统异常。


提示:以下是本篇文章正文内容,下面案例可供参考

一、中断管理

一、优先级分组(区分)
在这里插入图片描述
如果使用 ALIENTEK 的基础例程的话默认配置的组 2,所以在将基础例程中的外设驱动移
植到 FreeRTOS 下面的时候需要修改优先级配置。主要是 FreeRTOS 的中断配置没有处理亚优
先级这种情况,所以只能配置为组 4,直接就 16 个优先级,使用起来也简单!
二、FreeRTOS开关中断
在这里插入图片描述
FreeRTOS 开关中断函数为 *portENABLE_INTERRUPTS ()*和 portDISABLE_INTERRUPTS()
这两个函数其实是宏定义,在 portmacro.h 中有定义,如下:

#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
#define portENABLE_INTERRUPTS() vPortSetBASEPRI(0)

三、临界段代码
临界段代码也叫做临界区,是指那些必须完整运行,不能被打断的代码段,比如有的外设
的初始化需要严格的时序,初始化过程中不能被打断。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);
} }

注意临界区代码一定要精简!(因为进入临界区会关闭中断,这样会导致优先级低于 configMAX_SYSCALL_INTERRUPT_PRIORITY的中断得不到及时响应 )
只有所有的临界段代码都退出以后才会使能中断
四、
在这里插入图片描述
最低中断优先级15、最高中断优先级5
0-4不归FreeRTOS管理,5-15FreeRTOS可管理

二、中断测试实验

1.实验要求

在这里插入图片描述

2.相关代码

问题:

在这里插入图片描述
注意:这里的delay_xms()不会引起任何任务调度,建议不使用vTaskDelay();

主要代码

在这里插入图片描述

#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
//ÈÎÎñ¶ÑÕ»´óС	
#define START_STK_SIZE 			256  
//ÈÎÎñ¾ä±ú
TaskHandle_t StartTask_Handler;
//ÈÎÎñº¯Êý
void start_task(void *pvParameters);

//ÈÎÎñÓÅÏȼ¶
#define INTERRUPT_TASK_PRIO		2
//ÈÎÎñ¶ÑÕ»´óС	
#define INTERRUPT_STK_SIZE 		256  
//ÈÎÎñ¾ä±ú
TaskHandle_t INTERRUPTTask_Handler;
//ÈÎÎñº¯Êý
void interrupt_task(void *p_arg);

int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//ÉèÖÃϵͳÖжÏÓÅÏȼ¶·Ö×é4	 
	delay_init();	    				//ÑÓʱº¯Êý³õʼ»¯	 
	uart_init(115200);					//³õʼ»¯´®¿Ú
	LED_Init();		  					//³õʼ»¯LED
	TIM3_Int_Init(10000-1,7200-1);		//³õʼ»¯¶¨Ê±Æ÷3£¬¶¨Ê±Æ÷ÖÜÆÚ1S
	TIM5_Int_Init(10000-1,7200-1);		//³õʼ»¯¶¨Ê±Æ÷5£¬¶¨Ê±Æ÷ÖÜÆÚ1S
	
	//´´½¨¿ªÊ¼ÈÎÎñ
    xTaskCreate((TaskFunction_t )start_task,            //ÈÎÎñº¯Êý
                (const char*    )"start_task",          //ÈÎÎñÃû³Æ
                (uint16_t       )START_STK_SIZE,        //ÈÎÎñ¶ÑÕ»´óС
                (void*          )NULL,                  //´«µÝ¸øÈÎÎñº¯ÊýµÄ²ÎÊý
                (UBaseType_t    )START_TASK_PRIO,       //ÈÎÎñÓÅÏȼ¶
                (TaskHandle_t*  )&StartTask_Handler);   //ÈÎÎñ¾ä±ú              
    vTaskStartScheduler();          //¿ªÆôÈÎÎñµ÷¶È
}

//¿ªÊ¼ÈÎÎñÈÎÎñº¯Êý
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //½øÈëÁÙ½çÇø
    //´´½¨ÖжϲâÊÔÈÎÎñ
    xTaskCreate((TaskFunction_t )interrupt_task,  			//ÈÎÎñº¯Êý
                (const char*    )"interrupt_task", 			//ÈÎÎñÃû³Æ
                (uint16_t       )INTERRUPT_STK_SIZE,		//ÈÎÎñ¶ÑÕ»´óС
                (void*          )NULL,						//´«µÝ¸øÈÎÎñº¯ÊýµÄ²ÎÊý
                (UBaseType_t    )INTERRUPT_TASK_PRIO,		//ÈÎÎñÓÅÏȼ¶
                (TaskHandle_t*  )&INTERRUPTTask_Handler); 	//ÈÎÎñ¾ä±ú
	vTaskDelete(StartTask_Handler); //ɾ³ý¿ªÊ¼ÈÎÎñ
    taskEXIT_CRITICAL();            //Í˳öÁÙ½çÇø
}

//ÖжϲâÊÔÈÎÎñº¯Êý 
void interrupt_task(void *pvParameters)
{
	static u32 total_num=0;
    while(1)
    {
		total_num+=1;
		if(total_num==5) 
		{
			portDISABLE_INTERRUPTS();				//¹Ø±ÕÖÐ¶Ï  
			delay_xms(5000);						//ÑÓʱ5s
			portENABLE_INTERRUPTS();
		}
        LED0=~LED0;
        vTaskDelay(1000);
    }
}

总结

今天学了比较重要的中断管理以及中断优先级设置时注意的一些小细节,真不错~
继续加油!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值