This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

ImageB without OAD Target?

Other Parts Discussed in Thread: BLE-STACK

The Developer's Guide for Over Air Download for CC254x suggests in section 8.2 OAD Target Overview that:

"The other advantage of having a permanently resident Image-A which only implements the BLE-stack and OAD Target Profile is that the final customer’s Image-B does not have to include the OAD Target Profile at all, saving flash size..."

I have been trying to build an ImageB without the OAD Target, but whenever I do, the resulting hex file does not have the OAD Image Header in it.  I have tracked the difference down to calling OADTarget_AddService() or not.  If my code calls OADTarget_AddService, I get the appropriate OAD Image Header in my hex file, highlighted in yellow:

:020000040000FA
:10300000AF02FFFF0100009442424242FFFFFFFF78
:10301000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
... 

However, if I simply comment out the call to OADTarget_AddService(), I get the following in my hex file instead:

:020000040000FA
:02300000B71106
:10303000023264023C7BFFFFFFFFFFFFFFFFFFFF49
... 

Without the proper OAD Image Header, the BIM cannot checksum and launch the image properly.

What do I need to do to remove the OAD Target from my ImageB in order to save space as advertised?  I also don't want my ImageB acting as an OAD Target since I have a minimal ImageA that is OAD only and is not intended to be updated OTA.

Thanks,
-rich 

  • Hi,

    The image header data structure is defined in the oad_target.c file, so if you do not include that in your project, you must take it out and put it in some other .c file in your project. Its position is fixed to the beginning of the fwimage, so it doesn't matter which file it's in.

    Hope that helped.

  • Thanks for responding, but unfortunately it doesn't seem to help.  I am including and building oad_target.c in my project, but it doesn't include the header unless I actually have OADTarget_AddService() in my code.

    Or are you saying that I don't need to include oad_target.c at all if I copy the image header data structure to another file that is in my build, and that then I won't need to make the call to OADTarget_AddService()?

    As it turns out, I decided it would be useful to have the ImageB (my main application) be able to update my Loader (ImageA) just in case I do need to update it in the early phases of testing.  Fortunately, I was able to shrink the ImageA small enough to have enough room in my ImageB (for now) to include the OAD Target.

    Thanks,
    -rich 

  • You don't need to include oad_target.c if you don't need OAD target functionality. IAR linker will optimize out the file if it's not used anywhere. That's why it's not present unless you call OADTarget_AddService().

    All you really need is the OAD header data structure, so copy it and paste it in one of your other files. That way you avoid linking in oad_target.c unnecessarily.

    However you said you want to include OAD target functionality in ImgB anyway. In that case none of the above matters :)

  • Thank you Prashant.  

    That makes perfect sense now.  The part I didn't understand was that the compiler will optimize the entire file out if I don't directly use it, so the compiler directives to add the Image Header are not invoked.  I'm sure that knowledge will help me down the road!

    Thanks again,
    -rich 

  • Realise this is an old post, but does anyone have more details on this. I cannot get Image B to run.

    I have removed oad.h, oad_target.h, oad_target.c from the project.

    Removed the pre-processor FEATURE_OAD

    copied what I think are the relevant header structure to another source file - but no joy.
  • This is months late, but I had a similar problem. I wanted to make an imageA which contains the OAD service, but none of my application code, and an imageB which does not contain the OAD service. Image B did not run because the checksum in eeprom was FFFF. This was because the symbol _imgHdr was not present in image B, because I didn't define FEATURE_OAD for image B, therefore OADTarget_AddService was not called, which for some reason has the side effect of eliminating _imgHdr and _aesHdr from the binary, despite the #pragma required=_imgHdr directive.
    I included oad_target.c in the build, and also tried excluding it from the build and copying the _imgHdr elsewhere - none of it made any difference.
    What worked for me was to retain oad_target.c in the build, and to go the project Options, Linker section, Extra Options tab and check the "use command line options" box. Then add "-g_imgHdr", which forces the linker to include the image header even it is never referenced. I thought that was what #pragma required does, but obviously I am misunderstanding something.
  • Hi Stuart,

    Indeed I did actually resolve all this in a similar matter, like you said, the problem relates to code being optimised out, I think I ended using the #pragma required, also and moved some of the structure for image header into other sources files.

    No doubt you comments will be of use for others!

    br

    Rob
  • add“-g_aesHdr”,too. Thanks.
  • ... and change code in "oad_target.c":

    from

    static const __code aes_hdr_t _aesHdr = {

    to

    const __code aes_hdr_t _aesHdr = {

    then it works fine