CC13xx define interrupt handler - arm

I am working with a CC13xx (ARM M3 core) from TI using Code Composer. I started with their no RTOS UART example, which works fine. I would like to add a systick interrupt handler. Unfortunately, there is no start-up file (which is where I would expect the handlers to be assigned), and I don't know where or how the interrupt handlers are assigned. I looked though their examples, and they all assign the interrupt handlers at run-time, which forces the table into RAM, and negatively affect performance.
Can anyone tell me how to to assign interrupt handlers to the flash table on a CC13xx using Code Composer with no startup file?

Related

How to prevent system hang before watchdog timer task kicks in

We are using an ARM AM1808 based Embedded System with an rtos and a File System. We are using C language. We have a watchdog timer implemented inside the Application code. So, whenever something goes wrong in the Application code, the watchdog timer takes care of the system.
However, we are experiencing an issue where the system hangs before the watchdog timer task starts. The system hangs because the File System code is badly coded with so many number of while loops. And sometimes due to a bad NAND(or atleast the File System code thinks it is bad) the code hangs in a while loop and never gets out of it. And what we get is a dead board.
So, the point of giving all the information is to ask you guys whether there is any mechanism which could be implemented in the code that runs before the application code? Is there any hardware watchdog? What steps can be taken in order to make sure we don't get a dead board caused by some while loop.
Professional embedded systems are designed like this:
Pick a MCU with power-on-reset interrupt and on-chip watchdog. This is standard on all modern MCUs.
Implement the below steps from inside the reset interrupt vector.
If the MCU memory is simple to setup, such as just setting the stack pointer, then do so the first thing you do out of reset. This enables C programming. You can usually write the reset ISR in C as long as you don't declare any variables - disassemble to make sure that it doesn't touch any RAM memory addresses until those are available.
If the memory setup is complex - there is a MMU setup or similar - C code will have to wait and you'll have to stick to assembler to prevent accidental stacking caused by C code.
Setup the most fundamental registers, such as mode/peripheral routing registers, watchdog and system clock.
Setup the low-voltage detect hardware, if applicable. Hopefully the out-of-reset state for LVD on the MCU is a sound one.
Application-specific, critical registers such as GPIO direction and internal pull resistor registers should be set from here. Many MCU have pins as inputs by default, making them vulnerable. If they are not meant to be inputs in the application, the time they are kept as such out of reset should be minimized, to avoid problems with noise, transients and ESD.
Setup the MMU, if applicable.
Everything else "CRT", such as initialization of .data and .bss.
Call main().
Please note that pre-made startup code for your MCU is not necessarily made by professionals! It is fairly common that there's an amateur-level "CRT" delivered with your toolchain, which fails to setup the watchdog and clock early on. This is of course unacceptable since:
This makes any program running on that platform a notable safety/poor quality hazard, in case the "CRT" will crash/hang for whatever reason.
This makes the initialization of .data and .bss needlessly, painfully slow, as it is then typically executed with the clock running on the default on-chip RC oscillator or similar.
Please note that even industry de facto startup code such as ARM CMSIS fails to do some of the MCU-specific hardware setups mentioned above. This may or may not be a problem.
There is a hardware watchdog that could be run before the application runs. ARM AM1808 does have a timer that could be implemented as a watchdog, as per documentation: www.ti.com/lit/ds/symlink/am1808.pdf. So, you may wish to set it like that at least during the part of the program that runs through the critical and long section. You at wish to have a piece of booting code that first sets this watchdog, and after the correct initialization, goes to application. In fact, this is a very common approach.

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.

Interrupt service routine for watchdog timer on STM32 Discovery

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.

What's the difference between an event and an interrupt in ARM Cortex?

I was wondering, because it seems to be different (for example WFI and WFE are separate instructions), but I can't exactly pinpoint the thing.
After a few years, I see this question is popular, and in the mean time I understood the answer by experience.
Events are implemented as lines entering the MCU ARM core, alongside the memory bus (actually the core can generate events too, the lines are one way and point to point dedicated, this is not a bus), so that peripherals or other cores can raise those lines to tell stuff in real time to the core outside any memory bus management or instruction execution, even if there is no bus arbitrer in the MCU (I guess they are clocked at bus frequency, tho).
Those events are then handled by the core, and one way to make the event enter the program world it by raising an interrupt (more exactly, plugging the line to the NVIC, that can interpret it as an interrupt), by flipping a bit in one of the core registers, by re-starting the core clock or they can be plugged to a DMA peripheral to start or stop a transfert. There is a whole logic part dedicated to event management in the core, to mask them, use them as sources for exception or as source of DMA actions.
The list of events is decided by the MCU implementers, they can decide to use an NVIC, a DMA, or connect them to PLD logic (some cypress MCU can trigger a DMA or interrupt from the PLD part).
The absolute most common way to handle an event is to ignore it, and the second most common is to send an exception to execute some code.
Both instructions are meant for power management/saving. While WFI is supposed to halt the core till an interrupt or exception occurs, WFE will also wait for an "event", which can be send by the SEV instruction.
It is implementation defined to which level the instructions are implemented, they might be just NOPs. So for example you can not trust that an interrupt or "event" really occurred when WFE returns.

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