print message in chSysHalt

Use this forum for requesting small changes in ChibiOS. Large changes should be discussed in the development forum. This forum is NOT for support.
Thargon
Posts: 135
Joined: Wed Feb 04, 2015 5:03 pm
Location: CITEC, Bielefeld University, germany
Has thanked: 15 times
Been thanked: 24 times
Contact:

print message in chSysHalt

Postby Thargon » Tue Feb 05, 2019 10:41 am

Hi,

when running ChibiOS in debug mode, I would like to get a human readable message if a sanity check (i.e. chDbgCheck or chDbgAssert) fails. So far I used the CH_CFG_SYSTEM_HALT_HOOK, which is called at the very end of the chSysHalt() function and accessed the UART LLD directly from within the hook. This solution, however, is not feasible anymore as I ported my system to another MCU, which implements a different UART LLD (my solution obviously is platform dependent :( ). Unfortunately I cannot use the SerialDriver abstraction, since it depends on interrupts, which are disabled at the beginning of chSysHalt() before the hook is called.
A straight forward solution would be to introduce another hook "CH_CFG_SYS_HALT_INTRO(reason)", which is called at the beginning of chSysHalt(). I dislike the idea of introducing so many hooks, though, so maybe you have a better idea?

Background info - my use case:
I've developed some software, which is used by several people now and hence new issues arise. Those people, however, just want to use my system but develop their own stuff. They usually don't have the resources for in-depth debugging so I need a way for them to easily tell me what kind of error occurred. As a result, I simply print out unique error messages. I know that delaying a kernel panic is not essentially a good thing to do, but in my development case that would be ok.

Thanks for your advice!
- Thomas

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: print message in chSysHalt

Postby Giovanni » Tue Feb 05, 2019 11:28 am

Hi,

You should definitely NOT use any system API (RT, NIL, HAL, OSAL) from hooks, what you need to do is to add a low level output function using polled mode.

When you get in chSysHalt() the system is dead, do not assume anything working, you should not trust even stack.

Giovanni

Thargon
Posts: 135
Joined: Wed Feb 04, 2015 5:03 pm
Location: CITEC, Bielefeld University, germany
Has thanked: 15 times
Been thanked: 24 times
Contact:

Re: print message in chSysHalt

Postby Thargon » Tue Feb 05, 2019 1:13 pm

Hi,

thanks for the quick response (as always) :)

Giovanni wrote:You should definitely NOT use any system API (RT, NIL, HAL, OSAL) from hooks, what you need to do is to add a low level output function using polled mode.
I don't exactly get your idea about a low level output function. I think that is what I did before (using the UART LLD on a register level), but that is not portable. If course I could write an according function for each port, but I'd rather use a platform independent approach, if possible.

Giovanni wrote:When you get in chSysHalt() the system is dead, do not assume anything working, you should not trust even stack.
But in chSysHalt() there is still the reason string (the argument), which is copied to ch.dbg.panic_msg. So can I trust this data at least? That string and an access function for the UART is all I need.

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: print message in chSysHalt

Postby Giovanni » Tue Feb 05, 2019 1:22 pm

You can trust the parameter to point to valid data.

If you want to write a very safe handler then you should adopt a disaster-recovery approach. Jump in an asm code where you setup a temporary stack pointer (or not use stack at all), perform your recovery/logging action then stop.

chSysHalt() is called when bad things already happened and you cannot trust the system any more. Using any kind of API would mean trusting system integrity to some degree.

By low level I mean writing on the UART data register and poll the status register. You may start the serial driver before the disaster so you could assume the UART already clocked and initialized.

The right approach depends on you safety requirements.

Giovanni

electronic_eel
Posts: 77
Joined: Sat Mar 19, 2016 8:07 pm
Been thanked: 17 times

Re: print message in chSysHalt

Postby electronic_eel » Tue Feb 05, 2019 10:04 pm

Writing to UART registers is obviously very system dependant and would need something like HAL to work on different architectures.

As performance, resource efficiency and the like are completely irrelevant when the system has crashed:
Why not use a pure software UART with bitbanging and busy loops for delay?

A software uart just for transmitting is easy. To make it portable across platforms you just need one register address and bitmask to set the output pin to 1 or zero. You'd also need a delay matched to controller clock and baudrate. Both could for example be done with a define or the like. This is much easier than adapting code to correctly access the different kinds of hardware uarts between different controller series and manufacturers.

Thargon
Posts: 135
Joined: Wed Feb 04, 2015 5:03 pm
Location: CITEC, Bielefeld University, germany
Has thanked: 15 times
Been thanked: 24 times
Contact:

Re: print message in chSysHalt

Postby Thargon » Tue Feb 12, 2019 10:22 am

Many thanks for your advice!

I though about what you wrote and decided to distinguish between kernel checks and application checks. The former are assumed to be critical system failures so such event will not print messages anymore, but stop the system immediately (ChibiOS default). Application checks, on the other hand, print an error message and "kill" the according thread. This is okay, because in my environment normal users are not supposed to use S- and I-class functions at all but stay above my custom abstraction layer and interfaces.

Anyway, maybe you could think about some interface, that allows to transmit some bytes over an I/O interface of choice after everything has been shut down. Bitbanging would be completely fine ;) I think about something like:
  1. assert failed
  2. kernel panics (calls chSysHalt() and terminates execution)
  3. send message X via interface Y
  4. do {} while(1);


Return to “Small Change Requests”

Who is online

Users browsing this forum: No registered users and 3 guests