2016-08-31 12:29 AM
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-upgrade2016-09-01 12:24 AM
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 0x8001000like 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 variableuint32_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 methodbootloader.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.2016-09-01 04:33 AM
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().2016-09-01 04:39 AM
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. 0x8001000void{ // set vtor while(1) // application;}2016-09-01 07:02 AM
2016-09-01 11:15 AM
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.2016-09-01 11:13 PM
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 PMSubject: 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 application2. start the application3. use a hardware-interface to get data and write it to the flashi dont know how its possible to link a function, your bootloader method, to a certain address.2016-09-01 11:36 PM
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 :)2016-09-02 01:34 AM
My opinion was as follows,
1)Firmware will be stored in external eeprom2)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 successfullyWhat do you think? The only thing that ı learned newly is the working principle of flash memory and bootloader relation with your guide.2016-09-02 04:13 AM
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 eepromand 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.2016-09-02 07:14 AM
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