Showing results for 
Search instead for 
Did you mean: 

Hal vs Cmsis drivers (firmware,bootloader,flashmemory)

Associate II
Posted on August 31, 2016 at 09:29

Hello everyone,

First of all I would like to specify that I am working on a embedded project.Nowadays I am trying to write firmware operation for stm32 bit arm processor named as stm32f103c8t6.

I want to add a new feature to the project to be programmed remotely.For this process, I am using an external eeprom to store recieved data from gps module and Flash memory operation.

The idea is; 

The recieved main program data(firmware) from FTP server will be stored in external eeprom and then Microcontroller will overwrite this data in the flash memory .Thus, Bootloader will start new firmware after reset and identify it as a new software for the future applications.It is basically ''update'' operation for microcontroller.

So, In this case I already wrote flash memory(send and recieve data with initialization) and eeprom(send and recieve) codes.

In the last part,  Flash memory data should be loaded with bootloader.

I follow this tutorial to arrange specifications of microcontroller(remapping vector table,ram memory, bootloader data size...)

(I am using Keil for programming in C/C++)

My first problem is;

I hadn't create system program with hal drivers, Therefore I am not able to use these codes based on CMSIS drivers for Bootloader which is available in above tutorial.

Briefly, I can not use related Real time clock control(Rcc) codes with Cmsis drivers;






//  Enable SYSCFG peripheral clock












// Remap RAM into 0x0000 0000






Is there anyway to identify same operation codes with Cmsis Rcc library? and could you please inform me what are these codes in CMSIS based.

Second problem is;

I am using arm compiler mode instead of Gnu gcc compiler.Therefore I can not create any linker file to arrange memories for this project.It only supports scatter file.

But I have no idea how to construct it according to giving tutorial which is available above.

Could you please help me under these conditions(including scatter file).

Any help will be apreciated.

Thank you by now.

#flash-memory #bootloader #bootloader-firmware-upgrade
Associate II
Posted on August 31, 2016 at 10:11

when you using keil mdk just press <alt>+f7 and change the irom1 location.

normally it sould start with 0x8000000 and the size of your flash, just move it into a different location but check pagesizes first and then change remaining flash-size of course.

Associate II
Posted on August 31, 2016 at 10:35

Thank you for response,

So, it means that I am able to change flash memory(IROM1) and ram adress manually.

But, if you check given tutorial above, he arranged flash memory and allocate bootloader size with linker file.0x0800 0000 to 0x0800 1000 4k size for bootloader and it starts flash memory from initial adress which is now 0x08001000

How can I reserve space for bootloader operation in memory ?

Anyway I defined IROM as 0x08000000 and ram 0x20000000 according to your response.But ı would like to use linker file to allocate memory for bootloader.

Associate II
Posted on August 31, 2016 at 11:17

in my case i wanted to start always in my bootloader, so the bootloader is an small application which is located at the address 0x8000000.

because this is the address when the stm32f205 is booting in flash mode.  the main application should be located 0x8004000.

so the bootloader has one full page of 16k space. the stm is only capable of erasing full pages this is the reason why you have to ''waste'' 12k flash when your bootloader is only 4k

in the bootloader i perform an memory-check if i have an valid application if it is so i jump into the application-location. this means when an update failes i'm still able to reprogram the device.


Associate II
Posted on August 31, 2016 at 12:56

Your response quite helped me to understand.

According to this tutorial;

If I edit main application application method as;


void Remap_Table(void)


    // Copy interrupt vector table to the RAM.

    volatile uint32_t *VectorTable = (volatile uint32_t *)0x08004000;

    uint32_t ui32_VectorIndex = 0;


    for(ui32_VectorIndex = 0; ui32_VectorIndex < 48; ui32_VectorIndex++)


        VectorTable[ui32_VectorIndex] = *(__IO uint32_t*)((uint32_t)FIRMWARE_START_ADDR + (ui32_VectorIndex << 2));





    //  Enable SYSCFG peripheral clock





    // Remap RAM into 0x0000 0000




It will start to load main application at 0x08004000 adress of flash memeory after bootloader(0x08000000).

Is the right aproach ?

So after bootloader it jumps to main application at 0x08004000 and starts to load firmware after vector table at 0x0800 40C0 (192kb for vector table)

Why did he remap Random access memory(Ram) in his tutorial.

In my case I used flash memory adress without of ram initial adress.Is there any possibility to start firmware from flash memory instead of ram?

If I can, I will use above code for firmware load.

Also He used Hal drivers for reset and initial configurations



    //  Enable SYSCFG peripheral clock




How can ı apply these HAL based codes in CMSIS.

Thank you for your response, I am close to solve these problems.

Associate II
Posted on August 31, 2016 at 13:25

sorry i dont want to check source-code 🙂 i'm to lazy to try to understand what other guys want to do. for me is importend that you understand what you want to do and/or have to do 🙂

one importand note: maybe it differs when your bootloader is running out of the RAM, in my application bootloader is located in the flash 1. writing a bootloader is writing a ''normal'' application or program, the only tricky thing is to jump out of the bootloader in the main application. here you have to take care that you deinitialize all the hardware peripheral which you initialized befor. so the main-application ''sees'' a clean sheet of paper 🙂 2. the main-application is again a stand-alone program which is exactly doing what it should do, init peripherals and performing the task. the only thing is the different irom location and you have to initialize also the location of the interrupt-table. in my application its no for-loop, only some line of code. thes function is the first function you call in the main() or startup-routine 🙂 just before you enableing any interrupt.

void BootloaderSupport_init(void)
__disable_irq(); // disable global interrupts
#ifdef __MDK_ARM__ // fetch from the linker the irom-base address, some linker hacking
extern unsigned int Load$$ER_IROM1$$Base; 
#define __VECTOR_TABLE_ADDR__ (unsigned int)&Load$$ER_IROM1$$Base
SCB->VTOR = __VECTOR_TABLE_ADDR__; // SetVectorTable

Associate II
Posted on August 31, 2016 at 14:22

One more thing I would like to ask.

The priority is; 

1)Program starts with bootloader according to IROM  at 0x0800 0000 and allocated for example 4k for it.

2)jump to Main application starts at 0x08001000

3)Vector table starts at 0x08001000 to for example 0x080010C0 (or vector table should be initialize before bootloader? )

4)Firmware starts at 0x080010C0 and continue untill to end of firmware.

Am I right?(Please tell me it is correct)


At the same time ,

As you know I am going to write data to flash memory from external eeprom.So, should I consider bootloader and vector table size for this process.

I mean, the data should start to be written from 0x080010C0 instead of 0x08000000

I am sorry to disturb you that much but If I am right,  I will not disturb you for bootloader anymore 🙂

Associate II
Posted on August 31, 2016 at 14:47

what you have todo

1. write boodloader @ 0x8000000, vtor you dont have to set its per default as far as i know 2. write application @ 0x8001000, first line in main() set the vtor = 0x8001000 3. done in the bootloader to jump into your application: 1. set the main-stackpointer according the value @ 0x8001000 __set_MSP (*(__IO uint32_t *) (0x8001000)) 2. jump into the reset-handler of your application @ 0x8001004 you can check the startup-file (*.s) whats @ which location.

__Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler

when you jump set the main-stack-pointer and call the reset_hanlder, scroll further down. you'll see that the function SystemInit, which you'll find in our c-code will be called and then main()

; Reset handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR R0, =SystemInit
LDR R0, =__main

Associate II
Posted on August 31, 2016 at 15:06

personally what you want to copy into the eeprom is up to you.

what i whould do, due the issue that you can only erase complete pages in the flash, i would ''clone'' / copy complete pages from the eeprom to the flash and vice verca.

because when you want to rewrite the content of a page and you delete it and start writing with an offset the content [base-address to offset] will be 0xFF


now i get what you mean. in the bootloader you have to start to write the vector-table aswell so you have start writing @ 0x8001000. first reason see above.

second reason you inplement new featurs with use an interrupt which you've never used before :p than you would have a problem when you not would update the interrupt-table aswell
Associate II
Posted on August 31, 2016 at 15:12

You are awesome,  Thank you very much for the effort you exert 🙂

So glad to meet you.