Interrupt service routine for watchdog timer on STM32 Discovery - c

I recently bought a STM32 Value line discovery kit to work with STM32 devices. I'm working on a project now which requires a watchdog. It's called IWDG in STM32. But my problem is that I need an ISR when the watchdog is triggered.
Does anyone know how to implement this (or even have an example)?

You don't want a watchdog, since the whole purpose of the watchdog is to force a reset if the software has hung.
What you're after sounds more like simply a high-priority regular timer interrupt to me.
Set it up so that you restart the timer (pushing the interrupt event generation forwards in time) at regular intervals, so that the interrupt typically doesn't happen.

There are two watchdogs (at least with stm32s10x).
IWDG, which is indepenent and resets stm without isr.
WWDG (window watchdog), which has a isr 1 tick before it will reset the stm32.

Related

Embedded RTOS Stop System

I'm learning FreeRTOS on a Cortex M0. (Simultaneously, I'm learning the Cortex as well...). I've got plenty of experience with 8bit MCUs.
I'm going through the newbie tutorials on FreeRTOS and I understand setting up basics tasks and the idle daemon.
I realize I don't really understand what the FreeRTOS is doing to manage the underlying timing mechanicals of the kernel. Which leads to one big question...
What is the ideal way to shutdown an RTOS when you want to turn your device off? Not idle the device, but put your MCU into the deepest OFF there is (whatever you want to call it).
It seems trivial, to idle between tasks, but shutting the MCU off and making sure it stays off, and the RTOS kernel doesn't trigger an interrupt or somethign else to wake the MCU back up...?
this is deep sleep mode / power down mode, for an 8-bit MCU this is in the datasheet of ATmega128RFA1 on page 159 ff in http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-8266-MCU_Wireless-ATmega128RFA1_Datasheet.pdf ( with the wake-up sources ) in this mode all internal timers are disabled
in freeRTOS this is named Tickless Idle Mode, cf https://www.freertos.org/low-power-tickless-rtos.html
Note: If eTaskConfirmSleepModeStatus() returns eNoTasksWaitingTimeout
when it is called from within portSUPPRESS_TICKS_AND_SLEEP() then the
microcontroller can remain in a deep sleep state indefinitely.
eTaskConfirmSleepModeStatus() will only return eNoTasksWaitingTimeout
when the following conditions are true:
Software timers are not being used, so the scheduler is not due to execute a timer callback function at any time in the future.
All the application tasks are either in the Suspended state, or in the Blocked state with an infinite timeout (a timeout value of
portMAX_DELAY), so the scheduler is not due to transition a task out
of the Blocked state at any fixed time in the future.
To avoid race conditions the RTOS scheduler is suspended before
portSUPPRESS_TICKS_AND_SLEEP() is called, and resumed when
portSUPPRESS_TICKS_AND_SLEEP() completes. This ensures application
tasks cannot execute between the microcontroller exiting its low power
state and portSUPPRESS_TICKS_AND_SLEEP() completing its execution.
Further, it is necessary for the portSUPPRESS_TICKS_AND_SLEEP()
function to create a small critical section between the tick source
being stopped and the microcontroller entering the sleep state.
eTaskConfirmSleepModeStatus() should be called from this critical
section.
All GCC, IAR and Keil ARM Cortex-M3 and ARM Cortex-M4 ports now
provide a default portSUPPRESS_TICKS_AND_SLEEP() implementation.
Important information on using the ARM Cortex-M implementation is
provided on the Low Power Features For ARM Cortex-M MCUs page.
so in freeRTOS invoking tickless idle mode is equivalent to deep sleep or power down. possibly you have to manually disable internal timers on the cortex ...
had some problems powering down the ATmega128RFA1 MCU in Contiki OS ...

Is every input port of some microcontroller an interrupt?

I was learning about interrupts and came here to see if someone can help me!
A) I understand that the interrupt is the electrical signal sent by some external hardware to the processor, via one of the input ports.
B) I understand that in some MCU's more than one input port are "attached" to only one interrupt.
Can exist an useful input port in a MCU that is not linked to any interrupt at all?
A) I understand that the interrupt is the electrical signal sent by
some external hardware to the processor, via one of the input ports.
That is surely one class of interrupt, sure, as long as you understand that 'external hardware to the processor' can mean 'internal to the controller chip' - many MCU have extensive integrated peripherals.
B) I understand that in some MCU's more than one input port are
"attached" to only one interrupt.
Yes - that is not uncommon. The intrrupt-handler then has to poll the port to find out which GPIO/whatever pin generated the interrupt.
Can exist an useful input port in a MCU that is not linked to any
interrupt at all?
Sure, especially on 'trivial' controllers that do not require high-performace IO and have no RTOS.
Even higher-performance MCU apps may poll for sundry reasons. One common example is reading keypads. The input rate is very low and the mechanical switches need to be debounced. Fastening every KB read line to an interrupt line may cause unwanted multiple interrupts. Such iputs are better polled, though even then, a timer interrupt often handles the polling.
The answer is probably "yes," but it depends on the microcontroller architecture. There's no guarantee that one vendor's MCU will behave the same as any other (with respect to interrupts, ports, or anything else). If you're tasked with learning a particular MCU, then learn it, live it.
You house may have only one doorbell button. But pretty much anyone can use it for whatever reason. UPS there is a package. neighbor kid to play with your kid. someone trying to sell something and so on. A processor is no different. To reduce latency newer designs may have multiple interrupt signals on the core so that the handler doesnt have to do as much if any work to figure out who caused the interrupt. Kind of like having ringtones for every person on your phone, so you can tell without looking who is calling. Vs. one ringtone for everyone and you have to look.
Do not confuse external gpio ports on the chip with interrupt lines, they are not. they are general purpose I/O. they might have a way to be used as interrupts or not, depends on the design of the chip. Again as with the doorbell on your house, there are many things, technically all of them are within the chip (microcontroller), that create interrupts. Because software has to setup handlers before it can...handle...interrupts, all sources of interrupts are disabled at first, and only the ones software enabled have the ability to actually reach the core and cause an interrupt. Logic in the chip. so you may have an interrupt signal tied to the uart receiver and you might enable that. You might have one for the tx buffer, when it is empty interrupt. but you have to enable those before the processor can get an interrupt. there is a small section of logic that does fire an interrupt every time one of those events occurs, but that signal is gated and cannot reach the core, blocked by logic you control.
You can have timers in the mcu, that interrupt you when they roll over or count to zero. But you have to not only setup the timer to do that with software, you also have to enable the interrupt from making it across the chip from the timer to the processor core.
And yes sometimes the gpio peripheral has a way to interrupt the processor as well. as with everything else you have to with software setup the peripheral and define what interrupts you want and you have to enable them across the chip.
There are more different ways of doing this than there are companies making chips as they dont always do it the same way across their product lines. But generally at a minimum there is an interrupt enable on the peripheral end, one or many depending on the peripheral and features, that you have to enable in order for that signal to leave that peripheral on its way to the core. And there is often an interrupt controller peripheral or something built into the core or near it that takes all the dozens or hundreds of individual interrupt connections in the chip and prioritizes them and orrs them into the one or few interrupt lines into the core. you generally have to also enable the corresponding interrupt that matches the signal coming out of your peripheral to reach the processor core. And then there is sometimes an interrupt enable in the core itself so that even if you have the peripheral enabled, the interrupt controller enabled for that one peripherals interrupt, you still cannot interrupt the processor unless the interrupt enable in the processor core is enabled. That is the simple case, it can get more complicated if there are more layers of interrupt controllers along the way. Well the simple case is when you have something like a cortex-m with dozens or hundreds of individual interrupt signals, still have interrupt enables on both ends and in the core, just easier to manage as you have dozens to hundreds of interrupt handlers instead of one mega handler for everything.
So dont confuse the pins on the chip as being interrupts, on older dedicated processors, like the 8088/86, sure that was the one interrupt pin. But general purpose I/O sometimes called GPIO sometimes called ports, are just a peripheral, they are just pins you can make go high or low, they are not there to be interrupts although there may be a feature in that peripheral for that (or maybe there isnt). And again interrupt signals go through logic gates and have to be enabled, by software, at a minimum on both ends of that signal, at the peripheral and at the interrupt controller.

How to disable interrupt in Linux

I am using mini2440 arm board, and GPIO to control the hardware connected with the GPIO. I am using BSP that ships with the cd of the board. I have only enabled functionality which I will need for running the hardware.
I have disabled audio, Ethernet and unnecessary stuff in kernel, so that it don;t cause interrupt hence CPU attention. But the problem is sometimes some interrupt occur on the GPIO and hardware do malfunction. I know I can see all interrupt via cat /proc/interrupt, but how should i know which interrupt occur on GPIO from which device?
I am running my application with highest nice priority (-20), but still sometime external interrupt occur.
When i send data on GPIO, only TimerTick of s3c2440 do interrupt, but that's fine, it is require, but not other. Please tell me how to find which interrupt occur (I know I can check it via cat /proc/interrupt) and how to disable (Disable interrupt on ethernet via ifconfig eth0 down) interrupt from kernel? Need some expert solution, I have tried the solution getting help from people but need some expert solution.
Disabling devices in the kernel has no real efect on interrupts (generated by the hardware), it just affects how software handles them. If the device isn't present, no interrupts get generated. And Linux was written by absolute performance freaks, barring misbehaving hardware the interrupt handling is nearly as good/fast as it could be.
What exactly are you trying to do? Are you sure you aren't trying to get performance that your machine just can't deliver?

Watchdog fires on high interrupt rate

I am working on a customized/proprietary RTOS provided by my client.
The RTOS uses round robin scheduling with priority preemption.
Scenario is -
The Renesas H8S controller is running at 20 MHz
I have configured interrupt for ethernet interrupt (A LAN9221 chip is interrupting)
An OS task which reads the data from LAN controller is running at highest priority in OS
Another OS task TCP which is second highest priority task in system
An OS task which referesh watchdog
I have generated network traffic to simulate bombarding condition on the network.
Problem is at high data rates (more than 500 packets/second) on ethernet ISR watchdog is getting fired which is configured for 1 second.
Watchdog is configured to be serviced by a lower priority task of OS to detect any problem in OS functionality.
I doubt the frequency of ISR and higher priority tasks are not letting the watchdog task to be scheduled. To confirm my doubt i have serviced the watchdog in ISR itself and found working till 2000 packets/second.
Could you please suggest how can handle the situation so the watchdog should not fire even on higher data/interrupt rate.
Watchdog is refreshed in OS task running at normal OS priority which helps in catching endless loop.
The task which is at highest OS priority is Ethernet packet reading task.
There is one hardware interrupt which is raised when Ethernet receives packet and in ISR we schedule waiting Ethernet packet reading task.
Also in my system the OS is not running using timer interrupt (Like other OS run).
The OS is round robin and relinquish the control voluntarily. So increasing the watchdog task priority above the normal is not possible otherwise OS will always find it at higher priority and ready (watchdog is refreshed in infinite loop no waiting for any event) and other tasks will not get time to execute.
Only tasks which are waiting on some event can have high priorities.
So the problem is watchdog task is not getting time to refresh because of frequent interrupts and continuous scheduling of high priority tasks (Ethernet packet reading).
Try to give you watchdog a higher priority.
This might seem wrong at first glance. A watchdog shouldn't get a high priority but that's only true for systems which aren't under heavy load. Under heavy load, the scheduling will push the watchdog back (it's low prio after all) which can cause spurious time outs.
Giving the watchdog a high priority should not have a big impact on performance (it's a small task, runs not very often, triggered by an interrupt) but makes sure it can't starve.
The disadvantage is that you can't catch endless loops anymore (since the loop can now be interrupted by the watchdog).
You should also consider badly designed hardware or a bad mapping of interrupts. Maybe you can give the watchdog IRQ a higher priority than the network card. That would allow the watchdog to process its interrupts in a timely fashion without you having to give the task a higher priority.
Or you can try to increment a counter when a network packet has been processed. A new, high priority watchdog thread could watch this counter and re-configure the low-prio watchdog task not to fire as long as the counter changes.
In any form of real-time application you need, by definition, to be 100% aware of what is going on. You must know how much time each task consumes. Measure the time needed for each task with an oscilloscope by toggling a pin. Then calculate these times for the whole system. If the higher priority tasks take too much time, well, then obviously the dog will starve.
If this is too complex to measure because of acyclic or non-deterministic behavior, the program needs to be fixed. If the watchdog sits in a high priority task, you have pretty much disabled it for any task with lower prio. You might as well shut the watchdog off entirely then.
Trial & error patches, giving the watchdog higher prio, or increasing the CPU clock until the bug goes away is simply not a professional approach.
But then of course, the hardware might not be sufficient to service such a high data load as you expect. Then you may have no other option but to either use dirty patches or re-design the product from scratch with a suitable MCU.
It is probably not a matter of telling how to do it, the architecture you described should work. What you need to do is discover why the watchdog is not serviced.
If your RTOS does not have instrumentation or tools for debugging and testing, you could add I/O toggling in the watchdog loop and watch it with a scope - all the periods where it stops toggling are where higher priority tasks or interrupts are running -if that happens for more than one second, the watchdog will trigger. You might then add similar instrumentation to your other tasks and ISRs to see what is taking the time.
Is it possible that you are dead-locking under high load so that the system is in fact failing? A situation where the watchdog firing would be entirely valid. You don't want to stop it firing if it is in fact detecting an system failure - you want to fix the system failure.
If the task that handles network packets consumes so much time that it prevents the task responsible for refreshing the watchdog from getting CPU time; then the system is unable to handle high networking load. The watchdog problem is only a symptom of this "unable to handle high network load" problem.
The solution is to use a faster CPU, slow down the network, reduce the overhead of handling packets, or some combination of these options; so that the system can handle high network load (and so that the task that refreshes the watchdog does get run). Note that "handling high network load" may include dropping packets, which is the normal/established approach for handling network congestion.

I2C ISR and Interrupts

Platform - ARM9
I have a third party device connected via I2C to the ARM9. My problem is the I2C read/write is getting in a twist. It appears the IRQ line is asserted but never de-asserted when there is data to read. The read fails as the third-party device NACKs the address packet. So any subsequent write fails.
I am wondering if my interrupt handling in ok. In the ISR that services the IRQ, I disable interrupts, unregister the interrupt handler and then signal to the task to go read from the I2C bus. Finally, I re-enable the interrupts.
When the task services the signal posted above, I attempt to read data from the I2C bus but this fails. Finally, I always reregister the ISR after ever read attempt. There is no interrupt disabling/enabling that takes place during handling of the read signal.
My question is do I need to disable interrupts when reading/writing to the I2C bus?
Programming language of choice is c using propriety RTOS.
An important thing is whether your RTOS/system is ready to support nested exceptions. Unless there is a good reason to do so, things are simpler if you avoid nested exceptions and disable all interrupts when entering an ISR and re-enabling when leaving.
If you want to allow other higher-priority interrupts to occur while you are serving the I2C interrupt, then disable only the I2C interrupt. It is rather unusual to unregister an interrupt handler when entering an ISR. This may lead to unexpected behaviour, when there is no registered handler, the interrupt itself is enabled and an interrupt occurs. So instead of unregistering the handler, simple disable the I2C interrupt (Perhaps you are already doing so, but as I see it, registering a handler and enabling an interrupt are two different things).
A good strategy to solve your problem will be to try to communicate with the device without interrupts. Try to read/write from it in a serial fashion, doesn't matter if everything blocks - it is just testing. This is much easier to debug and after you are successful you can move to the interrupts version.
Most interrupts need to be acknowledged or cleared. You mention enabling/disabling, registering/unregistering and handling the interrupt. Just check that the interrupt is being acknowledged and/or cleared/reset. Often this involves writing the interrupt number or bit back to the interrupt pending register. Check the specific ARM manual or your RTOS manual.
Whether you need to enable/disable interrupts for your target platform is dependant on your specific hardware/RTOS implementation. Unfortunately, every ARM microcontroller vendor (STMicro, Freescale, Oki, etc) has the ability implement their I2C hardware differently and may have different requirements in how to clear the IRQ.
I'd recommend you find a copy of the hardware datasheet (and/or post the specific hardware part-number here so we can help pour over the vendor documentation, with you).

Resources