Rate limited rtapi_print_msg()?

More
10 Feb 2021 22:13 #198330 by arvidb
Is there a "standardised" way of notifying about recurring errors in code that runs at the servo thread rate? Specifically, I'd like to warn about overflow when converting from float to hal_s32_t.

I could just use rtapi_print_msg() but then it would spam the error message at 1 kHz until the machine turns off with a following error or similar. The Linux kernel has a WARN_ONCE macro - is there something similar in the LinuxCNC code base?

Please Log in or Create an account to join the conversation.

More
11 Feb 2021 19:03 #198426 by andypugh

I could just use rtapi_print_msg() but then it would spam the error message at 1 kHz until the machine turns off with a following error or similar. The Linux kernel has a WARN_ONCE macro - is there something similar in the LinuxCNC code base?


There might be such a macro, though I have not found it. (And searching the code for "ONCE" didn't find anything.)

A simple way would be to print the message and set a flag when an error occurs, and clear it on no-error.
I can also imagine a scheme where you snprintf the message to a buffer, and compare it to the last error printed (stored in a static variable somewhere)

Often a HAL component is coded as a state-machine, and those will print a message and then enter a "faulted" state, only exiting when reset or the fault clears.

Please Log in or Create an account to join the conversation.

More
12 Feb 2021 09:59 #198511 by arvidb
This is linuxcnc-ethercat and I don't think it has any fault state. (I'm trying to make it support different sets of pins and EtherCAT PDOs ("data objects") depending on configuration, e.g. to allow a drive to be configured for either position or velocity operation - which turned out to be quite tricky.)

I'll probably do something like this:
#define WARN_ONCE(format...)          \
do {                                  \
  static bool __warned;               \
                                      \
  if (!__warned) {                    \
      __warned = true;                \
      rtapi_print_msg(format);        \
  }                                   \
} while (0);

(Inspired by the macro from the Linux kernel.)

Please Log in or Create an account to join the conversation.

More
12 Feb 2021 18:29 - 12 Feb 2021 18:30 #198559 by andypugh
The problem with that is that it only prints one message. Then never prints anything again.

Here is an idea, which gives you 32 slots:
#define WARN_ONCE(slot, format...)          \
do {                                  \
  static int __warned;               \
                                      \
  if ((__warned & 1 << slot) == 0) {                    \
      __warned &= 1 << slot;                \
      rtapi_print_msg(format);        \
  }                                   \
} while (0);

Or, to only skip repeating the exact same message. (this is off-the-cuff and as-is will probably segfault). And it might be better as a function than a macro:

#define WARN_ONCE(format...)          \
do {                                  \
  static byte checksum;            \
  byte newsum;            \
  char * message[100];              \
  int i;                    \
  snprintf(message, 100, format);    \
  for (i = 0; message[i] != 0; i++) newsum += message[i]; \
  if (newsum != checksum) {                    \
      checksum = newsum;                \
      rtapi_print_msg(message);        \
  }                                   \
} while (0);
Last edit: 12 Feb 2021 18:30 by andypugh.

Please Log in or Create an account to join the conversation.

More
12 Feb 2021 21:11 #198579 by arvidb
Interesting suggestions - thanks!

In this case, I think a single warning is enough. Once you get an overflow (e.g. a position command that converts to an encoder count that doesn't fit in 32 bits) things will go south rather quickly, I guess? The important thing is that the problem isn't entirely silent (as it is today); that there is a clue in the log as to what happened. Although it would be nice to have it reset e.g. when drive enable was toggled... *hmm*

How/when would you use the slotted version?

The checksummed version would have to be a function for sure, otherwise it would work just as the "simple" version since each message would get its own checksum. Then again, if one error leads to another so that two messages were interleaved, then the function:ed version would do nothing.

Please Log in or Create an account to join the conversation.

More
12 Feb 2021 21:23 #198586 by andypugh

How/when would you use the slotted version?


I am being a bit dim, and forgetting that each instance of a macro is independent code.

The slot version would work as a function.

Please Log in or Create an account to join the conversation.

Time to create page: 0.104 seconds
Powered by Kunena Forum