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

本文介绍了利用switch-case结构和定时器实现带超时机制的工步执行模式,特别关注了一个S7-200SMART自由口通信超时处理的实例,展示了如何通过定时器控制工步执行间隔和处理超时情况。
摘要由CSDN通过智能技术生成

前言

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

流程图

image

代码模式

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时使用的一个实例 S7-200 SMART 自由口通信超时处理实例

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 timeout\n");
			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中判断触发条件后才会执行相应工步。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Java中实现超时机制可以使用线程、ExecutorService或FutureTask等方式。以下是一个使用线程实现的超时机制示例代码: ```java import java.util.concurrent.TimeUnit; public class TimeoutThread extends Thread { private Thread targetThread; private long timeoutMillis; public TimeoutThread(Thread targetThread, long timeoutMillis) { this.targetThread = targetThread; this.timeoutMillis = timeoutMillis; } public void run() { try { Thread.sleep(timeoutMillis); targetThread.interrupt(); } catch (InterruptedException e) { // Timeout thread was interrupted, do nothing } } } ``` 在上面的示例代码中,我们创建了一个TimeoutThread类,该类继承了Thread类,并带有一个Thread类型的targetThread成员变量和一个long类型的timeoutMillis成员变量。我们还实现了run()方法,在该方法中使用Thread.sleep()方法等待指定的超时时间,然后中断目标线程。 为了使用超时机制,我们需要在目标线程中启动TimeoutThread线程,并在目标线程执行任务的代码块中进行轮询,以检查是否已经超时。以下是一个使用超时机制的示例代码: ```java public class TimeoutExample { public static void main(String[] args) { Thread taskThread = new Thread(() -> { // Perform some long-running task try { Thread.sleep(5000); System.out.println("Task completed successfully."); } catch (InterruptedException e) { System.out.println("Task was interrupted."); } }); TimeoutThread timeoutThread = new TimeoutThread(taskThread, 3000); timeoutThread.start(); taskThread.start(); while (taskThread.isAlive()) { try { Thread.sleep(100); } catch (InterruptedException e) { // Do nothing } } } } ``` 在上面的示例代码中,我们首先创建一个目标线程taskThread,在该线程中执行一些长时间运行的任务。然后,我们创建一个TimeoutThread线程timeoutThread,并在其中传递目标线程taskThread和超时时间3000毫秒。接下来,我们启动timeoutThread和taskThread,并在主线程中进行轮询,以检查目标线程是否已经完成。如果目标线程已经完成,则退出轮询循环。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值