RTOS从零开始(1):从裸机转变成RTOS的思路与意义

RTOS从零开始(1)从裸机转变成RTOS的思路与意义


如有错误烦请大家指出。
======专栏地址======

一、裸机的弊端与改进
  • 轮询方式:弊端很明显,整个业务逻辑全在while中,只能顺序执行,而每个事件里都有或多或少的delay函数,导致MCU浪费很多时间空转,而且后面事件受到前面事件的运行时长影响,效率很低,实时性很差。
//程序只做大概参考
void main()
{
	while(1){
		event1();
		event2();
		...
	}
}
  • 初步改进:事件驱动方式(前后台):较轮询改善不少,受事件(中断)驱动,事件标志未触发则不会处理该事件函数,减少了很多不必要的执行时间,但是仍然不能彻底解决实时性的问题,因为某个事件标志被置位后,也不能立即就执行,还是必须等到当前事件执行结束,并且后面的事件没触发,才有机会获得执行。
//程序只做大概参考
void main()
{
	while(1){
		if(event1_flag){
			event1();
		}
		if(event2_flag){
			event2();
		}
	}
}
void event1_isr()
{
	event1_flag = 1;
}
void event2_isr()
{
	event2_flag = 1;
}
  • 二次改进:假设event1和2都是执行时间很长的函数,那可以给它们设置一个执行周期,减少因中断结束而返回的地点在其他程序执行过程中而浪费的时间,但是哪怕这样也无法绕过长时间执行的程序。
//程序只做大概参考
void main()
{
	while(1){
		event1();
		event2();
		event3();
	}
}
void event1_isr()
{
	event1_flag = 1;
}
void event2_isr()
{
	event2_flag = 1;
}
void event3_isr()
{
	event3_flag = 1;
}
void event1()
{
	static u16 cycleTime = 5;   //例如定时器1ms中断一次,则5ms处理一次event1
	if(cycleTime--)
	{
		return;
	}
	cycleTime = 5;
	if(event1_flag){
	...
	}
}
void event2()
{
	static u16 cycleTime = 10;   //例如定时器1ms中断一次,则10ms处理一次event2
	if(cycleTime--)
	{
		return;
	}
	cycleTime = 10;
	if(event2_flag){
	...
	}
}
void event3()
{
	static u16 cycleTime = 10;   
	if(cycleTime--)
	{
		return;
	}
	cycleTime = 10;
	if(event3_flag){
	...
	}
}
  • 再次改进:如果两个任务执行的时间很长,那可以用状态机思路(状态机思路在普通的嵌入式编程中尤为重要)将一个任务打散成很多段,然后切换着执行。
//程序只做大概参考
void main()
{
	while(1){
		if(event1_flag){    //1
			event1();
		}
		if(event2_flag){    //1
			event2();
		}
	}
}
void event1_isr()
{
	event1_flag = 1;
}
void event2_isr()
{
	event2_flag = 1;
}
void event1()
{
	static u8 state = 0;
	switch(state)
	{
		case(0):
		{
			state++;
			break;
		}
		case(1):
		{
			state++;
			break;
		}
		...
	}
	event1_flag = 0;
}
void event2()
{
	static u8 state = 0;
	switch(state)
	{
		case(0):
		{
			state++;
			break;
		}
		case(1):
		{
			state++;
			break;
		}
		...	
	}
	event2_flag = 0;
}
二、RTOS思维初窥

  上述方案的问题在于我们每次响应了中断后,都要返回到原来产生中断的位置继续往下执行,直到执行到该次响应中断的对应函数才执行该事件,哪怕人为的去打散任务也依旧受到前面函数的运行时间影响。

  • 最终改进思路
    在每次进入中断前,保存MCU的当前状态和数据,然后进入中断进行处理,然后完成该中断后,改变程序的返回位置,让程序不返回到刚刚产生中断的位置,而从最新获得中断标志的对应事件地址开始执行,这样就可以达到彻底的实时性。
    而这就是RTOS的作用,下面的event1/2就可以简单理解成“线程”,可以简单的把RTOS理解成,把event1和event2拆分成许多部分(时间片),通过RTOS来进行快速的切换执行。

注:单核单线程的MCU,就算用上RTOS还是无法改变芯片单线程,所谓实时系统,只是让其无限接近实时而已。

//程序只做大概参考
void main(){
	//配置RTOS
	XXRTOS_Init();
}
void event1_isr()
{
	event1_flag = 1;
}
void event2_isr()
{
	event2_flag = 1;
}
void event1()
{
	while(1){
		if(event1_flag){
		...
		}
	}
}
void event2()
{
	while(1){
		if(event2_flag){
		...
		}
	}
}
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Diode丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值