This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Keil uVision 5+nRF51822+BLES110 softdevice: best way to implement a checksum at compile/build time?

Hello, I have inherited a (good) project in which the previous designer implemented a checksum using a value calculated from this:

char* pMemory = 0; return crc16_ccitt(pMemory, NVS_TESTPAGE*((uint16_t)NRF_FICR->CODEPAGESIZE));

Her firmware compares this during startup against a value retrieved from flash memory. Then she designed an install process in which you (a) install the firmware, (b) run it and let it fail the checksum (which puts it into our FAULT state), (c) use a serial maintenance tool (which talks to our code which is enabled in FAULT) to query the above code, then (d) use the serial tool to send the proper checksum value back into the device to be written to flash, and when you cycle power it passes the checksum.

We are trying to streamline this process so that we dont need the serial tool (accessing the serial port has caused a manufacturing issue), and we can get the proper checksum value in there at build time (I presume she did the above because it you store it in source code, changing it changes the needed checksum and its a catch 22). I see enough hits for this to convince me it's possible, but can't find a solution that works for our compiler+target.

Can anyone recommend an approach or point me to some sample code?

Thanks VERY much for any help.

Parents
  • (this is a response to hungbui, in case I mis-posted... thank you)

    Actually thank you, I had a similar thought (just have it self-program on the first run) shortly after I hit "submit." :) So I tried exactly that, created a new flash storage item, and checked it for a NOTFIRSTRUN magic number, and if it is the first run, calc and set the CRC. That doesn't seem to work either though, here's my experience:

    I never see the FIRSTRUN logic path fire... I think this must be because my firmware actually runs once or twice before I can actually get into debug mode. Does that make sense?

    Second, even though NOTFIRSTRUN is "mysteriously" set, the subsequent CRC checks fail. My theory is that this is because the CRC calculated in debug mode is different than the CRC calculated in release mode? Does that make sense too? Can I expect this to work in release mode then?

    Also I assume that the crc calculated with this

    crc16_ccitt(pMemory, NVS_TESTPAGE*((uint16_t)NRF_FICR->CODEPAGESIZE));

    does NOT span flash memory accessed via API functions like

    ble_flash_page_write

    is that right? Otherwise her logic never would have worked, she would break the CRC every time she reconfigured.

  • It depends on how you flash and reset the chip when programming. Most likely the chip got running after you flash it, before you enter debug mode. I would suggest you to debug using UART trace instead.

    You have to make sure CRC calculation is not include the flash area that you store CRC checksum value. You can think of writing it to UICR area. What I'm seeing is that you are calculating the whole flash region with NVS_TESTPAGE*((uint16_t)NRF_FICR->CODEPAGESIZE) size. (except for UICR area)

    Running the device in debug mode should make no different with running it in normal mode in term of functionality.

Reply
  • It depends on how you flash and reset the chip when programming. Most likely the chip got running after you flash it, before you enter debug mode. I would suggest you to debug using UART trace instead.

    You have to make sure CRC calculation is not include the flash area that you store CRC checksum value. You can think of writing it to UICR area. What I'm seeing is that you are calculating the whole flash region with NVS_TESTPAGE*((uint16_t)NRF_FICR->CODEPAGESIZE) size. (except for UICR area)

    Running the device in debug mode should make no different with running it in normal mode in term of functionality.

Children
No Data
Related