ARM Programming With Bare C

We confess. When starting a microcontroller project, we often start with the last one we did for that environment, copy it, and just make changes. And the first one? It — ahem — might have been found on the Internet. There’s a lot more than just your code that goes into this. If you want  to do (and understand) absolutely everything yourself on an ARM development project, you could use an all-in-one walkthrough. It just so happens [Jacob Mossberg] has a from scratch guide of what you need to do to get your C code running on ARM.

Starting with an ARM Cortex M3, he writes a simple C program and gets the assembly language equivalent. What follows is a detailed analysis of the machine code, exploring what the compiler assumed would be set up. This leads to understanding of what the start up code and linker script needs to look like.

It is a great approach and reminded us of the old saying about “teach someone how to fish.” He even devotes a little time to talking about getting debugging working with OCD. Of course, the exact details are specific to the chip he’s using, but most of it would apply to any ARM chip. Even if you don’t use ARM, though, the thought process and methodology is itself quite interesting.

This post would be just the thing if you are using Blue Pills and ready to move away from the Arduino ecosystem. Of course, if you want to veer away from the Arduino system, but don’t want to go all the way to bare metal, there’s always mBed.

44 thoughts on “ARM Programming With Bare C

  1. “There’s a lot more than just your code that does into this.” — grammar?

    “Of course, if you don’t want veer away from the Arduino system, but don’t want to go all the way to bare metal…” — what?

    Sounds like this needs another pass of the edit steamroller! Feel free to delete this comment afterward; I always find it confusing reading comments about revisions that’ve been made and thus no longer apply.

          1. I think Al probably likes red wine as much as I do, maybe tempted to thereby write more easily, familiar pattern ;-)
            Of course the reseveratrol can be good for you but, I understand works better (as do anthocyanins) with higher mineral intake since most on western diet somewhat deficient in; Zn, Cu, Se, I, Mg, Mo, Cr etc But, hey I won’t whine about it much.
            FWIW: I make my own mineral dietary supplements, mostly Cu and ingredients to improve bio-availability, For Cu to the tune of 100 times the average level most people get which is around twice to three times the homeostatic level…
            Apologies for digressing, health more important that most everything & minerals not well understood.

          2. You know, excessive copper intake causes neural dysregulation and symptoms of psychiatric disorders. When the body tries to get rid of the extra copper, the same mechanisms mess up with your brain function.

            And it damages your kidneys and liver.

          3. Yes I do know Luke, first thing I looked at early 2010 Luke (whoever you are, no link – hmm ?) in formal uni studies and access to labs too. It all depends on your key psychological, intellectual equipment and focus to discover the truth beyond the ill thought traditional idea of “.. if it aint broke don’t fix it”. So if even a little within your particular terms of reference in respect of your intent and to address it why you should; study chemistry intently, read multiple peer reviewed journals (>1000 since early 2010), converse with experimenters in the field, assess the thorny issue of bioavailability, process co-antagonists equlibria re Zn & Fe, critique the dietary supplement industry propaganda, investigate those who have had confirmed high intakes for whatever reason, gain quantitative data on content in various foods, take blood tests for minerals & liver function & few others as secondary and tertiary factors (few other diagnostic tests too), address genetic aspects, some other complex factors – then feed that back into the knowledge base you have accumulated since 2010 Eg. where I graduated in food science with distinction in food chemistry at Curtin University…

            So when you discover a person’s average intake of Cu in USA, Europe and Australia is a mere 300mcg per day, some as little as 150 mcg/day and getting lower, they weigh 76Kg or more and WHO assess their homeostatic level should be of the order of 100mcg/Kg/day And discover Cu has the highest dynamic range above other trace minerals needing to fortify approx 150 Cu enzymes in combative equilibria with 100 Zn enzymes as well as complex cofactor issues – what do you get when you ‘do the math’ ie look at the ratio in respect of RDI – so then what would you do Luke -?

            Bear in mind the naturopathic industry has facile crude motive to pursue many false claims from (stupefying) hair samples to pecuniary issues re antagonists, ignoring genetics etc in order to sell you nothing more than excipients – then how do you address that when so many in industry struck by inertia and lazy acceptance of the status quo re foods and ‘nothing unusual’ – do you just complain when you get the chance easily provoked or instead be a wee bit more intelligent, learn and ask questions of those better researched and those with years of quantitative data ?

            I would not recommend anyone and especially those with immune system problems, cancer or Wilsons, Menke’s genetics taking any more than the homeostatic level in association with bioavailability issues moderated by absorption problems of co-antagonists for brain function Eg fructose, Vit C etc etc…

            If you have something new to add not already covered then don’t be shy Luke, spit it out – ok ?

    1. Well to paraphrase Bill Murray I should have drank all that cough syrup that morning. Hopefully, you could still figure it out. We have editors, too, of course, but it is odd that even in “the old days” when we did major books and you had your own editing, a tech editor, a copy editor, and the typesetter, I can open up almost any of my books to any page and we are likely to find something. Its why AI will one day take over the world ;-)

  2. I see start-up assembly wrappers in Cortex M projects ALL THE TIME and I just don’t understand why they don’t understand it is not needed. So thank you Jacob for the +1 on the side of sanity and experience. This is exactly the way my custom CM development framework has been setup for years. Great guide.

  3. Having done something similar for a different (non-ARM) uC, I found starting with the dev board and the vendor supplied example code is usually a good starting point to at least show you what you need to have configured. Then it’s just a case of pulling apart everything it did for what you want.
    While I kept the same development environment, I ended up re-writing the linker scripts as I was also writing a boot-loader (so brand new assembler startup code) for it as well and needed to carefully manage the memory allocation, plus I was trying to optimise algorithms to fit within the limited code-space I had.

    1. +1 on using CubeMX.

      It also generates code to initialize the clock tree, SysTick, and the startup code it copies does a good job or initializing all the other indirect data that the GNU compiler adds into the *init sections. That initialization seems to be missing from the code in the linked article. The other important thing that the linker script it provides does, is to ensure that your .data, .bss, and .heap sections don’t collide with a minimum stack size you specify… otherwise you might _think_ you have enough RAM, and end up with the stack growing down into your data without knowing it. BLAM.

      Where I find the HAL a little lacking is in its handling of interrupts. Their ISRs are very heavy. The biggest issue I have is that every one of them disables the interrupt when it handles it, so you are forced to call their (also heavy) function to re-enable it, you may also miss an interrupt if one happens between the time it is disabled and when you enable it. This slows everything down. The other big issue I see with the HAL is that their busy wait timeouts do not handle overflow/wrap around on the 32 bit SysTick counter variable… so, every 40 days the thing stands a chance of hanging if you call any of the polling routines regularly… In my code I only call those functions at startup.

      1. I personally prefer Renesas Synergy over ST’s efforts. I’m surprised it was never given a mention on this blog. Are Renesas MCUs still consiredered useful for commercial customers only?

        1. The only ‘tactic’ used here, is to provide hints for the sad profusion of young people who I hear from, that expect a career in embedded computer systems engineering, after being deluded into thinking their ability to script a few high-level routines will be sufficient.

      1. Yeah. In my world “systems engineering” has a huge, wide scope. You’d get in trouble for focusing on the tiny details rather than passing that down the line to the firmware development team, who would assign a specific person to research and manage the CPU initialization code.

        SE generally refers to the equipment or unit as a whole, including any necessary support pieces. IE it’s the firmware, the electronics, the case, the UI, the device hardware, the service network, the desktop application etc. If you need more than two or three skill sets, you need an SE to manage all the people, pieces, and customer expectations.

        In short, SE is the exact OPPOSITE of messing with make files and CPU fuse tables.

      2. So, context of use doesn’t narrow the scope for you? You know, embedded computer systems engineering when used in reference to article on low-level, or bare-metal, controller programming?

      1. do not go there!

        my first 6800 system, the one published in the Popular Mechanics magazine

        I couldn’t aford 30 odd toggle swithes, so I bodged together a board with DIP switches!

        It was a friggen pain!

        getting my first SYM-1 was luxury!

        A hex keypad!!

        I went back and built a TTL hex keypad!

          1. Hmm, yeah I virtually realised with all the stuff I need to remember and check puts me on edge, it’s best to do things one bit at a time not getting interrupted, heck I wouldn’t give two bits for all this multitasking stuff like women boast they can iron clothes whilst talking on the phone simultaneously ie. I hear them talk about this on the same bus all the time, all they end up doing is going back and forth using up energy they just sink to a new low and they hardly ever shake hands either…

    1. TYPE in codes??!?!
      Back in (somebody’s) day, they flipped switches to load one byte at a time!!
      Or manually punched cards
      Or wrote code on paper, with space next to it manually convert code to binary, to then do one of the above.
      Now get of (somebody’s) lawn
      Why does humanity love to brag about how hard it was before?
      My favorite “we had the computational power of a pocket calculator to go to the mooooooon!”

      1. You have clearly never had to work with someone who calls themselves an embedded systems engineer because they finally figured out how to make a full Linux OS blink an LED, but has no clue what a linker script is. It brings out the worst in those that have been around for decades before the new guy. You know, that guy that claims he has known everything you know about engineering since he was 5. Some people overcompensate. Also, some people make stuff go to the moon with a few kbytes of memory.

  4. Yes, bare metal is where it is at. Blue Pills and bare-metal, now there are some bargain good times for sure. Get yourself one of those bargain ST-link adapters and you can run OpenOCD and be doing source level debugging via gdb. I hardly gets more luxurious than that, though that sort of thing is rarely needed, but cool to know it is there.

    Everyone should know assembler, but you sure as heck don’t want to program in it these days.

  5. I haven’t studied the article yet, but from the introduction it seems very similar to the “Pandafruits” tutorial, which I found when startint with ARM Cortex 3 some time excellent read.

    It is a short tutorial, but packed with the details of getting a bare bones ARM uC going.
    From the linker script and a makefile to using the “standard peripheral Library” (SPL), flashing the chip and a little bit of debugging tools

    I do not like “arduino” much because of all those pre-instantiated object and initialisation of peripherals to (for me) unknown states.

    So I was curious about mbed, and compiled a HID example for the Blue Pill… 70kB, but the Blue Pill only has 64kb :(
    Both arduino & mbed are easy to set up for some experiments with STM32 with Plaftormio.

    1. Check your device flash size with STM’s ST-LINK utility. Not all but most Blue Pills with the STM32F103C8 actually have 128K flash instead of the advertised 64K. All ten of the cheap $2 STM32F103C8 Blue Pills I have sitting in my storage bin have 128K.

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.