cancel
Showing results for 
Search instead for 
Did you mean: 

STM32CubeIDE: How to program everything from scratch without automatic code?

Rick1
Associate II

I'm starting to program STM32 cortex M0 uC, and I want to do it totally from scratch, without any code automatically generated for me, using STM32CubeIDE 1.4.0.

In my code, I've erased everything and letf only this:

int main(void)
{
  while (1)
  {
  }
}

But when I open the file "***.LIST" I can see a lot of code generated, including the interrupt handlers and other stuff.

How can I stop it from writting background code for me and let everything manually made for me?

Thanks

6 REPLIES 6
Paul1
Lead

Don't use STM32CubeMX to create project.

You will have to in your own code init everything, but that seems to be what you want (I don't have time to go that route anymore).

Slightly simpler is to use MX to create project, but don't enable any pins or features (No GPIO, No UART, No Clocks, etc.)

If I was in your boots I would:

  • Create a minimal project with MX and IDE. Keep this generated code as a reference when writing your own code.
  • Create a new project IDE>New>Pick a method without MX. Write your own code from main().
  • Depending on where you start you could hand write the code for all the vectors and exceptions (Reset jump to main...), though probably best to keep at least that much as it also does things like set your initialized variable values (zero most, or pre-load values to set in declarations).
  • See [startup_stm32xxxxxxxx.s], you can pretty well take over everything if you replace that with your own.

Paul

Thanks for replying.

I took a look at [startup_stm32xxxxxxxx.s] but I must be missing something cuz I didn't get what I should delete or change to stop de initial code from compiling. I've tried do delete it all but some erros occurs when compilling.

Paul1
Lead

I recommend not messing with the .s file, but instead studying it so you know what it does, most of it is critical required code I never touch.

Have you done a minimal project either:

  • MX with no pins and no modules enables, or
  • IDE new C project without MX

Don't be surprised if it takes hours/days of referring to Datasheet and Reference Manual for your IC to understand what's in the init code.

Much easier to leave it and just insert in generated main() a call to main2() which you write in a separate file (main2 should replace everything done main()).

Paul

If you're going to mess with the startup_xxxx.s code (you're asking for a heap of hurt, but your choice), I'd suggest putting away the C compiler and going to raw assembly.

You're giving up the interrupt structure, memory testing, memory initialization, copying from flash to ram, setting up the stacks, setting up the heap, arranging the environment so that you can even branch to main and so that main can call subroutines and get back.

You've got a F1 car and you're wondering why it has brake pads and a crash structure since you're not planning on going slow or crashing. Okay. I suggest you start at the beginning, but if you insist you should look up the ARM programming reference and architecture manual for your processor. Learn about the memory layout, boot sequence, stacks, heap, ABI, registers, and fault handlers. But be cautious, the ARM family was designed to support compilers, you can code by hand in assembly, but it's working against the design.

I will definitely not program ARM32 in assembly language. But since I want to know every register I'm working with, to understand every internal step my uC is taking, I have to understand everything it takes to start working, so that's why I want to do it from scratch now that I'm just beggining with 32 bits uC (I already have good experience with 8 bit uC).

I have already read the datasheet and the reference manual, my "problem" now is just with STM32cubeIDE.

Paul1
Lead

OK, I understand wanting to know the details (and actually started that way, but found with 32bit you just have to think&work at a higher level as so much code and such complex ICs).

Look at the .s file under startup, but just to see the minimal functionality that is happening.

  • defines a few addresses that tell CPU where things are (variable init block in ROM, variable data space RAM, etc.)
  • Reset handler for lowest level actions at reset:
    • Set stack pointer
    • copy init block to variables, and to zero other variables.
    • library init
    • jump main()
    • endless loop if unexpectedly return from main(), consider a WDT to recover from this.
  • Vectors for code to handle exceptions, interrupts, and the like
  • Weak definitions that may be overridden by optional user code, weak definitions typically for unused interrupts and such.

Then look at main.c

  • main() will be simple or complex depending on what you enabled in STM32CubeMX, suggest starting with minimal enabled.
    • personally I insert a jump to main2() in main() as I've found messing with main() in generated files can result in lost code if you regenerate.
    • main() calls appropriate init code (HAL, Clock, modules enabled)
    • You can insert your init code here
    • main() then does endless loop, this is where you insert your run code (often a state machine or OS)

There's not much to it, unless you've enabled a bunch modules.

Paul