基于工步执行的附加超时机制的一种模式

前言

该模式主体是一个switch-case结构,所谓工步即为case常量表达式的值,一般为数字常量,也成为显性工步;通过default这一特殊机制,实现隐性工步的执行;而每一工步所执行的间隔就需要定时器来控制,这也是实现超时机制的方法。
这种模式还可以衍生出其他的模式,灵活性很大,总体上像是一个多路复用的模式,而我在这里只介绍一种结合定时器实现带超时机制的工步执行方法。

流程图

基于工步执行的附加超时机制的一种模式

代码模式

if(Flag_10ms){//10ms 执行间隔     swtich(step){         case 1:{             //do something             break;}         case 2:{break;}         case 3:{break;}          case timeout1:{//超时终止工步值,根据需求调节             //do someting             break;         }         case timeout2:{//多级超时             //do someting             break;         }         default:{             //if ... 判断可选工步执行条件(超时工步除外)             step = 1; //触发相应可选工步             timeout = 0             //else             step = timeout_start+(timeout++)          }     } }  

一个实例

这是在做CAN Bootloader时使用的一个实例

void CAN_Loader(void){ 	static uint8_t step=0,timeout=0; 	uint32_t tmp_cmd = 0,tmp_addr = 0; 	switch(step){  		case 1:{ //工步1 			 			tmp_cmd = join_u8_buf_to_u32(CAN0_Rx_Msg.Data); 			switch(tmp_cmd){ 				case CMD_RESET:{ 					break; 				} 				case CMD_UPDATE_APP:{ 					step = 3; //跳转工步 					break; 				} 				 				default:{ 					step = 4; //超时起始工步值,隐性工步 					break; 				} 			} 			 			break; 		} 		case 2:{ //工步2 			step = 4; 			break; 		} 		case 3:{ //工步3 			//do something 			step = 4; 		} 		case 200:{//超时功能(about 4s 			printf("someting is timeoutn"); 			step = 0; 			timeout = 0; 			break; 		} 		default:{ //默认工步,即隐性执行工步,由于触发显性工步的条件判断  			if((CAN0_MSG_OBJ.CAN_Msg_Vailed_Flag == CAN0_MSG_VALID) ||  				(CAN0_MSG_OBJ.CAN_Msg_Vailed_Flag == CAN0_MSG_BUSY)){//条件判断  				if(Cmd_Status == CMD_STATUS_NULL) step = 1;//跳转工步 				else if(Enable_Update_Flag) step = 3;//跳转工步 				CAN0_MSG_OBJ.CAN_Msg_Vailed_Flag = CAN0_MSG_NULL; 				timeout = 0;//超时计数清零 			}else { 				step = 4+(timeout++);//超时计数 				 			} 			break; 		} 	} } 

step为什么不从0开始,因为考虑到习惯上初始化时为0,所以就不要工步为0了。

总结

这种方式,虽然简单、灵活、易于扩展与延伸,但是有一个明显的缺点,就是除超时机制是以执行间隔来运行的,但是其他工步执行的间隔要2倍的执行间隔,因为需要在default中判断触发条件后才会执行相应工步。

发表评论

评论已关闭。

相关文章