We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi
I have a requirement to have a header struct containing CRC16, minor,major versions and an ident as a total of 4 x uint16_t at the start of my firmware file. This will be in each of 3 firmwares HEX files that live at different addresses within the flash starting 0x08000000.
Obviously, my bootloader will be at 0x08000000 (start of flash), but the initial 8 bytes will be the struct above. Does anyone know if this is achievable??
Micro is Cortex M3 with 1MB flash (STM32F103ZG) with RTX RTOS
My code to add my struct at 0x08000000 is thus:
//////////////////////////////////////////////
#pragma pack(1) typedef struct { uint16_t FileCRC16; uint16_t FwType; uint16_t MajorRev; uint16_t MinorRev; } str_Firmware_Header_Info_t,*pstr_Firmware_Header_Info_t;
//Enum of FirmwareTypes typedef enum { BL = 0, //BootLoader FC = 1, //FunctionalCode HI = 2, //HumanInterface BLFC = 3, BLFCHI = 4, FCHI = 5, INVALID = 6, //No Start line, or bad addresses etc UNKNOWN = 7, } FirmwareTypes;
#define BOOTLOADER_BASE_ADDRESS 0x08000000 #define CRC16_PLACEHOLDER 0x0000 #define BOOTLOADER_MajorRev 0 #define BOOTLOADER_MinorRev 1
const str_Firmware_Header_Info_t FIRMWARE_HEADER __attribute__ ((at(BOOTLOADER_BASE_ADDRESS))) = {CRC16_PLACEHOLDER,BL,BOOTLOADER_MajorRev,BOOTLOADER_MinorRev};
///////////////////////////////
In the project setting, 'Target' tab, I have IROM1 defined as Start:0x08000000 with Size:0x20000
building the above leads to a map file extract below:
/////////////////////////////////////////////
FIRMWARE_HEADER 0x08000000 Data 8 main.o(.ARM.__AT_0x08000000) __Vectors 0x08000008 Data 4 startup_stm32f10x_hd.o(RESET) __Vectors_End 0x08000138 Data 0 startup_stm32f10x_hd.o(RESET) __main 0x08000139 Thumb Code 0 entry.o(.ARM.Collect$$$$00000000) _main_stk 0x08000139 Thumb Code 0 entry2.o(.ARM.Collect$$$$00000001) _main_scatterload 0x0800013d Thumb Code 0 entry5.o(.ARM.Collect$$$$00000004) __main_after_scatterload 0x08000141 Thumb Code 0 entry5.o(.ARM.Collect$$$$00000004) _main_clock 0x08000141 Thumb Code 0 entry7b.o(.ARM.Collect$$$$00000008) _main_init 0x08000141 Thumb Code 0 entry8.o(.ARM.Collect$$$$00000009) BOOT_jump 0x0800014d Thumb Code 20 bootloader.o(.emb_text)
///////////////////////////////////////////////
Using the above, if I stick a breakpoint at the start of main(), I can step through the initial lines, but then it gets to my 'system startup task':
os_sys_init_user( System_Startup_Task, PRIORITY_ZERO, Startup_System_Task_Stack, sizeof(Startup_System_Task_Stack) );
The 'system startup task' never actually starts and the code falls unto the while(1); that sits below it.
Now, if I remove the line that creates the FIRMWARE_HEADER:
then everything works. The map file becomes:
__Vectors 0x08000000 Data 4 startup_stm32f10x_hd.o(RESET) __Vectors_End 0x08000130 Data 0 startup_stm32f10x_hd.o(RESET) __main 0x08000131 Thumb Code 0 entry.o(.ARM.Collect$$$$00000000) _main_stk 0x08000131 Thumb Code 0 entry2.o(.ARM.Collect$$$$00000001) _main_scatterload 0x08000135 Thumb Code 0 entry5.o(.ARM.Collect$$$$00000004) __main_after_scatterload 0x08000139 Thumb Code 0 entry5.o(.ARM.Collect$$$$00000004) _main_clock 0x08000139 Thumb Code 0 entry7b.o(.ARM.Collect$$$$00000008) _main_init 0x08000139 Thumb Code 0 entry8.o(.ARM.Collect$$$$00000009) BOOT_jump 0x08000145 Thumb Code 20 bootloader.o(.emb_text)
////////////////////////////////////////////
So... vectors are offset by 8 bytes (the size of my struct) in the 1st map, and placed at 0x08000000 in the second map file.
Am I barking up the wrong tree here, is there any way to have the struct at the start of my hex file?
Kind Regards
Nigel
Its all sorted now - moved my struct to the end. I wanted version FW type and CRC in the same struct. There's three distinct parts to the firmware, I wanted the version structs in the same place for all.
Don't suppose you have any idea why my jump from my bootloader into my main firmware is not working...??!
Followed the docs, PC gets loaded with the right address, but it aint playing ball. I am thinking that its related to the vector table...
From my bootloader (0x08000000) I call JumpToAddress(0x08010000); to run the main code that starts from 0x08010000
//tried various different takes on this method... static __asm void Boot_Jump(uint32_t firmwareStartAddress) { LDR SP, [R0] ;Load new stack pointer address LDR PC, [R0, #4] ;Load new program counter address }
void JumpToAddress(uint32_t dwAddress) { /* Reset registers */ /* Clear all interrupts set. */
// __disable_irq();
///NVIC->ICER[0] = 0xFFFFFFFF; //NVIC->ICER[1] = 0xFFFFFFFF;
NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x010000);
/* Set new vector table */ //SCB->VTOR = (uint32_t) dwAddress;
Boot_Jump(dwAddress); }
Any thoughts??