How to check if whole program is flashed on ARM? - c

I'm using arm-none-eabi-gcc 5.3 to produce binaries for STM32L4. I'm using bootloader to flash program. Problem is I can't be sure if I'm flashing whole file. I don't have any CRC available. Flash starts on 0x80000000 and 0x80040000 (2 banks for bootloader and main program). Currently I assuming If 0x80040004 is between 0x80040000 and 0x80080000, program is flashed. But how can I check if program is valid? I can't find where is size of binary that should be written on flash, so I can check last few integers.
Here is first few bytes from BIN (sorry, can't post whole file):
Last byte that is not programmed is 0x80051C00 (program has 72704 bytes).

The most likely error is loss of data connection during the transfer so that the image is only partially written. The chances of programming error once the data is received is probably negligible, although your transfer protocol should include some sort of data integrity check. For that you could simply validate the checksum of hex-file records or use a protocol with CRC error checking such as XMODEM-CRC or XMODEM-1K.
Ensuring that you do not attempt to start a partially loaded application image is simple. It is not necessary to program the flash in address order or even the order the data arrives in. Given that, when the data for the reset-vector at 0x80040004 is received, you retain it in RAM and program it last. That way the reset vector value will always be 0xFFFFFFFF if the programming did not complete:
Pseudo-code:
WHILE receiving data
IF program_address in range
// Write all data except address at reset vector
IF program_address == 0x80040004
start_address = program_data
ELSE
write( program_address, program_data )
ENDIF
ENDIF
ENDWHILE
// Write reset vector *LAST*
write( 0x80040004, start_address )
Then in the start-up code:
IF #0x80040004 == 0xFFFFFFFFFF
NO APPLICATION - DO SOMETHING!
ELSE
START APPLICATION
ENDIF

Related

c166 bootloader write to internal flash

I'm writing a bootloader for a c166 chip, to be exact, the 169FH. The bootloader can currently open a TCP/IP Connection so a PC can send an Intel hex file to the bootloader. This intel hex file is saved in the RAM. After receiving the hex file it is read line by line to set the bytes to the correct location in the flash. The flash location where the bootloader is stored is ofcourse different from where the main program can be saved.
This are the first two lines of the intel hex file:
:0200000400C03A
:20100000CA11EE111212341258127A129A12BC12DE12001322134413601388138813881349
The first line is to get the highest 16 bits of the 32bit flash address, which is in this case 0x00C0
in the second line are the lower 16 bits of the 32 bit flash address, which is in this case 0x1000. This creates to total address of 0x00C01000, the byte written to that address should be 0xCA.
I'm trying to write the byte to that address using the following code:
uint8_t u8Byte = (uint8_t )XHugeStringToDec((const __huge char *)&Ext_RamFlashSave.Byte[u32Idx], 9+(u8ByteIdx*2), 2);
uint8_t *u8Address = (uint8_t*)((uint32_t)(u32ExtendedLinearAddress << 16) + (uint32_t)u16BaseAddress + (uint32_t)u8ByteIdx);
*u8Address = (u8Byte);
XHugeStringToDec() is a function to get the hexadecimal value from the intel hex string. I know this is going correct.
Ext_RamFlashSave.Byte is the array where the intel hex file is storedin.
The u32ExtendedLinearAddress variable is 0x0C00, and is set earlier. The u16BaseAddress is 0x1000 and is also set earlier in code.
The problem is in the last line:
*u8Address = (u8Byte);
I have verified that u8Address is indeed 0x0C01000 and u8Byte is indeed 0xCA. But when I monitor my flash address, I do not see the byte written.
I can imagine that it is some kind of write protection, but I cannot find out how to work around this, or do I need a different way to write to the Flash address?
More info of how the intel-hex file is build is described here:
https://en.wikipedia.org/wiki/Intel_HEX
I am not familier with the chip you said.
But for writing to flash, Generally, following algorithm is used:
Unlock the flash. This is usually sending specific data sequence. The flash I use right now has 0xA0A0-> delay of 1msec -> 0x0505. This will enable writing to flash
Clear the error flags. Flash has some error flags like Write error or read error. Also, check for Busy flag to make sure Flash is ready
Erase the Page. Yes... You have to erase the page before writing to it. Even if you want to change a single bit, You have to erase entire page.
Write the data (Finally) But make sure that endien-ness is correct. Sometimes you Controller is Little Endien and Flash is Big Endien. So you have to match to Flash's.
Lock the Flash. This is usually done by sending same sequence which used for unlocking. (Refer Datasheet)
You cannot write to a flash directly... Have to go through entire process. That's why Flash are slow.
Some flash support 8bit writing while some only 16bit or 32 bit etc. So, you have to send those many bits while writing.
When you have to modify a small portion of a page, Read the page in a buffer. Modify data in the buffer. Erase the page and write entire buffer.
If you are modifying a

UART debug session in Keil for KL25Z

The program is to receive a byte from the host PC via UART0 on KL25Z. The data is fetched from Data Register D and assigned to a variable, c. Then controlled by the value of each bit of c, tri-color LEDs are lightened. The program works well with no problem.
When Keil enters ‘debug session’, I set a breakpoint to observe c and UART0->D.
[code][1]
[watch c][2]
After sending a byte from a terminal emulator software on PC, the program stops at the breaking point as RDRF (Receive Data Register Full) flags. At this moment, it can be observed data in Data Register is 0x61 which is the ascii code of letter ‘a’ and there is no value in variable, c.
[UART0_D][3]
[watch c][4]
If stepping by one line, variable c is supposed to be equal to 0x61. However, the result is c is 0 and Data Register is emptied. Because c is 0, LEDs are not lightened accordingly. I don’t understand why?
[UART0_D][5]
[watch c][6]
The setting for debug is as follows.
[debugger selection][7]
[debugger settings][8]
I'm running short of 10 reputation points to post more than 2 links. Relative images are attached here. Sorry for the inconvenience.
image link
Thanks.

STM32F4 Jump to Bootloader via SoftReset and without BOOT0 and BOOT1 Pin

i ask because of an answer to a similar quastion which can be found here: Jump to Bootloader in STM32 through appliction i.e using Boot 0 and Boot 1 Pins in Boot mode from User flash
The User "JF002" #JF002 answered "When I want to jump to the bootloader, I write a byte in one of the backup register and then issue a soft-reset. Then, when the processor will restart, at the very beginning of the program, it will read this register. This register contains the value indicating that it should reboot in bootloader mode. Then, the jump to the bootloader is much easier"
Can someone explain that solution to me step-by-step or show a code example?
At this time i write my exam and i am really reliant to help about this because it is only a little part with programming and i have no experience in that.
What I think User #JF002 is referring to by "backup register" is the SRAM onboard the STM32. The following has worked for me:
Configure backup registers at the beginning of the program using:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
PWR_BackupAccessCmd(ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, ENABLE);
PWR_BackupRegulatorCmd(ENABLE);
Write A_VALUE to a backup register during your program using:
(*(__IO uint32_t *) (BKPSRAM_BASE + OFFSET)) = A_VALUE;
where OFFSET is the address to write in SRAM. Use 0 for first address.
Issue a soft reset command using NVIC_SystemReset().
On boot, read (*(__IO uint32_t *) (BKPSRAM_BASE + OFFSET)) and check for A_VALUE:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
PWR_BackupAccessCmd(ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, ENABLE);
PWR_BackupRegulatorCmd(ENABLE);
void (*SysMemBootJump)(void);
volatile uint32_t addr = 0x1FFF0000; // For STM32F4 Discovery
if((*(__IO uint32_t *) (BKPSRAM_BASE + 0)) == A_VALUE)
{
(*(__IO uint32_t *) (BKPSRAM_BASE + 0)) = 0; // Reset memory, if desired.
SysMemBootJump = (void (*)(void)) (*((uint32_t *)(addr + 4))); // Set Bootloader address
__set_MSP(*(uint32_t *)addr); // Move Stack Pointer
SysMemBootJump(); // Execute Bootloader
}
else
{
RunYourApplication();
}
I have a small problem with man's answer. My problem is that there is a non-zero probability that the value of whatever memory location you pick is the same as A_VALUE when you power the system on. If that happens, then the software cannot tell whether the value that it reads (A_VALUE) is due to it having been written to the memory location prior to a soft reset, or due to random chance alone.
If the OP assumes the former, then the system starts up a bootload inappropriately with the potential of trashing the software. If he/she assumes the latter, then a required bootload will be missed. Neither is acceptable.
An improvement would be to have a more secure authentication wherein a random pattern was written to a block of memory that is saved as long as the system is powered, and a CRCC (cyclical redundancy code check) competed over that block. Then on soft reboot, the CRCC is calculated again. If the answer is still valid, the block is intact and it may be assumed that the boot was caused by a soft reboot.
Is it perfect? No, but the probability that all the bits in a block of memory bytes happens to yield the correct CRCC value is very much smaller than the probability of some small number of bits causing the value A_VALUE to be read.

serial flash emulation as EEPROM

I am developing an application on the existing board.
The application requires frequent data(just 10 bytes) storage,
So I am thinking have the External flash emulation as EEPROM
because my board doesn't have the EEPROM.We have the External spi flash is with us.
any one can help me in this emulation or please suggest me the any
other approach to full fill my application requirement.
There are a number of libraries that can do what you want. Some years ago i used the Intel library that they provided for their parallel flash chips.
The technique they use is to use additional bytes to designate which value in the flash is valid, and how many bytes the value it occupies. For example the first time a value is written the valid flag is high. When the bye is re-written, the valid flag on the old data is set low, and the new value and flag/byte count data is written in the flash immediately after the old value. When the value is read, you start at the first position, and if the valid flag is low, you use the count to move to where the newer value was stored, and so on until you find a value with the valid flag high.
When an entire sector has been used this way, you need to read the current value, erase the sector, and re-write he current value at the start.
This technique works because a flash bit can be changed form a high to low, but not changed back from a low to a high without erasing.
This explanation is a little simplified, I am sure there will be a tutorial on the web somewhere.

Can I log variable value to a file without break points in gdb?

Is it possible to log for ex: array values to a log file without using break points in gdb?
I used this:
set logging on some_file
b func
command 1
p print_clock_cycles
c
end
Aim: To log the clock cycles value to a file through gdb. The logging can be infinite so I cannot use the existing memory.
My problem: In case I am printing the clock cycles by reading a register, the value is different when printed with the above script when compared to without breakpoint (reading by some other means which I do not want to use due to memory constraints). I am assuming gdb is taking some more time to print when we have a break point which is affecting the clock cycles. I do not have any other debugger for ex jtag attached.
Is there any other means by which I can log the value?
Thanks
Do you have a serial port available? When I develop on embedded platforms, that's a good way to save debugging information.
I wrote functions to manage the serial port. My "print" functions queue up string data in a buffer, and the serial ISR drains data out of the buffer. As long as the serial port can drain the buffer fast enough it never fills up.

Resources