Atmel AVR sleep mode and Sleep Enable bit handling - avr

I am trying to understand how to program avr in event-based model, where it reacts to what is going around it.
After reading my chip (ATmega16a) manual and googling I still can't find exact answer to my question.
Both avr-libc manuals I found http://www.atmel.com/webdoc/AVRLibcReferenceManual/group__avr__sleep.html and http://www.nongnu.org/avr-libc/user-manual/group__avr__sleep.html insist on that it is recommended to enable sleep mode (set SE bit) right before entering sleep and disable it afterwards (by clearing SE). What purpose serves this bit-shuffling? Why can't I just enable sleep mode once at the reset and then freely enter it by just executing 'sleep' instruction where it is needed?

You can just enable sleep mode once at the reset and then freely enter sleep.
By clearing the SE bit you can prevent sleeping in situations when you need.

Related

OpenOCD debugging Stops after STM32 Sleep

When debugging the STM32 with OpenOCD and GDB, OpenOCD does not continue to debug when the MCU wakes up from STOP mode.
I have the following code which sleeps the MCU for 10 seconds and then wakes it up:
uint32_t seconds = 10;
uint32_t counter = (uint32_t)(seconds * 1000) / 0.488;
HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, counter,
RTC_WAKEUPCLOCK_RTCCLK_DIV16);
HAL_SuspendTick();
HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI);
SystemClock_Config();
HAL_ResumeTick();
do_stuff():
When I use the STM32CubeIDE with ST's Programmer, it works as expected. The debugging process continues to the next line after the MCU wakes up.
With OpenOCD and GDB and stays stuck at
Continuing.
halted: PC: 0x080010f0
How can I make it behave similar to the ST debugger, where it continues debugging after sleep?
I use the following line to start the OpenOCD session:
openocd -f interface/stlink-v2.cfg -f target/stm32f4x.cfg
You have to enable debugger STOP-mode support. Quote from the reference manual:
The core does not allow FCLK or HCLK to be turned off during a debug
session. As these are required for the debugger connection, during a
debug, they must remain active. The MCU integrates special means to
allow the user to debug software in low-power modes. For this, the
debugger host must first set some debug configuration registers to
change the low-power mode behavior:
• In Sleep mode, DBG_SLEEP bit of DBGMCU_CR register must be
previously set by the debugger. This will feed HCLK with the same
clock that is provided to FCLK (system clock previously configured by
the software).
• In Stop mode, the bit DBG_STOP must be previously set by the
debugger. This will enable the internal RC oscillator clock to feed
FCLK and HCLK in STOP mode
From description of the DBGMCU_CR register.
Bit 1 DBG_STOP: Debug Stop mode
0: (FCLK=Off, HCLK=Off) In STOP mode, the clock controller disables all clocks (including HCLK and FCLK). When exiting from STOP
mode, the clock configuration is identical to the one after RESET (CPU
clocked by the 8 MHz internal RC oscillator (HSI)). Consequently, the
software must reprogram the clock controller to enable the PLL, the
Xtal, etc.
1: (FCLK=On, HCLK=On) In this case, when entering STOP mode, FCLK and HCLK are provided by the internal RC oscillator which remains
active in STOP mode. When exiting STOP mode, the software must
reprogram the clock controller to enable the PLL, the Xtal, etc. (in
the same way it would do in case of DBG_STOP=0)
I think HAL_DBGMCU_EnableDBGStopMode() function is resposible for this register. But you may need to check the exact library version you using.
Probably STProgrammer modifies this bit silently.

Recommended way to break out of a Watchdog Timer (WDT) supported main loop

I need to include hardware WDTs on both ESP32 and rp Pico based systems running micropython. I am using the Thonny IDE and with an 8s timeout on the Pico I can interrupt (Cntrl-C) the system and quickly delete the main from the board. This then allows me to continue development of the code. This approach works with an 8s timeout but if I was working with much shorter delays I am not so sure that it would. My concern is getting stuck with a main.py I can't change? Is there a better way anyone can recommend to handle this.
Harry
PS: Relative beginner with Python. The more I know, the more I know I don't!
What works for me: add time.sleep() for 5 seconds in the beginning of your code where you can kill script from Thonny using CTRL+C before WDT has been initiated. This way you dont need to delete file manually from board, you just stop it's execution before WDT

How to disable sleep in MacOS while processing program is running?

I created a digital full screen Clock in Processing. I also created a executable file to run it directly via double click. My OS is MacOS High Sierra. When I run it, my laptop goes to sleep after some time. I want to disable sleeping while my clock is running. Is there a programming way to do this.
One option would be to use Amphetamine to do this. It's not programmatic though, which might not be possible from Processing (unless you can do Objective C style calls).

Kernel panic error in ARM board

I have ARM board at remote location. Some time I had a kernel panic error in it. At this same time there is no option to hardware restart. bus no one is available at this place to restart it.
I want to restart my board automatically after kernel panic error. so what to do in kernel.
If your hardware contains watchdog timer, then compile the kernel with watchdog support and configure it. I suggest to follow this blog http://www.jann.cc/2013/02/02/linux_watchdog.html
Caution :: I never tried this. If the problem is solved, request you to update here.
You can modify the panic() function kernel/panic.c to call the kernel_restart(*cmd) at the point you want it to restart (like probably after printing the required debug information).
I am assuming you are bringing up a board, so Please note that you need to supply the ops for the associated functions in machine_restart() - (called by kernel_restart) in accordance to the MACH . If you are just using the board as is , then i guess rebuilding the kernel with kernel_restart(*cmd) should do.
The panic() is usually due to events that the kernel can not recover from. If you do not have a watchdog, you need to look at your hardware to see if a GPIO, etc is connected to the RESET line. If so, you can toggle this pin to reboot the CPU. Trying to alter panic() may just make things worse, depending on the root cause and the type of features you use.
You may hook arm_pm_restart with your custom restart functionality. You can test it with the shell command reboot, if present. panic() should call the same routine. With current ARM Linux versions
You may wish to turn off the MMU and block interrupts in this routine. It will make it more resilient when called from panic(). As you are going to reset, you can copy the routine to any physical address you like.
The watchdog maybe better; it may catch cases where even panic() may not be called. You may have a watchdog and not realize it. Many Cortex-A CPUs, have one built in. It is fairly rare for hardware not to have a watchdog.
However, if you don't have the watchdog, you can use the GPIO mechanism above; hardware should usually provide someway for software to restart the device (and peripherals). The panic() maybe due to some mis-behaving device tromping memory, latched up DRAM/Flash, etc. Toggling a RESET line maybe better than a watchdog in this case; if the RESET is also connected to other hardware, besides the CPU.
Related: How to debug kernel freeze, How to change watchdog timer
AFAIK, a simple way to restart the board after kernel panic is to pass a kernel parameter (from the bootloader usually)
panic=1
The board will then auto-reboot '1' second(s) after a panic.
Search the Documentation for more.
Some examples from the documentation:
...
panic= [KNL] Kernel behaviour on panic: delay <timeout>
timeout > 0: seconds before rebooting
timeout = 0: wait forever
timeout < 0: reboot immediately
Format: <timeout>
...
oops=panic Always panic on oopses. Default is to just kill the
process, but there is a small probability of
deadlocking the machine.
This will also cause panics on machine check exceptions.
Useful together with panic=30 to trigger a reboot.
...
As suggested in previous comments watchdog timer is your friend here. If your hardware contains watchdog timer, Enable it in kernel option and configure it.
Other alternative is use Phidget. If you usb connection available at remote location. Phidget controller/software is used to control your board using USB. Check for board support.

Debugging kernel hang

I am trying to run an app which is using a kernel mode driver. System locks up every hour and the only way to recover it is a hard reset. Sysrq stops responding, telnet sessions hang and there are no error messages of any kind. Unfortunately the board does not have ejtag support. I have been trying to isolate it functionally, but this is like looking for a needle in a hay stack. Any suggestions?
PS: This is a mips linux system (2.6.31).
Here are some options, depending on the specifics on your situation. If you can provide more detail about the platform and nature of the kernel mode driver it would be helpful.
Assuming you have reason to be confident in the hardware, your likely sources of lockups are locking problems in the kernel, uninitialized variables, and infinite loops with preemption disabled.
Can you configure a timer interrupt to run periodically and blink a LED? You might find it useful to see if interrupts continue to be handled while in a lockup.
Enable soft lockup detection in the Linux kernel hacking menu, and any other relevant kernel hacking features. It may take Linux a minute or two detect and report a soft lockup. Have you waited long enough to check for this?
Enable lock dependency checking in kernel hacking, and fix any reported locking errors in your driver.
Try changing the kernel preemption mode. This changes the behaviour of some system locks, in some cases turning deadlocks into less harmful locks. If it's relevant/possible, disable SMP.
Unfortunately without sysreq operating, or some way of poking the underlying system, you are out of luck.
If you can get some behavior out of the system (perhaps a hardware watchdog?), I would recommend kdump.
Furthermore, if this is a more recent problem, start by bisecting the code of the driver to determine where the crash is occurring.
If the kernel isn't totally hung and you are still getting interrupts, you might be able to use KGDB.
If you can't do that, you could add more logging code to your driver to track down the source of the problem. I'd put a printk() on every function's entry at a minimum and probably on every exit of each function as well. That should at least help you find out where the problem is happening.

Resources