[英]Arrival-time handling with wrap around in C
我目前正在Ansi-C中编写一个软件,并且正在努力获得一个基本功能。
该软件将通过CAN网络接收消息,当这些消息到达时,我需要确保它们在预期时间之前和之前的消息之后交付。
只允许使用无符号变量,因此当定时器达到最大值时会出现问题(在我的情况下为255)。
由于我知道两条消息之间的最长时间,因此很容易验证消息是否在预期时间之前到达。
此示例处理环绕并发现迟到的消息:
UC_8 arrival = 250;
UC_8 expected = 15;
UC_8 maxInterArrTime = 30;
result = expected - arrival;
if(result <= maxInterArrTime){
// ON TIME!
}
else{
// DELAYED
}
这是一个简单的部分,但我还必须检查到达的消息实际上是在上一条消息之后到达的。 我的问题是我不知道如何用环绕问题来解决这个问题。 我试图模仿找到延迟消息的解决方案,但没有任何运气。
UC_8 arrival = 10; // Wrapped around
UC_8 lastArrival = 250;
UC_8 expected = 15;
UC_8 maxInterArrTime = 30;
result = expected - arrival;
result2 = lastArrival - arrival; //Problem
if(result2 >= ???){ // How should I compare and with what?
//Message received after previous msg
if(result <= maxInterArrTime){
// ON TIME!
}
else{
// DELAYED
}
else{
//Message received before previous msg - ERROR
}
我的问题是当到达时间值低于前一个到达时间,但实际上是“更大”,因为它已经缠绕。 我想我可能需要做几步。
有什么建议我怎么解决这个? 我需要保持if语句的数量很少,代码将被分析复杂性和其他东西。
如果您可以保证数据包之间的延迟不会超过256或更多,那么以下内容将考虑环绕
if (newerTime >= olderTime)
delay = newerTime - olderTime;
else
delay = 256 - olderTime + newerTime;
如果你不能保证延迟小于256,那么展开是正确的,你不能做你想做的事情。
咦? 你不能用神奇的方式围绕一个缺少信息的情况。 如果您只有8位无符号时间戳,那么您将无法区分3个刻度前发生的事情和259个刻度之前发生的事情,依此类推。
考虑使更大(更多位)的时间戳可用。
如果可以确保时间增量的绝对值小于最大可测量时间跨度的1/2,则可以确定时间增量。
int8_t delta_u8(uint8_t a, uint8_t b) {
int8_t delta = a - b;
return delta;
}
...
delta = delta_u8(newerTime, olderTime);
delay = abs( (int) delta ); // or you could have a byte version of abs, since
// I suspect that you may be doing embedded stuff
// and care about such things.
如果你能确保时间总是向前发展,那么你可以做得更好。 随着时间的推移,我的意思是在你的情况下, newerTime
总是大于olderTime
,无论它们在数字上如何比较。 在这种情况下,您可以测量最大可测量时间跨度的增量 - 这实在不言而喻。
uint8_t delta_i8(uint8_t a, uint8_t b) {
return a - b;
}
如果你知道在相同的时间段内不能发生两个事件你可以做得更好1.如果你知道两个事件不能发生在一起比一定时间更近,那么你可以计算到最大时间跨度的增量可以通过时间戳+事件之间必须存在的时间量来表示,但是您必须使用更大的可变大小来进行实际数学运算。
所有这些都是有效的,因为当你对它们进 您可以非常轻松地将此视为将已知时间值中的一个转换为新原点(0)并调整其他时间值以匹配此移位。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.