Hi Peter,
> I wrote a function, specific to my sketch, which I use for just this purpose.
>
> But it has to do other things when invoked. I use it after initialization as
> well, a little like assert(), to stop a machine control process safely. (Yeah,
> I am not an educational user of Arduino.)
Right. I would say you could still do the same - just create a
safehalt() function which cleans up and then calls halt()?
My intention was not really to create a halt/reboot for use in libraries
or other generic code - but mostly to have some convenience functions
for sketches to concisely print an error and halt execution. IMHO,
libraries should never be calling halt() or reboot() in case of errors -
they should report back to the sketch and let the sketch decide what to
do.
In that regard, only the reboot() function would add something that
sketches cannot currently implement (portably) themselves, the halt
functions and reboot functions with arguments could be implemented in
the sketch itself directly. Still, I think they have added value as
convenience functions.
> So it seems to me that the halt() API needs something like the traditional C
> atexit() to register a limited number of callbacks to be invoked as part of the
> shutdown. Without this I think it would be impossible to anticipate all the
> needs that are essential to halting.
I'm afraid that adding such callbacks significantly complicates things.
Also, it seems to me that without them, the API is still useful. If it
is not sufficient, a sketch can implement their own wrappers instead.
> I assume halting means at a minimum "noInterrupts(); for (;;) continue;"
That's what I had in mind, yes.
> > reboot()
> > Reboots the Arduino. On AVR, this could use the watchdog, not
> > sure what would be suitable on SAM?
>
> I have a specific use for this on the Arduino Due.
>
> The CDC interface on the native port is substantially faster than the
> programming port, but (IIRC) doesn't have an option to reset the chip. The 1200
> bps hack resets it for programming, but I need to reset the chip without
> programming at the start of a job in my physical process to guarantee job
> integrity. I thought of doing something with the watchdog to do this but never
> was faced with a situation where I had to use the native port, so I didn't
> proceed further.
Ah, it seems that the 1200 baud trick actively configures the bootloader
to run indeed:
https://github.com/arduino/Arduino/blob/bd8f7932e64fb3a41e3d934437d5eabd8707dcc9/hardware/arduino/sam/cores/arduino/Reset.cpp#L27-L51
This reboot() API should probably not set those flags and instead just
reboot into the sketch directly.
On complication I just found, is that not all bootloaders currently
clear the watchdog flag. On AVR, this means that the watchdog
immediately triggers again after 15ms, leading to a reboot loop. In
particular, the atmega, atmega8, lilypad and bt bootloaders do not do
this. This means that the watchdog reset won't be usable on those
bootloaders (but I am not aware of any alternatives). This affects the
Diecimila, nano, mega1280, mini, fio, bt, lilypad, pro and pro mini
boards. It's a fairly trivial fix, though (which could at least fix
to-be-produced boards).
Gr.
Matthijs