• AVR Freaks

Hot!Multiple builds, different macros at compile time

Author
lcj
Starting Member
  • Total Posts : 51
  • Reward points : 0
  • Joined: 2003/11/07 12:41:15
  • Location: British Columbia Canada
  • Status: offline
2019/11/14 16:10:58 (permalink)
0

Multiple builds, different macros at compile time

I'm using xc8, mplabx v5.25, windows, coding for a pic18lf26k22. I need to produce several hex files each time I build, each differing only by a single variable, so passing a different -DMYMACRO=x command line argument.
 
If I were using a makefile this would be really simple, but I'm a little puzzled at how to do it in the mplabx environment. If I look in project properties, I can see the generated command line, or at least part of it. If I look at the compiler output window I can see several source files being compiled to an intermediate state with .p1 extensions; these live in the project/build/default/production directory. Most of these are small generated files (like mcc_generated_files/eccp1.p1) for setting up hardware devices, uarts, interrupts, timers, capture compare devices, memory, etc., and then my main application source file is compiled to the intermediate state too; call it application.p1. The last step is to link them all together and generate a hex file. If everybody knows this, sorry, but I'm stating it largely so I can clarify my own thoughts about how this works.
 
What I want is to do is all that, but with an extra step. My application source file should be compiled several times, each time passing a different macro value on the compiler command line, like -DMYMACRO=1, followed by compiling again with -DMYMACRO=2, and so on. Each application.p1 file would have a different name, like application1.p1, application2.p1, application3.p1 and so on. The last step in this case would be to link the standard (mcc generated) intermediate p1 files several times, once with each application file, producing a uniquely named output file, like application1.hex, application2.hex, and so on. This would be way cooler if I could specify the -DMYMACRO=x variable in the linking step; then I would only need to compile application.c to application.p1 once, and just link it several times.
 
Does that make sense? If so, how do I set up mplabx to do this? Do I have to go back to a command shell, and use xc8-cc and a makefile?
 
thanks in advance for any advice & suggestions.
#1

9 Replies Related Threads

    du00000001
    Just Some Member
    • Total Posts : 3244
    • Reward points : 0
    • Joined: 2016/05/03 13:52:42
    • Location: Germany
    • Status: online
    Re: Multiple builds, different macros at compile time 2019/11/14 16:37:13 (permalink)
    +1 (1)

    Do I have to go back ...

    Depends:
    1. If MYMACRO just results in one or more variable values differing between hex files, it's the wrong approach to build x times. Better to path the hex file.
    2. OTOH, if MYMACRO is used for conditional compilation, you need these multiple build runs. Use the makefile MPLAB generates and set up your command line make/batch processing.

    PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
    #2
    lcj
    Starting Member
    • Total Posts : 51
    • Reward points : 0
    • Joined: 2003/11/07 12:41:15
    • Location: British Columbia Canada
    • Status: offline
    Re: Multiple builds, different macros at compile time 2019/11/14 16:39:35 (permalink)
    0
    du00000001
    1. If MYMACRO just results in one or more variable values differing between hex files, it's the wrong approach to build x times. Better to path the hex file.



    This would be the situation. What is the better approach?
    #3
    du00000001
    Just Some Member
    • Total Posts : 3244
    • Reward points : 0
    • Joined: 2016/05/03 13:52:42
    • Location: Germany
    • Status: online
    Re: Multiple builds, different macros at compile time 2019/11/14 17:30:55 (permalink)
    +3 (3)
    Patch the hex file! (Sorry for the "path" typo.)
     
    1. Find the variable's address (from the map file or via the debugger)
    2. Use some tool or script to modify this location in the hex file and write a new one. This step can be repeated x times.
    Somewhere in the MPLAB directories there should be a tool called hexmate which might do the trick. But there's a lot of hexfile tools available in the net. Or you create your own fancy script- it's not too difficult as the hex files are pure ASCII. (wikipedia is good to start with:  https://en.wikipedia.org/wiki/Intel_HEX )

    PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
    #4
    oliverb
    Super Member
    • Total Posts : 245
    • Reward points : 0
    • Joined: 2009/02/16 13:12:38
    • Location: 0
    • Status: offline
    Re: Multiple builds, different macros at compile time 2019/11/15 00:25:41 (permalink)
    +1 (1)
    You can have multiple configurations in MPLAB X, and it is possible to batch-build them
    Though not batch-clean, that's broken in the versions I used.
     
    Just to clarify: it is a bit clunky because it means messing around in project options, but each configuration can have different macros defined, different source files enabled, different targets etc. There's an option to build all which will loop through each configuration in turn. There should be an option to clean all, but in MPLAB X it only cleans the selected configuration not the whole list.
     
    post edited by oliverb - 2019/11/15 01:30:27
    #5
    lcj
    Starting Member
    • Total Posts : 51
    • Reward points : 0
    • Joined: 2003/11/07 12:41:15
    • Location: British Columbia Canada
    • Status: offline
    Re: Multiple builds, different macros at compile time 2019/11/15 16:46:52 (permalink)
    0
    du00000001
    Patch the hex file! (Sorry for the "path" typo.)
     ..a tool called hexmate which might do the trick...



    This seems like the ticket, but when I try to do this, since the variable is actually a macro and can be one or two bytes (-DMYVAR=some number between 5 and 7200), the actual assembly operation is quite different once the number exceeds 255. I looked at the op codes in the assembly file, then located them in the hex file, but simply grepping for the pattern shows multiple instances of what translates to a movlw 01ch instruction. This makes patching the file tricky. I would have to call hexmate to find the instruction in a specific area of memory, and since it will move around each time the hex file is built, patching on the fly looks prone to error.
    #6
    ric
    Super Member
    • Total Posts : 24638
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: Multiple builds, different macros at compile time 2019/11/15 16:56:09 (permalink)
    0
    Could you always read the value via a function call to force it to fetch from a single location?

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #7
    jtemples
    عُضْوٌ جَدِيد
    • Total Posts : 11432
    • Reward points : 0
    • Joined: 2004/02/13 12:31:19
    • Location: Southern California
    • Status: offline
    Re: Multiple builds, different macros at compile time 2019/11/15 16:58:06 (permalink)
    +4 (4)
    Put the "some number" at a fixed location in flash, and load its value from there.  This eliminates any code changes based on the value, and you won't have to change your patch procedure when you modify the code.
    #8
    mpgmike
    Super Member
    • Total Posts : 332
    • Reward points : 0
    • Joined: 2014/01/23 17:27:06
    • Location: NJ
    • Status: offline
    Re: Multiple builds, different macros at compile time 2019/11/16 04:51:01 (permalink)
    0
    Just saw this, haven't had the opportunity to read through it yet, but it sounds like exactly what you're looking for:
     
    http://ww1.microchip.com/...eviceDoc/50002539A.pdf

    I don't need the world to know my name, but I want to live a life so all my great-grandchildren proudly remember me.
    #9
    lcj
    Starting Member
    • Total Posts : 51
    • Reward points : 0
    • Joined: 2003/11/07 12:41:15
    • Location: British Columbia Canada
    • Status: offline
    Re: Multiple builds, different macros at compile time 2019/11/19 19:31:56 (permalink)
    +1 (1)
    mpgmike
    Just saw this, haven't had the opportunity to read through it yet, but it sounds like exactly what you're looking for:
     
    http://ww1.microchip.com/...eviceDoc/50002539A.pdf



    Thanks for this, but what I'm looking for is not quite the same. The above is primarily for serialization, which doesn't fit well. In this case they're neither serial numbers, nor even sequential, and there are only a limited number (less than 10) values of interest. The sqtp idea might work, but it seems like a misguided approach, as I need several specific output files with names showing their configuration settings.
     
    I have to say there's more than one way to skin a cat. I tried my original idea, the command shell makefile approach, and it does indeed work, but du00000001, you're right, it isn't the best/right approach. In operation, it looks like a very brute-force technique; recompiling the application up to 10 times for each new release of software looks convoluted, and just cries out for a more elegant approach.
     
    If I define the macro as a 16-bit number, the code will always treat the immediate value in the assembly code as a two-byte number (the assembly code will not differ if the macro value is under 256), which makes the full range of 16-bit numbers available. This still does not solve the problem of hunting down the right two locations in the hex file, as they may be split across two lines of the file, and there's no guarantee the code sequence won't repeat more than once, or move around as development continues.
     
    jtemples and du00000001 together have the winning combination (imho). If I declare a constant, map it to a known location in its own psect (this has value for future development), then use the constant in the application code instead of a macro, a simple batch file can generate the various configuration options by calling hexmate several times. This is much faster.
     
    <edit... I thought some specifics might help out the next unwitting coder...>
     
    In the header file for the application, I added the following:
     
    #define MYCONST 20    // the original declaration.
    asm("PSECT configblk,space=0,noexec,size=0x40,optim=");
    const unsigned int __section("configblk") ruiMyVar = MYCONST;

     
    ...so I've created a psect called configblk, up to 64 bytes in size, then declared a constant unsigned int in the new psect, confgigblk, containing the default configuration value for all builds.
     
    In my source code, the value goes from
     
    void somefunction(void) {
    unsigned int uimybasevalue;
        uimybasevalue = MYCONST;
        ...
    }

    ...now becomes:
    void somefunction(void) {
    unsigned int uimybasevalue;
        uimybasevalue = ruiMyVar;    // thought this would require a far qualifier, but appears not to.
        ...
    }

     
    That gets me part way there. Next, open Project Properties, click on the "XC8 Linker" category, and add the psect with a hard-coded address via:
     
    Additional Options:
    -Wl,-Pconfigblk=00f000h/00f000h

     
    This locates the newly defined psect, configblk, at 0xf000 in the pic18's memory. The reason for this is, in future, there will be additional configuration parameters here, and I will likely need to add the ability for a user to set some of the configuration options. Flash needs to be written in page-aligned 64-byte blocks, so I've located the psect such that it will be easy to read/modify/write the block. Circling back, the reason for 00f000h/00f000h is that the first instance of the address is the runtime address, the second instance is the location within the hex file. Keeping them the same is probably not necessary, but I thought this was already complicated enough.
     
    Anyway, I can verify the constant declaration is at location 0xf000 in the hex file, which is what I want. Sooo... next step was to create a batch file to modify the hex file. Without getting into every line of it, here's an abridged version, just giving the gist:
     
    Also note, I'm running this in a subdirectory: project.x\altversions
     
    @echo off

    set source="..\dist\default\production\project.x.production.hex"
    set hexmate="c:\program files (x86)\microchip\xc8\v2.00\pic\bin\hexmate.exe"

    %hexmate% %source% -find=1400@f000-f010,replace=003c > .\project_release_option1.hex
    %hexmate% %source% -find=1400@f000-f010,replace=0078 > .\project_release_option2.hex
    ...
    %hexmate% %source% -find=1400@f000-f010,replace=1c20 > .\project_release_optionN.hex
     
    set source=""
    set hexmate=""

     
    A word of caution: hexmate requires that the -find option have the target value, in this case 0x0014, specified little endian, which is why it appears as 1400 in the above batch file snippet, but the manual does not appear to mention anywhere that the replacement value must be supplied big endian! If I wanted to replace 0x0014 with 0x0015, I would say:
     
    hexmate project.x.production.hex -find=1400@f000-f010,replace=0015 > .\project_release_option.hex

     
    So big thanks all for the suggestions, I got where I needed to be.
    #10
    Jump to:
    © 2019 APG vNext Commercial Version 4.5