FreeRTOS中断内使用taskENTER_CRITICAL()进入临界区

项目背景:

1、电机转速是20000RPM ,电机转一圈触发4次中断,中断中有一个全局变量pulse_count进行累加动作

2、在任务中,会清零这个全局变量,并且读取该变量,判断这个变量是不是达到了指定圈数;

操作:

在pulse_count++操作前加taskENTER_CRITICAL()不加这条进入进入临界区

现象:

加了taskENTER_CRITICAL(),系统异常,比如打断点后,没有按照想象的流程走;

分析:

该外部中断GPIO_EXIT优先级是5,正好能够调用FreeRTOS的API函数

  • configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY = 5:可以安全调用FreeRTOS API的最高中断优先级

SysTick的中断优先级是15,最低优先级;

考虑到以下:

  • 在32位处理器上,64位变量的读取和写入操作不是原子的,需要两个32位操作来完成

所以想在pulse_count++上面添加taskENTER_CRITICAL()操作;确保原子操作;

中断触发频率:

结论:

复制代码
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if(GPIO_Pin == Motor_FG_IT_Pin)
	{

		//taskENTER_CRITICAL();  // 进入临界区 我草 不能加这个代码
        pulse_count++;
        //taskEXIT_CRITICAL();   // 退出临界区
	}

}

unsigned char task(unsigned char quanNum)
{
	static unsigned int begintime = 0;
	static unsigned int delaytime = 0;
	unsigned char ret = 1;
	uint32_t count_to_print = 0;
	
	switch(Step)
	{
		case 0:
				begintime = GetCurTick();
				delaytime = 2000;//时间
				__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, 0);//低电平全速
		    
                taskENTER_CRITICAL();// 进入临界区后再操作共享变量
				pulse_count = 0;
				Step++;
		        taskEXIT_CRITICAL(); // 操作完成后立即退出临界区
				ret = 1;
				//debug_printf("beg SongSi\r\n");
			break;
		
		case 1://pulse_count++ 加了taskENTER_CRITICAL后,不进这里中断,感觉整个任务调度都出问题了
				if(GetTickDly(begintime)>delaytime)
				{
					__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, 100);//高电平停止
					
					taskENTER_CRITICAL();
					Step = 0;
					taskEXIT_CRITICAL();
					ret = 0;
				}
				
				taskENTER_CRITICAL();
				if(pulse_count >= quanNum*4)
				{ 
					count_to_print = g_uTimesCount;
					__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, 100);//高电平停止
					pulse_count = 0;
					Step = 0;
					ret = 0;
				}
				taskEXIT_CRITICAL();
			break;
		
		default:
			break;
	}
	return ret;
}
相关推荐
qq_672592757 小时前
电源芯片为什么发热
单片机·嵌入式硬件
天天爱吃肉82187 小时前
【跨界封神|周杰伦×王传福(陶晶莹主持):音乐创作与新能源NVH测试,底层逻辑竟完全同源!(新人必看入行指南)】
python·嵌入式硬件·算法·汽车
国科安芯8 小时前
抗辐照MCU在精密时频系统中的单粒子效应评估与可靠性验证
单片机·嵌入式硬件·架构·制造·安全性测试
森焱森8 小时前
嵌入式硬件工程师应知 白银快速分析报告
linux·c语言·arm开发·嵌入式硬件·去中心化
czhaii8 小时前
单片机最佳入门多线程示例讲解
c语言·单片机
BackCatK Chen18 小时前
第 8 篇:TMC2240 电机正反转实现|DIR 引脚控制 + 代码优化(稳定不抖动)
stm32·单片机·嵌入式硬件·保姆级教程·电机正反转·tmc2240·dir引脚控制
星马梦缘19 小时前
EDA彩灯电路绘制
单片机·嵌入式硬件·物联网·pcb·eda·嘉立创
Forsete21 小时前
LINUX驱动开发#9——定时器
linux·驱动开发·单片机
Hello_Embed1 天前
libmodbus 移植 STM32(USB 串口后端篇)
笔记·stm32·单片机·嵌入式·freertos·libmodbus
VekiSon1 天前
Linux内核驱动——杂项设备驱动与内核模块编译
linux·c语言·arm开发·嵌入式硬件