Debug method - 3: get help from internet

Debug method - 3: get help from internet

Currently, I am developing a bootloader for the new project. The main functionality of bootloader is helping firmware update process. The bootloader receives the new application data and write the data to replace original application. Based on the feature, the bootloader needs at least two functionalities(1. receiving data from other storage. 2. write chunk of data to flash).

Today, I was working on second functionality which writes chunk of data to flash. There is one important constraint to understand for this process. If your application runs on flash, you would prohibit to write that area directly. Typically, during IAP(In-Application Programming), flash operation commands are stored in RAM and execute there to avoid crashing. Also, you would better to know physical constraints of flash device to implement basic operations such as write and erase.

Write operation

  • start address must be flash start address + a number of page

  • data size to write also must be align with a page size

  • Prior to write, erase must be done or all data must contain reset values

Erase operation

  • start address must be flash start address + a number of sector

  • data size to erase also must be align with a sector size

Page size and sector size can be varied by each hardware. But typically, page size is 256 bytes and sector size is 4096 bytes. Read operation does not have constraints and any location can be de-reference by pointer to read the value.

Before implement the feature from the scratch, I brainstorm what options are available.

  • Borrow the similar code base from the previous project

  • Look for vendor’s low level driver example project

My previous project is different than my current project so that I cannot apply first method. My previous project main program runs on RAM. The program was stored in flash but before jump to application, the programs are copied from flash to ram and executed. My current project main program runs on Flash.

Now, I look for the vendor’s low level driver example project. My current MCU stores all basic flash operations in boot ROM. From main application, each operations can be access via function pointer. The low level driver is already nicely interface boot ROM. I did not necessary to look up each operation’s address in reference manual.

The example code also provides multiple options to where to run. It covers my need where the application runs from the flash. I ran the example code in evaluation board and understand low level driver’s usage. I can bring most workflow from example project to my production application. I carefully move one function by one function and get all done as I expected. I compile my new test code and use a debugger to observe the result. Unfortunately, it fails!

Don’t be panic! As an engineer, keep digging until the problem goes away. First, I compare my code with an example code again. Everything looks good. Second, I check the each operation’s start address. Ah! I found the low level driver code only accepts start address as excluding flash start address. My flash start address is 0×7000 0000. I was calling function with 0×7030 0000. The driver code expects to see 0×0030 0000. After fix this part, now, I was able to erase the page! However, next step, writing the page is failed.

Writing the page function is also taking the address excluding the flash’s offset. I fixed the issues when I update erase function call. Third, I finally googling about this issue where the operation return value is general failure. Thanks god. I found the similar issue in vendor’s community forum and the post shows the solution as resolved! Guess what the solution was?

During flash operation, disable all interrupts and after flash operation, enable all interrupts again! Now, I realize the example code only demonstrates this functionality and of course there is no other interrupts in background. However, my production code runs multiple interrupts in background and during flash operation, it cause the crash.

After adding defensive code around flash operation to disable/enable interrupts, finally application is able to erase and write data as I expected!

Did you find this article valuable?

Support Hyunwoo Choi by becoming a sponsor. Any amount is appreciated!