EmbeddedRelated.com
Forums
Memfault Beyond the Launch

ARM Cortex Mx vs the rest of the gang

Started by Klaus Kragelund May 30, 2017
On 12/07/17 20:44, Don Y wrote:
> On 7/11/2017 4:16 PM, Chris wrote:
I've snipped most of this post - these posts are ridiculously long, and I expect few people will bother reading them any more.
>> >> I guess you are talking arm?. FIRQ is a leftover from early arm, fwir. > > The thread is about ARMs (Cortex M4). FIRQ is still available in > most (all?) ARM cores. >
Cortex M devices do not have FIRQ or any other complicated modes. They have a very simple and efficient interrupt system. I don't know details for Cortex A devices.
> > Modern hardware FPU's tend to treat all opcodes as atomic. > The difference is software emulations -- you'd not want to let > the emulation of FSIN run to completion when it can be interrupted > at any of the hundreds of opcode fetches spanning its duration. >
Modern hardware FPUs usually treat complex opcodes like FSIN as interruptable and either restart them, or continue from where they left off. Of course, many modern FPUs simply don't implement such complex and time-consuming opcodes but stick to simpler arithmetic and instructions that only take a few clock cycles.
>> Do commercial tool chains make use of them ?. >> Last time I checked, gcc still didn't know about interrupts, though >> some vendors do add extensions. >
gcc "knows" about interrupts, in that there are extensions (usually function __attribute__'s, perhaps also headers with specific features and maybe other extensions) that support interrupts on a wide variety of targets. It does not "know" about them if you mean understanding about different execution contexts, or how to enable and disable interrupts. On ARM Cortex M, gcc does not "know" about interrupts in this sense - simply because the interrupt hardware in the cpu means that there is no special effort needed. Interrupt functions are normal C functions.
On 7/13/2017 4:42 AM, Anders.Montonen@kapsi.spam.stop.fi.invalid wrote:
> Don Y <blockedofcourse@foo.invalid> wrote: >> On 7/11/2017 4:16 PM, Chris wrote: > >>> > Unconditionally saving and restoring the FPU's state is akin to >>> > unconditionally saving the entire state of the CPU for each >>> > interrupt -- why invent things like FIRQ (which costs real silicon) >>> > if these constraints "shouldn't happen these days"? >>> I guess you are talking arm?. FIRQ is a leftover from early arm, fwir. >> The thread is about ARMs (Cortex M4). FIRQ is still available in >> most (all?) ARM cores. > > ARMv7-M did away with most modes, leaving only thread and handler modes > (corresponding to the old "usr" and "svc" modes). ARMv8-M added secure > variants of both. There are no equivalents of the "fiq", "irq", "abt", > "sys" and "und" modes. Another difference is that R13 (stack pointer) is > the only banked register in the base architecture, plus secure state > versions of some control registers in ARMv8-M.
I spoke about "ARM cores", not *just* M-series cores. E.g., the A cores still support these modes (you can find cores that don't support FPUs, big.LITTLE, NEON, etc.; that doesn't mean the FIRQ feature -- or the rationale behind it, is "obsolescent").
On 07/13/17 21:31, David Brown wrote:
> On 12/07/17 20:44, Don Y wrote: >> On 7/11/2017 4:16 PM, Chris wrote: > > I've snipped most of this post - these posts are ridiculously long, and > I expect few people will bother reading them any more.
Must have too much time on my hands, but yes, far too long.
> > On ARM Cortex M, gcc does not "know" about interrupts in this sense - > simply because the interrupt hardware in the cpu means that there is no > special effort needed. Interrupt functions are normal C functions.
I write all interrupt handlers in C, but still need to know what registers are used inside the handler, to avoid saving everything. Since there is a disconnect between the mainline code and an interrupt handler, how does gcc know which registers to save and restore ? Fine if the toolchain vendor has provided something like #interrupt pragma, but otherwise, you need asm macros at entry and exit for the register saves. Or am I missing something ?... Chris
On 14/07/17 17:27, Chris wrote:
> On 07/13/17 21:31, David Brown wrote: >> On 12/07/17 20:44, Don Y wrote: >>> On 7/11/2017 4:16 PM, Chris wrote: >> >> I've snipped most of this post - these posts are ridiculously long, and >> I expect few people will bother reading them any more. > > Must have too much time on my hands, but yes, far too long. > > >> >> On ARM Cortex M, gcc does not "know" about interrupts in this sense - >> simply because the interrupt hardware in the cpu means that there is no >> special effort needed. Interrupt functions are normal C functions. > > I write all interrupt handlers in C, but still need to know what > registers are used inside the handler, to avoid saving everything.
No, you don't - at least, not for the normal registers (the FPU registers are more complex, as has already been covered). That is the whole point of the way interrupts are handled on the Cortex M devices. The ABI for the device is fixed clearly - ARM has said exactly which registers are "volatile" and which are "non-volatile". And the interrupt hardware preserves all the volatile registers before the interrupt function is started. This means that as long as the C compiler generates code that is compatible with the ABI, it will already save exactly the registers it needs to save - no more (assuming an efficient compiler!) and no less. You need to know about register usage for writing an RTOS with pre-emptive multitasking, and that sort of thing - you don't need to know at all for normal C code called from an interrupt. I don't know of any other processors that handle this as smoothly as the Cortex M cpus - usually the compiler has to do /something/ special for interrupt functions, preserving some registers and exiting with a "return from interrupt" instruction. But not on the Cortex M.
> > Since there is a disconnect between the mainline code and an interrupt > handler, how does gcc know which registers to save and restore ? Fine > if the toolchain vendor has provided something like #interrupt pragma, > but otherwise, you need asm macros at entry and exit for the register > saves. Or am I missing something ?... >
Yes, you are missing something (not surprising, as the Cortex M is different from other processors in this regard). It is normal practice to divide the register set into "volatile" or "caller-preserved" registers and "non-volatile" or "callee-preserved" registers. When generating the code for a function, the compiler can use the "volatile" registers as it wants without saving and restoring their values. But if it wants to use the "non-volatile" registers, it must preserve their values so that they are returned unchanged when the function exits. The compiler will not generate code to save and restore these unless it actually /uses/ these registers. And the same goes for any functions it calls further down the line. So when an interrupt has triggered, the Cortex M preserves all the "volatile" registers and then calls the interrupt function, which is a perfectly normal function.
> Chris >
On 07/14/17 15:38, David Brown wrote:

> So when an interrupt has triggered, the Cortex M preserves all the > "volatile" registers and then calls the interrupt function, which is a > perfectly normal function. > >
That's really an advance and makes the software task much easier. Assume that works for N level nested interrupts as well ?... Chris
On 07/12/17 18:44, Don Y wrote:

> > Time gets scarcer and interests (for anyone with an imagination) > multiply. The only solution I've found is to reduce the time spent > asleep! :<
Probably don't disagree with much of what you say, but wading through so much is hard waork. As I said, tl:dr applies :-). Ok, keep it short. I like to get 8 hours sleep a night, perhaps there's so much backup to do after a days interaction with life. Whatever, if you still get stimulated by the advance of tech, then you have a life and future... Chris
On 14/07/17 18:03, Chris wrote:
> On 07/14/17 15:38, David Brown wrote: > >> So when an interrupt has triggered, the Cortex M preserves all the >> "volatile" registers and then calls the interrupt function, which is a >> perfectly normal function. >> >> > > That's really an advance and makes the software task much easier. > > Assume that works for N level nested interrupts as well ?... >
Yes, it does. It is not a /huge/ advance - it is not that hard to use "__attribute__((interrupt))" or a #pragma on your interrupt functions. But it is nice and convenient, and more efficient than compiler instructions to stack the volatile registers. Indeed, its convenience has a negative effect - you need to be careful to name your interrupt functions appropriately, because it is not obvious that they /are/ interrupt functions!
On 07/14/17 18:20, David Brown wrote:

> Yes, it does. > > It is not a /huge/ advance - it is not that hard to use > "__attribute__((interrupt))" or a #pragma on your interrupt functions. > But it is nice and convenient, and more efficient than compiler > instructions to stack the volatile registers. > > Indeed, its convenience has a negative effect - you need to be careful > to name your interrupt functions appropriately, because it is not > obvious that they /are/ interrupt functions!
I have a naming convention to handle that, if that's what you are getting at. timer_drvr.c upper level timer driver code timer_isr.c lower level interrupt handler Same for anything else interrupt related.. Chris
On 12.7.2017 &#1075;. 02:16, Chris wrote:
> ... > I guess you are talking arm?. FIRQ is a leftover from early arm, fwir. > Have you seen amount of tortuous code needed to get interrupts > working properly with Arm7TDMI, for example?. About 2 pages of dense > assembler, from memory. I rejected early arm almost on that basis > alone, but there were other idiosyncracies. They fixed it eventually > with a proper (68K) style vector table, but it took them a long time > :-). Cortex was when Arm finally came of age.
I can't think of a single non-68k/coldfire processor which has the multiple priority interrupt levels (but I don't know ARM) or an equivalent. Did ARM come that much of age? I'd be surprised. Even power do not have it, some cores do have a FIRQ which has priority over IRQ (i.e. will interrupt an IRQ handler). On the core I use (and did not use the FIRQ) there is a hardware mess with the return from FIRQ opcodes - and IIRC the suggested workaround would kill the "FIRQ interrupt IRQ" capability, LOL. (I think it was to copy the FIRQ return registers to those for IRQ and exectute a return from IRQ.... too bad if you had just interrupted an IRQ handler). Dimiter ====================================================== Dimiter Popoff, TGI http://www.tgi-sci.com ====================================================== http://www.flickr.com/photos/didi_tgi/
On 07/14/17 21:45, Dimiter_Popoff wrote:

> > I can't think of a single non-68k/coldfire processor which has the > multiple priority interrupt levels (but I don't know ARM) or an > equivalent. Did ARM come that much of age? I'd be surprised.
Neither do I. At the time, we avidly followed developments in Byte magazine and remember being so impressed by the 68K architecture, went out and spent a fortune on the 68KECB, just to learn about it. It's the architecture that all others since have been compared against, often unfavorably, but Motorola were influenced by older mini architectures such as pdp11, or even Vax. "Get as much mini arch into a micro as possible", I think was the reasoning. I bet it would still be competitive even now with modern process technology, but of course, CISC is out of fashion these days.
> > Even power do not have it, some cores do have a FIRQ which has > priority over IRQ (i.e. will interrupt an IRQ handler). On the core > I use (and did not use the FIRQ) there is a hardware mess with the > return from FIRQ opcodes - and IIRC the suggested workaround would > kill the "FIRQ interrupt IRQ" capability, LOL. (I think it was > to copy the FIRQ return registers to those for IRQ and exectute > a return from IRQ.... too bad if you had just interrupted an IRQ > handler). >
Older arm arch was a mess, imho, looking like bits had been glued on all over the place. The idea of IRQ and FIRQ harks back to 6800 and 6502's IRQ and NMI, which served similar functions. If they could build compiler friendly orthoganal architecture micros 30 years ago, there's no excuse not to do it now... Chris

Memfault Beyond the Launch