cancel
Showing results for 
Search instead for 
Did you mean: 

Hal vs Cmsis drivers (firmware,bootloader,flashmemory)

pm_brk_pm
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...)

http://marcelojo.org/marcelojoeng/2015/09/bootloader-on-stm32f0.html

(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;

__HAL_RCC_AHB_FORCE_RESET

(

)

;

    

//  Enable SYSCFG peripheral clock

    

__HAL_RCC_SYSCFG_CLK_ENABLE

(

)

;

    

__HAL_RCC_AHB_RELEASE_RESET

(

)

;

    

// Remap RAM into 0x0000 0000

    

__HAL_SYSCFG_REMAPMEMORY_SRAM

(

)

;

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
23 REPLIES 23
pm_brk_pm
Associate II
Posted on September 01, 2016 at 09:24

Hi Chris,

I wrote a progrem according to your guide and I need your confirmation .Please don't get mad.I am totally new in this task.

1. write boodloader @ 0x8000000, vtor you dont have to set its per default as far as i know(you said)

So, as you mentioned before bootloader will start at 0x08000000 .I thought there is no need to write anything in this case.It should start to read part of flash memory automatically?

2. write application @ 0x8001000, first line in main() set the vtor = 0x8001000

I created jump_app method for application at 0x8001000

like this;

-----------------------------------------------------------------------------------------------------------

void Bootloader::Jump_application(void){

 // disable global interrupts

    __disable_irq();

    // Disable all peripheral interrupts

    NVIC_DisableIRQ(SysTick_IRQn);

    NVIC_DisableIRQ(USART2_IRQn);

    NVIC_DisableIRQ(WWDG_IRQn);

    NVIC_DisableIRQ(RTC_IRQn);

    NVIC_DisableIRQ(FLASH_IRQn);

    NVIC_DisableIRQ(RCC_IRQn);

    NVIC_DisableIRQ(EXTI0_IRQn);

    NVIC_DisableIRQ(EXTI2_IRQn);

    NVIC_DisableIRQ(EXTI4_IRQn);

    NVIC_DisableIRQ(DMA1_Channel1_IRQn);

    NVIC_DisableIRQ(DMA1_Channel2_IRQn);

    NVIC_DisableIRQ(DMA1_Channel4_IRQn);

    NVIC_DisableIRQ(ADC1_2_IRQn);

    NVIC_DisableIRQ(TIM1_BRK_IRQn);

    NVIC_DisableIRQ(TIM1_CC_IRQn);

    NVIC_DisableIRQ(TIM3_IRQn);

    NVIC_DisableIRQ(I2C1_EV_IRQn);

    NVIC_DisableIRQ(I2C2_EV_IRQn);

    NVIC_DisableIRQ(SPI1_IRQn);

    NVIC_DisableIRQ(SPI2_IRQn);

    NVIC_DisableIRQ(USART1_IRQn);

    NVIC_DisableIRQ(USART2_IRQn);

    NVIC_DisableIRQ(USART3_IRQn);

 

 //------------After flah memory programming , this method starts from specified flash memory adress to compile all settings and core program.-----------

    // main app start address defined as;

Flash_start_adress = 0x08001000; //After bootloader at (0x08001000)

    uint32_t main_flash_app_adress = Flash_start_adress;   

 

    uint32_t MemoryAddress = (uint32_t)&main_flash_app_adress; //Set related flash_start adress to MemoryAddr variable

 

    uint32_t *pMemory = (uint32_t *)MemoryAddress;//Identified MeryAddr pointer is assigned to pointer pMem.So pmem indicates(point out) the variable value of MemoryAddr

  

    // First address is the stack pointer initial value

    __set_MSP(*pMemory); // Set stack pointer to 0x08001000

 

    // Now get main app entry point address

    pMemory++;

    void (*pMainApp)(void) = (void (*)(void))(*pMemory);//create pointer function and set pMem 

 

    // Jump to main application (0x0800 1004)

    pMainApp();

}

------------------------------------------------------------------------------------------------------------

3)Identify vtor as 0x08001000 , so, as I understand it will start in the beginning of this adress.

the code is simply;

------------------------------------------------------------------------

void Bootloader :: Vector_table(){

  #define __VECTOR_TABLE_ADDR__  0x08001000

 SCB->VTOR = __VECTOR_TABLE_ADDR__; // SetVectorTable to 0x08001000    

}

------------------------------------------------------------------------------------------------------------

4)So, in my main application first I run bootloader application and then vtor application.

the code is;

------------------------------------------------------------------------------------------------------------

int main(){

Bootloader bootloader;

bootloader.Jump_application();//First run Jump_application bootloader method

bootloader.Vector_table();//then I define vector table method which is defined above

}

-----------------------------------------------------------------------------------------------------------

Is it all correct?

I just dont know how to apply reset function for CMSIS in vectortable or bootloader method.So if I identify and run these 2 method in main.will it start to load firmware from flash memory adress.

I really apreciate if you help me again :)

I just didn't understand how bootloader starts automatically and define its adress @ 0x08000000.

christoph2399
Associate II
Posted on September 01, 2016 at 13:33

1. first we jump back and think what the stm32f is doing, in terms of ''booting'', i just refer to the capter ''boot configuration'' in the reference manual of your stm32f device.

but basically when you boot from the ''main flash memory'' due the boot-pin configuration the applications will start @ the start of your flashmemory (e.g. 0x8000000)

so each time the device boots it will jump @ 0x800000 and do its task. after a reset / watch-dog it will jump to the programm @ 0x8000000.

the cortex does not care that is a bootloader its just machine-code which will be executed.

2. from your bootloader you jump in a different memory region. you can imagine it like an ''function-call''. for easy understandig just pretend  that you call the main() of your application. you dont know the name of your application but you know in the bootloader the address where your application has to be. 

3. so when you jump from the ''bootloader'' to the ''applicaion'' you have to reset your stack and everything. so basically you have to set the main-stack pointer and you dont jump really into main() you jump into the reset-handler of your application and the reset-handler will execute your main().
christoph2399
Associate II
Posted on September 01, 2016 at 13:39

create project for bootloader with flash base-addres @ 0x8000000

void main(void) // bootloader

{

// check flash // line #1

// if ok jump into application

//__set_MPS(*0x8001000) and jump @ 0x8001004

// else

// while (1) // stick into bootloader

// if update done

// perform nvic_systemreset() -> basically jump to line #1

}

create 2nd porject with base address e.g. 0x8001000

void

{

// set vtor

while(1)

 // application;

}
pm_brk_pm
Associate II
Posted on September 01, 2016 at 16:02

I understood what you said, even before.But what ı dont understand is ;

Let say,

1)I created bootloader method as a function.(with specified adress and disabling interrupts so on...)

2)I created vector table method as a function( with specified adress and reset function).

If we come to the main function, we should call these two function.

Which one should run first?

After running bootloader function and then vector table function.It will reset microcontroller then bootloader start automatically at 0x08000000, 

it jumps to the main application at 0x08001000 and identifies vectortable.After that, it will pass to the other pages available in flash memory??

So should I call these function as

1)Flash memory specification and write data to flash memory to 0x08001000

2)If flash data is completed, run bootloader function to specify jump application and disabling interrupts.

3)Then run vector table function to specify vector table at first adress and then reset microcontroller.

4)After reset, bootloader runs at 0x0800 0000  and starts to load flash memory from 0x08001000

So basically, I dont want to create another project for bootloader.I just would like to use this bootloader as a function and call it in my flash memory algorithm.So after flash memory completed this bootloader function should run automatically and load flash memory after reset.

Is it correct and possible?, I am so sorry to ask you again and again.I just would like to understand details.

Thank you so much.

christoph2399
Associate II
Posted on September 01, 2016 at 20:15

i dont get it. bootloader is always a standalone program which basically has in my opinion three tasks.

1. check for a valid application

2. start the application

3. use a hardware-interface to get data and write it to the flash

i dont know how its possible to link a function, your bootloader method, to a certain address.

pm_brk_pm
Associate II
Posted on September 02, 2016 at 08:13

Working principle of my project is(what I would like to do in this project);

I have already designed circuit and finished programming side of it.

Circuit design includes : GSM module, Gps module, Arm 32 bit f1 series microcontroller.

So, It is basically a ''Tracking System''.GSM sends the position information recieved from the satelite to the server .After recieving position data from Gps , Arm microcontroller interprates this information and It sends data through GSM module to the server.

Circuit and programming part of it is working properly.In this case ı would like to add  remote programmability.

At this point I want to make;

1)I am using external eeprom which is connected via I2C to arm microcontroller to store recieved firmware data which will be avaliable in Ftp server as .hex file.(First,I will get firmware data from Ftp server and directly transmit it to the external eeprom)

2)After this operation I am planning to write this firmware to flash memory.Then I should add bootloader method inside of my main algorithm to start microcontroller with new firmware.

It means that, If program file(firmware as .hex file) is available in server, start to write it to externel eeprom via microcontroller and directly get data from eeprom to flash memory.Finally the only thing left is to manage bootloader inside of this algorithm.

I am planning to recieve this firmware from server via Gsm module.

 

Is it possible to manage bootloader method inside as a function?

Because , this device will not be close to me.I should be able to program it remotely.

Posted: Thursday, September 01, 2016 8:15 PM

Subject: Hal vs Cmsis drivers (firmware,bootloader,flashmemory)

i dont get it. bootloader is always a standalone program which basically has in my opinion three tasks.

1. check for a valid application

2. start the application

3. use a hardware-interface to get data and write it to the flash

i dont know how its possible to link a function, your bootloader method, to a certain address.

christoph2399
Associate II
Posted on September 02, 2016 at 08:36

first of all everything is possible, as long as its within the physical limitations :D

for an engineer there is no - no.

but than its just getting harder.

for basic understanding why you should have 2 standalone applications (bootloader, application).

for example we use a windows-tool like a pdf-reader or so, which is able to downloadan update. but for installing the newer version of the tool the old tool has to be closed and ''overwritten'' with the new tool. how sould a tool close it self, delete his old self and overwrite it with its newer self when already deleted?

basically the tool downloads the new version and an update.exe. the update.exe closes the tool - deletes the old tool - installs the new tool - starts the new tool and closes its self.

now the only possibility i know of, you have to load your bootloader-method in the sram. than out of the sram you could delete the flash-content and update your flash. but with this approach i cant help you. but let me know how its done when you know :)
pm_brk_pm
Associate II
Posted on September 02, 2016 at 10:34

My opinion was as follows,

1)Firmware will be stored in external eeprom

2)I already defined functions(methods) for flash memory arrangement(write,erase and read methods)

3)I was thinking to write firmware data to part of flashmemory  from eeprom(The firmware data should be stored in second half of flash memory instead of deleting ex 

application from flash memory.

For example;

 ex application is stored first part which is available in 0x08001000 to let say 0x08001FFF and new firmware will be stored after this last adress)

4)Now, new firmware is available in second part of the flash memory(256kb).Then bootloader function and vectortable method should arrange flash memory to read new firmware from second part of flash memory.In this case,Initial adress will point to second part of the flash.

5)After reset , bootloader starts from 0x8000000 and load second half of the flash memory which is identified in bootloader function..If the data was not written correctly or flash is not completed, I would like to run second bootloader function to point ex data in flash memory and load it.

6)Finally , the process is completed successfully

What do you think? The only thing that ı learned newly is the working principle of flash memory and bootloader relation with your guide.

christoph2399
Associate II
Posted on September 02, 2016 at 13:13

personally i still dont get it,

you have two applications and each application has the bootloader-functionallity within?

i would keep it as simple as possible.

[bootloader][application1][application2]

so my bootloader its like a dual-boot on windows, that i can start two indipendent operating systems.

my bootloader is able to access the external eeprom

and knowsthe start-address of both applications and could verify them. 

then the bootloader will determin what to start, maybe with a hardware configuration like with reading an input or with a configuration byte which he is reading out of the flash somewhere.

if my applications1 is running and wants to update applications2 it will just update the eeprom. then the bootloader will do the rest. 
pm_brk_pm
Associate II
Posted on September 02, 2016 at 16:14

What I understood from boot mode is,

Boot code is stored in part of flash memory (initial adress).So, according to working principle of microcontroller, boot code starts first and directly read and load flash memory data from specified adress.Thus, program data will be run from flash memory.

I just would like to specify flash memory adress with function, so we call that as bootloader function.It just specify flash memory initial program adress(let say 0x08001000), then we arrange vector table which starts in  initial adress of program(0x08001000 to 0x080010cC0) and reset microcontroller.

After reset;

 

It starts bootcode at 0x8000000 of flash memory(initial adress) automatically and this boot code will start to read 0x08001000 with vector table , then load it as a new firmware.

So, Boot code will run automatically in the beginning to read data from specified adress of flash memory which is identified in bootloader function?

What I supposed is,Arm booting is one specified operation that runs in the initial mode of microcontroller and start to load data from flash memory ? Isn't it.

So ,After changing flash memory with new program data, this bootloader function just change flash memory adress , jump to application(new program data at 0x08001000) and reset microcontroller.Then booting starts in the beginnig to load new data from 0x08001000 automatically? 

So,

 After reset. I just would like to load new system program from flash memory automatically.Isn't it bootloader operation(booting) or I am completely wrong?

I am not going to use any serial protocol like USART.I just would like to boot my microcontroller and it should read and load data from flash memory.So,I need an automatic boot mode which reads and update new program data via flash memory.

https://www.youtube.com/watch?v=ZUXuk2zFHfs