Watchdog configuration on Stellaris Launchpad LM4F120 - c

I try to configure the watchdog timer on Stellaris Launchpad LM4F120.
The code is the following:
void configure_watchdog(void) {
SYSCTL_RCGCWD_R = 0x1; /* Enabling Clock for WD0 */
WATCHDOG0_LOAD_R = 0xffffffff; /* Setting initial value */
WATCHDOG0_CTL_R = WDT_CTL_INTEN; /* Enabling interrupt generation */
}
This supposed to be enough in accordance to the datasheet.
The problem is that controller always falls to FaultISR and resets after it. I can't understand why.
What am I doing wrong?
EDIT: The controller does not reset. It just goes to FaultISR

Jumping to an ISR when the watchdog expires sounds like the correct behavior. What exactly are you doing inside your ISR code? If you are resetting the watchdog inside the ISR, then you shouldn't be seeing the microcontroller reset itself (based on your posted configuration code, at least). After you set up the watchdog, read the configuration register back out and make sure that it holds the value that you expect. Some of the bits in that register can only be set under certain circumstances, and it's possible that you're not running with the settings that you think you're using.
You mentioned that you were trying to use the watchdog timer as a generic downcounter. Could you use one of the general-purpose timers instead of the watchdog? You would still get an interrupt when time expired, but regular timers don't have the ability to reset the entire system.

You have to keep servicing the watchdog, otherwise it times out and calls whatever is setup for that exception. FaultISR would appear to be that in your case.
If you want the watchdog to do something else on the timeout you need to figure out how your particular toolchain connects functions to exception sources and map your new function correctly.
If you don't want the watchdog to expire (which is usually what it's there for, to catch errant code) then you need to service it regularly. The compiler vendor often provides a function or intrinsic to do this.

Related

Watchdog timeout is too short

I have a conceptual question, I'm currently working on a project that have to implement a watchdog timer to ensure that the code works properly, I'm using a STM32F4, from the datasheet I can see that the max timeout allow by the IWDG (independent Watchdog) is 32768 ms, I'm using a SIM800L for communication via GPRS, so some communications take longer than that, during this process the UC is busy waiting for the answers, so it cannot reset the IWDG, so I was thinking on deactivating the Watchdog in those parts, or implement my own watchdog whit a timer and a simple reset function so can make longer timeout periods.
My question is:
Is this a sign of a flaw on my code design? Should I instead adapt my code to reset the IWDG every 30 seconds or so and never deactivate it? Is implementing my own WDG with a timer bad practice?
¿is this a sign of a flaw on my code design?,
¿should instead adapt my
code to renew the IWDG every 30 seconds or so?
No, you simply need to write the key register or load a new value to the downcounter before the downcounter reaches zero. It shows the watchdog that your software is alive and no reset is needed.
during this process the UC is busy waiting for the answers, so it
cannot reset the IWDG
This means that your implementation is bad. You need to implement it non-blocking way. It is not dificult.
¿implementing my own
WDG whit a timer is a bad practice?
It is a very bad idea. What will happen if your program hardfault? Your own watchdog will be useless. Hardware WDG is also clocked from its one clock source - so if your program does something wrong with the clocks - it will still work.
Programs should never deactivate the watchdog in run-time, as that defeats the purpose of having a watchdog in the first place. Many watchdog hardware peripherals don't even allow you to disable it once enabled.
You cannot implement your own watchdog using timers, because the watchdog hardware is explicitly using a different timer than what's available to the application programmer. So if your program halts for whatever reason, your timer solution will halt as well. Forget about implementing watchdogs using on-chip timers or software. You can only implement your own watchdog using a external hardware, such as a binary counter IC or monostable multivibratior IC.
Is this a sign of a flaw on my code design?
It is - you should not busy-wait for external resources to become available. Rather than
while(some_serial_bus == BUSY) {} // bad, busy wait
you should be doing:
for(;;)
{
kick_wdog();
if(some_serial_bus != BUSY) // good, polling
{
do_stuff();
}
}
When implementing the driver for the external serial bus you should provide a method to check if data is available, then allow the caller to decide whether to busy wait for that function or not. An ideal, properly written driver should never contain any busy waits nor should it contain any "sleep/delay" calls.
I don't think you can stop the IWDG once it starts (nor would you want to). I'm not familiar with the SIM800L, but your best bet would be to find a way to kick the watchdog intermittently while GPRS is operating. You want to do this in firmware, not hardware. (Don't use a HW timer to kick the WDT because if your SW crashes, the HW timer could keep doing its thing.) Alternatively, the STM32F4 also as a window watchdog (WWDG) timer you could use. You might be able to configure longer window times with the WWDG.

How can I determin if execution takes place in thread mode or if an exception is active? (ARMv7-A architecture)

I am using FreeRTOS on an ARM Cortex A9 CPU und I'm desperately trying to find out if it is possible to determin if the processor is executing a normal thread or an interrupt service routine. It is implemented in V7-a architecture.
I found some promising reference hinting the ICSR register (-> VECTACTIVE bits), but this only exist in the cortex M family. Is there a comparable register in the A family as well? I tried to read out the processor modes in the current processor status register (CPSR), but when read during an ISR I saw that the mode bits indicate supervisor mode rather than IRQ or FIQ mode.
Looks a lot like there is no way to determine in which state the processor is, but I wanted to ask anyway, maybe I missed something...
The processor has a pl390 General Interrupt Controller. Maybe it is possible to determine the if an interrupt has been triggered by reading some of it's registers?
If anybody can give me a clue I would be very greatfull!
Edit1:
The IRQ Handler of FreeRTOS switches the processor to Superviser mode:
And subsequently switches back to system mode:
Can I just check if the processor is in supervisor mode and assume that this means that the execution takes place in an ISR, or are there other situations where the kernel may switches to supervisor mode, without being in an ISR?
Edit2:
On request I'll add an overal background description of the solution that I want to achieve in the first place, by solving the problem of knowing the current execution context.
I'm writing a set of libraries for the CortexA9 and FreeRTOS that will access periphery. Amongst others I want to implement a library for the available HW timer from the processor's periphery.
In order to secure the access to the HW and to avoid multiple tasks trying to access the HW resource simultaneously I added Mutex Semaphores to the timer library implementation. The first thing the lib function does on call is to try to gain the Mutex. If it fails the function returns an error, otherwise it continouses its execution.
Lets focus on the function that starts the timer:
static ret_val_e TmrStart(tmr_ctrl_t * pCtrl)
{
ret_val_e retVal = RET_ERR_DEF;
BaseType_t retVal_os = pdFAIL;
XTtcPs * pHwTmrInstance = (XTtcPs *) pCtrl->pHwTmrInstance;
//Check status of driver
if(pCtrl == NULL)
{
return RET_ERR_TMR_CTRL_REF;
}else if(!pCtrl->bInitialized )
{
return RET_ERR_TMR_UNINITIALIZED;
}else
{
retVal_os = xSemaphoreTake(pCtrl->osSemMux_Tmr, INSTANCE_BUSY_ACCESS_DELAY_TICKS);
if(retVal_os != pdPASS)
{
return RET_ERR_OS_SEM_MUX;
}
}
//This function starts the timer
XTtcPs_Start(pHwTmrInstance);
(...)
Sometimes it can be helpful to start the timer directly inside an ISR. The problem that appears is that while the rest of function would support it, the SemaphoreTake() call MUST be changed to SemaphoreTakeFromISR() - moreover no wait ticks are supported when called from ISR in order to avoid a blocking ISR.
In order to achieve code that is suitable for both execution modes (thread mode and IRQ mode) we would need to change the function to first check the execution state and based on that invokes either SemaphoreTake() or SemaphoreTakeFromISR() before proceeding to access the HW.
That's the context of my question. As mentioned in the comments I do not want to implement this by adding a parameter that must be supplied by the user on every call which tells the function if it's been called from a thread or an ISR, as I want to keep the API as slim as possible.
I could take FreeRTOS approch and implement a copy of the TmrStart() function with the name TmrStartFromISR() which contains the the ISR specific calls to FreeRTOS's system resources. But I rather avoid that either as duplicating all my functions makes the code overall harder to maintain.
So determining the execution state by reading out some processor registers would be the only way that I can think of. But apparently the A9 does not supply this information easily unfortunately, unlike the M3 for example.
Another approch that just came to my mind could be to set a global variable in the assembler code of FreeRTOS that handles exeptions. In the portSAVE_CONTEXT it could be set and in the portRESTORE_CONTEXT it could be reset.
The downside of this solution is that the library then would not work with the official A9 port of FreeRTOS which does not sound good either. Moreover you could get problems with race conditions if the variable is changed right after it has been checked by the lib function, but I guess this would also be a problem when reading the state from a processor registers directly... Probably one would need to enclose this check in a critical section that prevents interrupts for a short period of time.
If somebody sees some other solutions that I did not think of please do not hesitate to bring them up.
Also please feel free to discuss the solutions I brought up so far.
I'd just like to find the best way to do it.
Thanks!
On a Cortex-A processor, when an interrupt handler is triggered, the processor enters IRQ mode, with interrupts disabled. This is reflected in the state field of CPSR. IRQ mode is not suitable to receive nested interrupts, because if a second interrupt happened, the return address for the first interrupt would be overwritten. So, if an interrupt handler ever needs to re-enable interrupts, it must switch to supervisor mode first.
Generally, one of the first thing that an operating system's interrupt handler does is to switch to supervisor mode. By the time the code reaches a particular driver, the processor is in supervisor mode. So the behavior you're observing is perfectly normal.
A FreeRTOS interrupt handler is a C function. It runs with interrupts enabled, in supervisor mode. If you want to know whether your code is running in the context of an interrupt handler, never call the interrupt handler function directly, and when it calls auxiliary functions that care, pass a variable that indicates who the caller is.
void code_that_wants_to_know_who_called_it(int context) {
if (context != 0)
// called from an interrupt handler
else
// called from outside an interrupt handler
}
void my_handler1(void) {
code_that_wants_to_know_who_called_it(1);
}
void my_handler2(void) {
code_that_wants_to_know_who_called_it(1);
}
int main(void) {
Install_Interrupt(EVENT1, my_handler1);
Install_Interrupt(EVENT2, my_handler1);
code_that_wants_to_know_who_called_it(0);
}

How Can I save some data before hardware reset of microcontroller?

I'm working on one of Freesacle micro controller. This microcontroller has several reset sources (e.g. clock monitor reset, watchdog reset and ...).
Suppose that because of watchdog, my micro controller is reset. How can I save some data just before reset happens. I mean for example how can I understand that where had been the program counter just before watchdog reset. With this method I want to know where I have error (in another words long process) that causes watchdog reset.
Most Freescale MCUs work like this:
RAM is preserved after watchdog reset. But probably not after LVD reset and certainly not after power-on reset. This is in most cases completely undocumented.
The MCU will either have a status register where you can check the reset cause (for example HCS08, MPC5x, Kinetis), or it will have special reset vectors for different reset causes (for example HC11, HCS12, Coldfire).
There is no way to save anything upon reset. Reset happens and only afterwards can you find out what caused the reset.
It is however possible to reserve a chunk of RAM as a special segment. Upon power-on reset, you can initialize this segment by setting everything to zero. If you get a watchdog reset, you can assume that this RAM segment is still valid and intact. So you don't initialize it, but leave it as it is. This method enables you to save variable values across reset. Probably - this is not well documented for most MCU families. I have used this trick at least on HCS08, HCS12 and MPC56.
As for the program counter, you are out of luck. It is reset with no means to recover it. Meaning that the only way to find out where a watchdog reset occurred is the tedious old school way of moving a breakpoint bit by bit down your code, run the program and check if it reached the breakpoint.
Though in case of modern MCUs like MPC56 or Cortex M, you simply check the trace buffer and see what code that caused the reset. Not only do you get the PC, you get to see the C source code. But you might need a professional, Eclipse-free tool chain to do this.
Depending on your microcontroller you may get Reset Reason, but getting previous program counter (PC/IP) after reset is not possible.
Most of modern microcontrollers have provision for Watchdog Interrupt Instead of reset.
You can configure watchdog peripheral to enable interrupt , In that ISR you can check stored context on stack. ( You can take help from JTAG debugger to check call stack).
There are multiple debugging methods available if your micro-controller dosent support above method.
e.g
In simple while(1) based architecture you can use a HW timer and restart it after some section of code. In Timer ISR you will know which code section is consuming long enough than the timer.
Two things:
Write a log! And rotate that log to keep the last 30 min. or whatever reasonable amount of time you think you need to reproduce the error. Where the log stops, you can see what happened just before that. Even in production-level devices there is some level of logging.
(Less, practical) You can attach a debugger to nearly every micrcontroller and step through the code. Probably put a break-point that is hit just before you enter the critical section of code. Some IDEs/uCs allow having "data-breakpoints" that get triggered when certain variables contain certain values.
Disclaimer: I am not familiar with the exact microcontroller that you are using.
It is written in your manual.
I don't know that specific processor but in most microprocessors a watchdog reset is a soft reset, meaning that certain registers will keep information about the reset source and sometimes reason.
You need to post more specific information on your Freescale μC for this be answered properly.
Even if you could get the Program Counter before reset, it wouldn't be advisable to blindly set the program counter to another after reset --- as there would likely have been stack and heap information as well as the data itself may also have changed.
It depends on what you want to preserve after reset, certain behaviour or data? Volatile memory may or may not have been cleared after watchdog (see your uC datasheet) and you will be able to detect a reset after checking reset registers (again see your uC datasheet). By detecting a reset and checking volatile memory you may be able to prepare your uC to restart in a way that you'd prefer after the unlikely event of a reset occurring. You could create a global value and set it to a particular value in global scope, then if it resets, check the value against it when a reset event occurs -- if it is the same, you could assume other memory may also be the same. If volatile memory is not an option you'll need to have a look at the datasheet for non-volatile options, however it is also advisable not to continually write to non-volatile memory due to writing limitations.
The only reliable solution is to use a debugger with trace capability if your chip supports embedded instruction trace.
Some devices have an option to redirect the watchdog timeout to an interrupt rather then a reset. This would allow you to write the watchdog timeout handler much like an exception handler and dump or store the stack information including the return address which will indicate the location the interrupt occurred.
However in some cases, neither solution is a reliable method of achieving your aim. In a multi-tasking environment or system with interrupt handlers, the code running when the watchdog timeout occurs may not be the process that is causing the problem.

SysTick interrupt does not fire if GDB attached before it is enabled

I have an ATSAMD21E18A micro that I am using with semi-hosting. In order for the semi-hosting to work, GDB needs to be "attached" before the first bkpt instruction. On the other hand, I have inexplicably found that the SysTick interrupt will not fire if GDB was already attached when I configured it. If I want to the SysTick interrupt to fire, I have to perform a reset (power-off via a button) and tell GDB to continue when it hasn't yet configured the micro (that is, it hasn't sent breakpoints over or anything else), and then hit Ctrl-C to initialize debugging mode after the SysTick configuration but before we get to initialise_monitor_handles.
I have verified that the start function is only copying over the relocatable data segment, zeroing the zero segment, and setting the right initial stack pointer value. We are writing our code without libraries like CMSIS.
Also I can confirm that I have no issues when the debugger is not attached (JLinkGDBServer through an Atmel SAM-ICE), besides needing to remove the semi-hosting stuff.
Also, the SysTick COUNT does still correctly count even when the interrupts themselves don't fire. Also the SysTick pending interrupt bit PENDSTSET in ICSR, is in fact set when this happens.
My code follows:
int main()
{
// enable system timer interrupt
SYS_TICK->STATUS = 0; // (CSR)
SYS_TICK->PERIOD = 48000; // (RVR) fire at 1khz for 48mhz clock
SYS_TICK->STATUS = 0b111; // use processor clock, w/ interrupt, and enabled
SYS_TICK->COUNT = 1; // (CVR) avoid high unknown value
// dumb busy loop
util_idle_ms(2000); // <<< I hit Ctrl-C to break here!
initialise_monitor_handles();
// ... more system initialization and everything else
}
I have seen some similar seeming questions here on StackOverflow, but they seemed to be too vague to get good answers.
Edit:
Here are possibly relevant register values taken during the busy loop for the run that doesn't call the SysTick handler (no hard reset, GDB attached before SysTick configured):
SYS_TICK_CSR/STATUS: 0x10007
SYS_TICK_RVR/PERIOD: 48000
SYS_TICK_CVR/COUNT: 5245 (varies of course)
NVC_ISER: 0 (and we expect this since SysTick is considered an exception, and not an interrupt)
DHCSR: 0x30003/0x1030003 (C_MASKINTS is not set; I've seen both values show up)
ICSR: 0x400f00f (it really wants to run the SysTick handler)
PRIMASK: 0
xPSR: 0x2100000f (IPSR is 0x0f/SysTick)
And for the run that calls the SysTick handler just fine (hard reset with GDB attaching after SysTick configuration):
SYS_TICK_CSR/STATUS: 0x10007
SYS_TICK_RVR/PERIOD: 48000
SYS_TICK_CVR/COUNT: 16892 (varies of course)
NVC_ISER: 0
DHCSR: 0x10003/0x1030003 (I've seen both values show up)
ICSR: 0 (SysTick handler already run)
PRIMASK: 0
xPSR: 0x2100000f
So the register values here do not yet seem to reveal anything new to me... Please help inform me of other potentially relevant registers to check!
Just for interest, the reason this is important to me is because I have gotten gprof to work on this chip, based on https://mcuoneclipse.com/2015/08/23/tutorial-using-gnu-profiling-gprof-with-arm-cortex-m/
And although I do have to hit Ctrl-C at just the right time after a hard reset, it does work like this!
Edit
I have found that I had a misunderstanding where I thought running load in GDB performed a soft reset. I have since found that although it returns execution to reset vector, various peripherals and other registers are not in fact reset. If I perform a soft reset in GDB with monitor reset then I don't need to Ctrl-C during a delay to attach GDB and both SysTick and SemiHosting will work.
The problem occurs when SysTick is configured and then load is run in GDB, without an explicit hard or soft reset. In this case, SysTick does not fire interrupts. Most of my debugging went like this, loading new code and immediately expecting it to work so I could evaluate it. Just running monitor reset is a better workaround than before, but I still would prefer to know the reason for SysTick's misbehavior!
I would visit the ARM® v6-M Architecture Reference Manual and see if you can get some direction from that. https://static.docs.arm.com/ddi0419/d/DDI0419D_armv6m_arm.pdf
Observe that state of the registers related to the Systick that you didn't include in your question. If you can't figure out the problem based on those registers, edit your question and post the register values here (the NVIC ISER, all registers related to systick config, the DHCSR, and any others you think are related). They will be the key to getting more feedback.
The Debug Halting Control and Status Register (DHCSR) has the ability to mask interrupts including the systick. Maybe this is being set by the debugger?
bit 3 of the DHCSR looks relevant
I would also check that the SYST_RVR (Systick reload value register) is being set to something sane.
I don't have the rep to comment on your question, but I'm hoping this can get you going in a productive direction :)

whether Single-shot timer stops automatically?

I'm implementing a Timer 1 (which is basically a comparator & capture timer ) in comparator mode with single-shot mode operation? There's an option for starting the timer in continuous mode too.
My question is when I start the timer in single shot mode , after it reaches a mentioned count & compares, it will generate an interrupt flag but then does it mean that the timer is also stopped?
or do I need to stop it explicitly in single -shot mode too? I think it makes sense only in continuous mode?
I'm currently checking only the generated interrupt flag & assuming the timer is stopped & clearing the interrupt flag for further operation & the n come out of my function.
however, there is a control bit in the control register of the timer which can be toggled to make it run or stop? Should I just check the bit after the interrupt flag has generated or do I need to reset this control bit too? Which means I should have an explicit function to stop the timer as well?
Additional Information -
I'm using NXP (Philips ) controller.
Thank you in advance,
Prateek
I just got to read in the NXP datasheet that yes, If any timer, started in single shot (one- shot) mode will stop automatically.
Btw, If any one of you have any explanation kindly, put it below.
Thank you.
To understand microcontroller timers, just have to first realize that there is generally just one single main timer running. When enabled, this timer counts up until it overflows and then starts over.
When you start a "hardware timer", you only set up a register with a timer value which holds the value main_timer + delay. The hardware compares this register with the main timer at every tick, and when they match, it triggers an interrupt, sets a port or whatever you have configured it to do. Typically, you'd have to set up your timer register anew after that.
More more specific answers you have to specify the MCU family and part number used. NXP has made everything from ancient 8051 to modern ARM Cortex, and the timer peripheral hardware will be different for every MCU family.

Resources