Hacker News new | ask | show | jobs
by eckzow 4518 days ago
I don't mean to be a party pooper since I've done my fair share of hacky workarounds in v7-M processors and it is always exhilarating when it works...

But since I'm a Cortex M fanboy I have to defend its reset capabilities :)

For your specific case, try something like

  volatile uint32_t *AIRCR = (volatile uint32_t*)0xE000ED0C;
  const uint32_t VECTKEY = 0x05FA << 16;
  const uint32_t SYSRESETREQ = 1 << 2;

  void take_reset()
  {
    *AIRCR = VECTKEY | SYSRESETREQ;
    __dsb();
    while(1);
  }
It's technically dependent on external hardware in your processor subsystem, but it should work if your implementer has half a brain (or, at least cares enough to read the integration manual). If it doesn't work, please flog your implementer publicly so that I can know to avoid them in the future...

Incidentally, even that tiny code snippet is uses a C extension (the __dsb intrinsic) which is either a great example of how C can be wielded to great power (I can generate raw instructions!) or how C is terribly handicapped (I need a special compiler extension or all my system code is horribly broken!). All depends on point of view, I guess...

Anyway, more info @ page 498, http://web.eecs.umich.edu/~prabal/teaching/eecs373-f10/readi...

2 comments

I too had already been through that particular part of the ARM7-M manual, after coming up through the data sheet to the technical reference guide, to the Cortex M architecture manual, and yes to the base ARM7-M architecture specification.

There is "should" and "does" :-) I had followed the exact same sequence and discovered on my system it didn't cause a system reset. I escalated it a bit (in this case ST Micro) and the caveats came out, "Well if you system is correctly designed, if the actual reset pin isn't connected to something that is interfering, if the core is in a state where it can actually take a reset, ..." This being unlike pretty much every processor I've worked on, from PDP-8's, 11's, 10's, VAXen, IBM 360/370, Sun 1, 2, 3, 4, Motorola 6800, 68K, 68K, Z80, 8080, 806, Pentium *, the list goes on. Most actually have a reset instruction, usually privileged, to force a system reset. But the difference is that the reset sequence was guaranteed to force a system reset if it executed, all of those previous processors had a company that made the processor as opposed to simply licensed the processor to a third party. Since it is completely reproducible on my system I've got an action item to create a small test case for errata analysis.

Yes, that is the code they suggest, with assurances that it will work in pretty much any case. Except when it might not. It was a bit stunning for me, I still marvel at the notion. Like an add statement that will 99.999% of the time add its operands together[1] unless it doesn't.

[1] No there isn't such a thing in ARM it is just the way I hear "It will almost always reset the system."

Fair enough. The Cortex-M's that I've dealt with have generally been homed inside some larger chip, and so the "reset pin" notion was a bit more vague, and in such an environment ARM's stance makes a bit more sense as you really want the reset to reset the "subsystem" (including whatever other random hardware you glued to yourself today).

It's also true that ARM has heard some of these complaints, which is why there were steps toward standardizing some things--like, the SYSTICK interface--in v7-M. It's really been a step up since the ARM7TDMI, and I hope that it will continue with v8-M or whatever the next revision ends up being.

Personally, when I'm dealing with a discrete chip and I need to reset it I've found that the most reliable methods that don't set off the hack-o-meter too badly are to wait for or directly invoke watchdog hardware... but yes, that's essentially always device specific.

That is a very good point! If you are building some SoC and the CPU is just some small part of it, "system reset" can in fact be a very vague notion. I hadn't really been thinking that way and in that context the ARM position does make sense. As another person pointed out offline there is the watchdog timer, if you wanted you could set it and halt. Then it would kick you with a reset.
From memory, the Z80 and x86 don't have a reset instruction. On a 286+ you can fake one by triple-faulting.
For anyone else curious on the __dsb() call, from ARM's docs:

The Data Synchronization Barrier (DSB) acts as a special kind of memory barrier. The DSB operation will complete when all explicit memory accesses before this instruction have completed. No instructions after the DSB will be executed until the DSB instruction has completed, that is, when all of the pending accesses have completed.