用 C 语言进行到达时间处理

发布于 2024-09-08 03:37:53 字数 1084 浏览 2 评论 0原文

我目前正在用 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 语句数量,将对代码的复杂性和其他内容进行分析。

I´m currently writing a software in Ansi-C and are struggling to get one of the basic functionality to work.

The software will receive messages over a CAN-network and when these messages arrive, I need to make sure that they are delivered before a expected time and after the previous message.

Only unsigned variables are allowed to be used, so there will be problems with wrap around when the timers reach their maximum value (255 in my case).

It is easy to verify that messages arrive before the expected time, since I know the maximum time between two messages.

This example handles wrap around and discovers messages that are late:

UC_8 arrival = 250;  
UC_8 expected = 15;
UC_8 maxInterArrTime = 30;

result = expected - arrival;

if(result <= maxInterArrTime){
// ON TIME!
}
else{
// DELAYED
}

This is the easy part, but I must also check that the arrived message actually have arrived after the previous message. My problem is that I do not know how to solve this with the wrap around problem. I tried to mimic the solution that finds delayed messages, but without any luck.

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
}

My problem is when the arrival time value is lower than the previous arrival time, but is actually "larger" since it has wrapped around. I guess I might need to do it i several steps.

Any suggestions how I can solve this? I need to keep the number of if-statements low, the code will be analysed for complexity and other stuff.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

ゝ杯具 2024-09-15 03:37:53

如果您可以保证数据包之间的延迟不会达到 256 或以上,则以下内容将说明环绕

if (newerTime >= olderTime)
  delay = newerTime - olderTime;
else
  delay = 256 - olderTime + newerTime;

如果您不能保证延迟小于 256,则展开是正确的,您可以不做你想做的事。

If you can GUARANTEE that the delay between packets will not be 256 or more then the following will account for wrap around

if (newerTime >= olderTime)
  delay = newerTime - olderTime;
else
  delay = 256 - olderTime + newerTime;

If you can't guarantee the delay is less than 256 then unwind is correct, and you can't do what you want to do.

月牙弯弯 2024-09-15 03:37:53

啊?您无法神奇地通过编码来解决丢失信息的情况。如果您只有 8 位无符号时间戳,那么您将无法区分 3 个时钟周期前发生的事情和 259 个时钟周期前发生的事情,依此类推。

考虑提供更大(更多位)的时间戳。

Huh? You can't magically code your way around a case of missing information. If you only have 8-bit unsigned timestamps, then you will not be able to differentiate between something that happened 3 ticks ago, and something that happened 259 ticks ago, and so on.

Look into making larger (more bits) timestamps available.

这个俗人 2024-09-15 03:37:53

如果可以确保时间增量的绝对值小于最大可测量时间跨度的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),并调整另一个时间值以匹配此转变。

If you can ensure that the absolute value of the time delta is less than 1/2 of the maximum measurable time span then you can determine the time delta.

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.

If you can ensure that time always move forward then you can do better. By time moving forward I mean that in your case newerTime is always greater than olderTime, regardless of how they numerically compare. In this case you can measure deltas up to the maximum measurable time span -- which really goes without saying.

uint8_t delta_i8(uint8_t a, uint8_t b) {
    return a - b;
}

If you know that two events can't happen during the same tick you can do even better by 1. If you know that two events can't happen closer together than a certain amount of time then you can calculate deltas up to maximum time span representable by your time stamp + the amount of time that must be between events, but then you have to use a larger variable size to do the actual math.

All of these work because the values rap around when you do math on them. You can very easily think of this as turning one of your known time values into the new origin (0) and adjusting the other time value to match this shift.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文