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.

Share Flash Erase settings with team

Other Parts Discussed in Thread: CCSTUDIO, TM4C129XNCZAD

I'm working with two images in Flash: a bootloader and an application.

When debugging one, I don't want to erase the other, so in each project's properties (Debug, Flash Settings, Erase) I changed "Entire Flash" to "By Address Range".

This works fine for me, but not for other people in the team, because this setting is stored in a .launch file which is excluded from version control as it contains developer-specific paths etc.

Does anyone know a different way to store/specify this?

I'm considering writing a script (to run as a pre-build step) to inspect the .launch file but this seems extreme...

  • Hello,

    We have typically not recommended that .launch files be added to version control due to lack of portability. However, we have made improvements in this area with recent CCS versions. If your launch configuration file does not have any absolute paths and such, then it is likely ok to share that file. I'll to confirm this myself.

    Thanks

    ki

  • Thanks Ki.  My .launch file does contain absolute paths, and other developer-specific things such as display options for the Memory Browser.

    I'm using CCS 8.3.1 for this project but for another project I use CCS 10.4 and I can see absolute paths are still present in the .launch file it generates.

    Do you know if the settings in the .launch file are accessible as (or through) variables that I could access from a script?  The relevant node in the .launch file has a "key" attribute with a value beginning "com.ti.ccstudio.debug.debugModel.ATTR_DEBUGGER_PROPERTIES.".

  • Do you know if the settings in the .launch file are accessible as (or through) variables that I could access from a script?

    There are some variables that can be used in more recent CCS versions. When these later versions of CCS auto-generate a project .launch file, it should use them. Can you share your .launch file? I'd like to take a look.

    Thanks

    ki

  • Thanks Ki.

    Here's the .launch file for my CCS 8.3.1 project.

    (Drag and drop didn't seem to work, so I've just pasted the content below.)

    Malcolm

    -- 

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <launchConfiguration type="com.ti.ccstudio.debug.launchType.device.debugging">
    <stringAttribute key="com.ti.ccstudio.debug.debugModel.ATTR_DEBUGGER_PROPERTIES.C:\Users\Malcolm\source\customer055\wimBootLoader\targetConfigs\Tiva TM4C129XNCZAD.ccxml.Texas Instruments XDS2xx USB Debug Probe/CORTEX_M4_0" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot; ?&gt;&#10;&lt;PropertyValues&gt;&#10;&#10; &lt;property id=&quot;ConnectOnStartup&quot;&gt;&#10; &lt;curValue&gt;1&lt;/curValue&gt;&#10; &lt;/property&gt;&#10;&#10; &lt;property id=&quot;EnableInstalledBreakpoint&quot;&gt;&#10; &lt;curValue&gt;1&lt;/curValue&gt;&#10; &lt;/property&gt;&#10;&#10; &lt;property id=&quot;IgnoreSoftLaunchFailures&quot;&gt;&#10; &lt;curValue&gt;0&lt;/curValue&gt;&#10; &lt;/property&gt;&#10;&#10; &lt;property id=&quot;FlashEraseType&quot;&gt;&#10; &lt;curValue&gt;By Address Range&lt;/curValue&gt;&#10; &lt;/property&gt;&#10;&#10; &lt;property id=&quot;FlashEraseEndAddr&quot;&gt;&#10; &lt;curValue&gt;7FFF&lt;/curValue&gt;&#10; &lt;/property&gt;&#10;&#10; &lt;property id=&quot;FlashDebugPortUnlockChoice&quot;&gt;&#10; &lt;curValue&gt;Fury, DustDevil, and Tiva Classes&lt;/curValue&gt;&#10; &lt;/property&gt;&#10;&#10; &lt;property id=&quot;FlashVerboseMode&quot;&gt;&#10; &lt;curValue&gt;1&lt;/curValue&gt;&#10; &lt;/property&gt;&#10;&#10;&lt;/PropertyValues&gt;&#10;"/>
    <stringAttribute key="com.ti.ccstudio.debug.debugModel.ATTR_PROGRAM.C:\Users\Malcolm\source\customer055\wimBootLoader\targetConfigs\Tiva TM4C129XNCZAD.ccxml.Texas Instruments XDS2xx USB Debug Probe/CORTEX_M4_0" value="${build_artifact:wimBootLoader}"/>
    <stringAttribute key="com.ti.ccstudio.debug.debugModel.ATTR_PROJECT.C:\Users\Malcolm\source\customer055\wimBootLoader\targetConfigs\Tiva TM4C129XNCZAD.ccxml.Texas Instruments XDS2xx USB Debug Probe/CORTEX_M4_0" value="wimBootLoader"/>
    <stringAttribute key="com.ti.ccstudio.debug.debugModel.ATTR_TARGET_CONFIG" value="${target_config_active_default:wimBootLoader}"/>
    <stringAttribute key="com.ti.ccstudio.debug.debugModel.MRU_PROGRAM.C:\Users\Malcolm\source\customer055\wimBootLoader\targetConfigs\Tiva TM4C129XNCZAD.ccxml.Texas Instruments XDS2xx USB Debug Probe/CORTEX_M4_0" value="C:/Users\Malcolm\source\customer055\wimBootLoader\Debug\wimBootLoader.out"/>
    <mapAttribute key="com.ti.ccstudio.debug.ui.displayFormats">
    <mapEntry key="Texas Instruments XDS2xx USB Debug Probe/CORTEX_M4_0@##separator##@0" value="8-Bit Hex - TI Style"/>
    </mapAttribute>
    <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
    <listEntry value="/wimBootLoader"/>
    </listAttribute>
    <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
    <listEntry value="4"/>
    </listAttribute>
    <stringAttribute key="org.eclipse.debug.core.source_locator_id" value="com.ti.ccstudio.debug.sourceLocator"/>
    <stringAttribute key="org.eclipse.debug.core.source_locator_memento" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;sourceLookupDirector&gt;&#13;&#10;&lt;sourceContainers duplicates=&quot;false&quot;&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;default/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.debug.core.containerType.default&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;cpuSpecificContainer cpuName=&amp;quot;Texas Instruments XDS2xx USB Debug Probe/CORTEX_M4_0&amp;quot;&amp;gt;&amp;#13;&amp;#10;&amp;lt;childContainerEntry childMemento=&amp;quot;&amp;amp;lt;?xml version=&amp;amp;quot;1.0&amp;amp;quot; encoding=&amp;amp;quot;UTF-8&amp;amp;quot; standalone=&amp;amp;quot;no&amp;amp;quot;?&amp;amp;gt;&amp;amp;#13;&amp;amp;#10;&amp;amp;lt;project name=&amp;amp;quot;wimBootLoader&amp;amp;quot; referencedProjects=&amp;amp;quot;true&amp;amp;quot;/&amp;amp;gt;&amp;amp;#13;&amp;amp;#10;&amp;quot; childType=&amp;quot;org.eclipse.debug.core.containerType.project&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&amp;lt;childContainerEntry childMemento=&amp;quot;&amp;amp;lt;?xml version=&amp;amp;quot;1.0&amp;amp;quot; encoding=&amp;amp;quot;UTF-8&amp;amp;quot; standalone=&amp;amp;quot;no&amp;amp;quot;?&amp;amp;gt;&amp;amp;#13;&amp;amp;#10;&amp;amp;lt;default/&amp;amp;gt;&amp;amp;#13;&amp;amp;#10;&amp;quot; childType=&amp;quot;org.eclipse.debug.core.containerType.default&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&amp;lt;childContainerEntry childMemento=&amp;quot;&amp;amp;lt;?xml version=&amp;amp;quot;1.0&amp;amp;quot; encoding=&amp;amp;quot;UTF-8&amp;amp;quot; standalone=&amp;amp;quot;no&amp;amp;quot;?&amp;amp;gt;&amp;amp;#13;&amp;amp;#10;&amp;amp;lt;productsSource/&amp;amp;gt;&amp;amp;#13;&amp;amp;#10;&amp;quot; childType=&amp;quot;com.ti.ccstudio.debug.containerType.products.source&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&amp;lt;childContainerEntry childMemento=&amp;quot;&amp;amp;lt;?xml version=&amp;amp;quot;1.0&amp;amp;quot; encoding=&amp;amp;quot;UTF-8&amp;amp;quot; standalone=&amp;amp;quot;no&amp;amp;quot;?&amp;amp;gt;&amp;amp;#13;&amp;amp;#10;&amp;amp;lt;deviceLibrarySource/&amp;amp;gt;&amp;amp;#13;&amp;amp;#10;&amp;quot; childType=&amp;quot;com.ti.ccstudio.debug.containerType.device.library.source&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&amp;lt;childContainerEntry childMemento=&amp;quot;&amp;amp;lt;?xml version=&amp;amp;quot;1.0&amp;amp;quot; encoding=&amp;amp;quot;UTF-8&amp;amp;quot; standalone=&amp;amp;quot;no&amp;amp;quot;?&amp;amp;gt;&amp;amp;#13;&amp;amp;#10;&amp;amp;lt;librarySource/&amp;amp;gt;&amp;amp;#13;&amp;amp;#10;&amp;quot; childType=&amp;quot;com.ti.ccstudio.debug.containerType.library.source&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&amp;lt;/cpuSpecificContainer&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;com.ti.ccstudio.debug.containerType.cpu.specific&quot;/&gt;&#13;&#10;&lt;/sourceContainers&gt;&#13;&#10;&lt;/sourceLookupDirector&gt;&#13;&#10;"/>
    <stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;memoryBlockExpressionList context=&quot;reserved-for-future-use&quot;/&gt;&#13;&#10;"/>
    </launchConfiguration>

  • Can you send the one from 10.4 also?

  • OK, here's the 10.4 .launch file (for a different project).

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <launchConfiguration type="com.ti.ccstudio.debug.launchType.device.debugging">
    <mapAttribute key="ccs.memoryview.format">
    <mapEntry key="org.eclipse.cdt.debug.ui.memory.memorybrowser.MemoryBrowser@#$Texas Instruments XDS110 USB Debug Probe/Cortex_M3_0@#$0" value="8-Bit Hex - TI Style"/>
    </mapAttribute>
    <mapAttribute key="ccs.memoryview.pageexpr">
    <mapEntry key="org.eclipse.cdt.debug.ui.memory.memorybrowser.MemoryBrowser@#$Texas Instruments XDS110 USB Debug Probe/Cortex_M3_0" value="@@outPacket"/>
    </mapAttribute>
    <stringAttribute key="com.ti.ccstudio.debug.debugModel.ATTR_DEBUGGER_PROPERTIES.CC1310F128.ccxml.Texas Instruments XDS110 USB Debug Probe/Cortex_M3_0" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot; ?&gt;&#10;&lt;PropertyValues&gt;&#10;&#10; &lt;property id=&quot;ConnectOnStartup&quot;&gt;&#10; &lt;curValue&gt;1&lt;/curValue&gt;&#10; &lt;/property&gt;&#10;&#10; &lt;property id=&quot;EnableInstalledBreakpoint&quot;&gt;&#10; &lt;curValue&gt;1&lt;/curValue&gt;&#10; &lt;/property&gt;&#10;&#10; &lt;property id=&quot;IgnoreSoftLaunchFailures&quot;&gt;&#10; &lt;curValue&gt;0&lt;/curValue&gt;&#10; &lt;/property&gt;&#10;&#10;&lt;/PropertyValues&gt;&#10;"/>
    <setAttribute key="com.ti.ccstudio.debug.debugModel.ATTR_HIDE_CONFIG_ELEMENT_TYPES">
    <setEntry value="BOARD"/>
    <setEntry value="BYPASSED_CPU"/>
    <setEntry value="BYPASSED_ROUTER"/>
    <setEntry value="CONNECTION"/>
    <setEntry value="DEVICE"/>
    <setEntry value="NON_DEBUG_CPU"/>
    <setEntry value="NO_DRIVER"/>
    <setEntry value="ROUTER"/>
    <setEntry value="SUBPATH"/>
    <setEntry value="SYSTEM"/>
    </setAttribute>
    <stringAttribute key="com.ti.ccstudio.debug.debugModel.ATTR_PROGRAM.CC1310F128.ccxml.Texas Instruments XDS110 USB Debug Probe/Cortex_M3_0" value="${build_artifact:Customer11}"/>
    <stringAttribute key="com.ti.ccstudio.debug.debugModel.ATTR_PROJECT.CC1310F128.ccxml.Texas Instruments XDS110 USB Debug Probe/Cortex_M3_0" value="Customer11"/>
    <stringAttribute key="com.ti.ccstudio.debug.debugModel.ATTR_TARGET_CONFIG" value="${target_config_active_default:Customer11}"/>
    <stringAttribute key="com.ti.ccstudio.debug.debugModel.MRU_PROGRAM.CC1310F128.ccxml.Texas Instruments XDS110 USB Debug Probe/Cortex_M3_0" value="C:\Users\Malcolm\source\repos\OTA\Customer11\Board1_A_Debug\Customer11.out"/>
    <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
    <listEntry value="/Customer11"/>
    </listAttribute>
    <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
    <listEntry value="4"/>
    </listAttribute>
    <stringAttribute key="org.eclipse.debug.core.source_locator_id" value="com.ti.ccstudio.debug.sourceLocator"/>
    <stringAttribute key="org.eclipse.debug.core.source_locator_memento" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;sourceLookupDirector&gt;&#13;&#10;&lt;sourceContainers duplicates=&quot;false&quot;&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;default/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.debug.core.containerType.default&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;cpuSpecificContainer cpuName=&amp;quot;Texas Instruments XDS110 USB Debug Probe/Cortex_M3_0&amp;quot;&amp;gt;&amp;#13;&amp;#10;&amp;lt;childContainerEntry childMemento=&amp;quot;&amp;amp;lt;?xml version=&amp;amp;quot;1.0&amp;amp;quot; encoding=&amp;amp;quot;UTF-8&amp;amp;quot; standalone=&amp;amp;quot;no&amp;amp;quot;?&amp;amp;gt;&amp;amp;#13;&amp;amp;#10;&amp;amp;lt;project name=&amp;amp;quot;Customer11&amp;amp;quot; referencedProjects=&amp;amp;quot;true&amp;amp;quot;/&amp;amp;gt;&amp;amp;#13;&amp;amp;#10;&amp;quot; childType=&amp;quot;org.eclipse.debug.core.containerType.project&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&amp;lt;childContainerEntry childMemento=&amp;quot;&amp;amp;lt;?xml version=&amp;amp;quot;1.0&amp;amp;quot; encoding=&amp;amp;quot;UTF-8&amp;amp;quot; standalone=&amp;amp;quot;no&amp;amp;quot;?&amp;amp;gt;&amp;amp;#13;&amp;amp;#10;&amp;amp;lt;default/&amp;amp;gt;&amp;amp;#13;&amp;amp;#10;&amp;quot; childType=&amp;quot;org.eclipse.debug.core.containerType.default&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&amp;lt;childContainerEntry childMemento=&amp;quot;&amp;amp;lt;?xml version=&amp;amp;quot;1.0&amp;amp;quot; encoding=&amp;amp;quot;UTF-8&amp;amp;quot; standalone=&amp;amp;quot;no&amp;amp;quot;?&amp;amp;gt;&amp;amp;#13;&amp;amp;#10;&amp;amp;lt;productsSource/&amp;amp;gt;&amp;amp;#13;&amp;amp;#10;&amp;quot; childType=&amp;quot;com.ti.ccstudio.debug.containerType.products.source&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&amp;lt;childContainerEntry childMemento=&amp;quot;&amp;amp;lt;?xml version=&amp;amp;quot;1.0&amp;amp;quot; encoding=&amp;amp;quot;UTF-8&amp;amp;quot; standalone=&amp;amp;quot;no&amp;amp;quot;?&amp;amp;gt;&amp;amp;#13;&amp;amp;#10;&amp;amp;lt;deviceLibrarySource/&amp;amp;gt;&amp;amp;#13;&amp;amp;#10;&amp;quot; childType=&amp;quot;com.ti.ccstudio.debug.containerType.device.library.source&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&amp;lt;childContainerEntry childMemento=&amp;quot;&amp;amp;lt;?xml version=&amp;amp;quot;1.0&amp;amp;quot; encoding=&amp;amp;quot;UTF-8&amp;amp;quot; standalone=&amp;amp;quot;no&amp;amp;quot;?&amp;amp;gt;&amp;amp;#13;&amp;amp;#10;&amp;amp;lt;librarySource/&amp;amp;gt;&amp;amp;#13;&amp;amp;#10;&amp;quot; childType=&amp;quot;com.ti.ccstudio.debug.containerType.library.source&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&amp;lt;/cpuSpecificContainer&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;com.ti.ccstudio.debug.containerType.cpu.specific&quot;/&gt;&#13;&#10;&lt;/sourceContainers&gt;&#13;&#10;&lt;/sourceLookupDirector&gt;&#13;&#10;"/>
    <stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;memoryBlockExpressionList context=&quot;reserved-for-future-use&quot;/&gt;&#13;&#10;"/>
    </launchConfiguration>

  • Thanks. I see one absolute path to the out file. When you actually look at the launch properties in the IDE, is the out file referenced with an absolute path there also?

  • Hi Ki, I can see a mixture of absolute and variable-dependent paths when I do Project Properties, Build, Variables and select "Show System".

    For example, in this screenshot, the OUT file name (BuildArtifactFileName) depends on ${ProjName} but the full path to the OUT file (BuildArtifactFilePath) is already resolved to my system.

    Is this what you meant by "look at the launch properties"?

    By the way, we are moving the CCS 8 project to CCS 10.4.  I hope there will be a way to make the .launch file user-independent because my CCS 8 work-around (a pre-build script which fails if the launch file doesn't have the correct FlashEraseEndAddr etc.) does not stop the build in CCS 10.  (This might be a by-design Eclipse behaviour, although it did work in CCS 8...)

    Malcolm

  • Can you take a look at the actual launch properties of the project?

    Go to: Run -> Debug Configurations

    Then select the configuration for your project in the left panel and in the right panel, check the various settings to see if absolute paths are used anywhere:

  • Thanks for the instructions Ki.  I think I haven't used that dialog before.

    I do not see any absolute paths in there (except RTS Library in the Source tab).

    Malcolm

  • I do not see any absolute paths in there (except RTS Library in the Source tab).

    Those are expected.

    So I experimented a bit and it looks like with recent version of CCS, the project .launch file can be shared. When I imported projects from one machine to another, the settings in the launch config file were picked up on the other machine. I also had an absolute path in the launch file but that was automatically updated to match the new environment when I started a debug session. 

    I believe the key is to not have any absolute paths when viewing the debug launch configuration in the CCS GUI. If variables (like $(build_artifact) ) are used instead, then you should be good to go.

    Please see the below link for more details on using such variables in your debug launch config:

    https://software-dl.ti.com/ccs/esd/documents/ccs_portable-projects.html#debug-configurations

    Thanks

    ki

  • Thanks Ki.  I appreciate your time and effort investigating this.

    However, the .launch file still seems non-ideal to share as it will frequently show up as a changed file (for example, when you change the address or format of the Memory Browser), and each developer will have to remember to not commit those changes (if we're striving for clean patches).

    I currently have a low-tech workaround which is a post-build step to check particular settings exist in the .launch file.  I'll post details later.

    Malcolm 

  • However, the .launch file still seems non-ideal to share as it will frequently show up as a changed file (for example, when you change the address or format of the Memory Browser), and each developer will have to remember to not commit those changes (if we're striving for clean patches).

    Yes you do raise a good point regarding version control

    I currently have a low-tech workaround which is a post-build step to check particular settings exist in the .launch file.  I'll post details later.

    Nice. Looking forward to hearing about the details

    ki

  • Here's my low-tech work-around.  It's not fool-proof but it seems to be working OK for myself and the team.

    Step 1.  Add a script to the project folder.  My team exclusively uses Windows so I've used a batch script named check-flash-erase-range.bat.  The contents are:

    :: Check that the .launch file specifies the correct range of Flash to erase before programming.
    :: The .launch file is developer-specific so is not under version control.
    :: The default CCS behaviour is to erase the entire Flash before programming.
    :: The bootloader occupies the first page so we must not erase it.
    
    findstr "FlashEraseType" %1 | findstr /m /i "By Address Range" > nul
    IF %ERRORLEVEL% NEQ 0 GOTO :fail
    
    findstr "FlashEraseStartAddr" %1 | findstr /m /i 1234 > nul
    IF %ERRORLEVEL% NEQ 0 GOTO :fail
    
    :: Both checks succeeded.
    Echo     ----
    Echo     Flash erase range is correct.
    Echo     ----
    EXIT/B 0
    
    :fail
    Echo     ----
    Echo     Error: The Flash erase range is incorrect or not set.  In Project Properties, Debug, Flash Settings, Erase, select "By Address Range" (0x1234 to 0x5678).
    :: The line above is for the CCS "Problems" tab.  The following lines are for the "Console" tab, which is more readable.
    Echo     In Code Composer Studio, edit the Project Properties.
    Echo     Under Debug, go to Flash Settings, Erase and select "By Address Range".
    Echo     Set the Start Address to 0x1234, and the End Address to 0x5678.
    Echo     This ensures that the bootloader is not erased by programming the application.
    Echo     ----
    EXIT /B 1
    

    Note: replace "1234" and "5678" with the relevant addresses for your project.

    Step 2.  Add the following line to the post-build steps in the Build Properties.  (Note: it must be POST-build because pre-build step failures do not stop the build.)

    call "${ProjDirPath}/check-flash-erase-range.bat" "..\\.launches\\${ProjName}.launch"

    Note the mixture of Linux and Windows path separators.  This is what worked for me.

    Note: the above steps are for the application project.  You need to do something similar for the bootloader project, but searching for "FlashEraseEndAddr" instead.