Environment:
Texas Instruments TM4C123FH6PM ARM Processor
Texas Instruments TM4C123GXL Launchpad Evaluation Board
Texas Instruments Code Composer Studio Version 5.5.0.00077
Emulator: Stellaris Serial In-Circuit Debugger (Launchpad only)
Blackhawk USB100v2 JTAG (Production Target)
DriverLib version: TivaWare_C_Series-2.0.1.11577
TASK:
Trying to create a protected area of flash that contains code (the MONITOR) that runs and acts as a downloader for other code (the APCODE). Once downloaded, the APCODE is then executed at a memory address defined in the APCODE (ORG address). MONITOR works fine downloading and executing the APCODE. The MONITOR is ORG’d at 0x00000000 which needs to be protected from accidental/intentional FLASH erase/write commands executed in the APCODE. To achieve this we are attempting to use the FlashProtectSet() calls from DriverLib. NOTE: We are NOT calling FlashProtectSave() in our current solution.
The solution must allow debugging with JTAG pod, reprogramming of any FLASH memory region, and finally, when running without the debugger the code must protect the MONITOR flash memory from erase or write.
ISSUE:
We are able to achieve the desired results using the launchpad board. We can protect the MONITOR and continue to develop and download code using the Stellaris (USB) Serial Debugger; however, on our target board, we are able to lock the MONITOR Flash (address 0x00000000 to address 0x000007FF) using the code below; however, unlike the launchpad board, the target board is Locked and we are unable to download any code changes using JTAG to the area of FLASH that was protected – essentially the target board is bricked w/r/t changing the first code written with the FlashProtectSet() call. Note that we can flash code changes to areas in memory that were not in the area protected by the FlashProtectSet() calls.
Note: On the lauchpad board, we have to power the board off and back on in order to continue to develop code and download it. Before powering off the lauchpad board, the compiler would try to download to the launchpad and the Complier would cause an immediate fault and not complete the download. Once this fault occurred, powering off the board and then downloading the code again “unlocked” the protection.
CODE:
Code running at 0x00000000 that was used to lock the MONITOR FLASH locations:
int protect_pages = 12; // 2k pages to protect protect base + 12*2K uint32_t protect_base = 0x0000; int c2; for (c2 = 0; c2 < protect_pages;c2++) { FlashProtectSet((protect_base+(0x800*c2)),FlashReadOnly); } FlashIntClear(FLASH_INT_PROGRAM|FLASH_INT_ACCESS); FlashIntEnable(FLASH_INT_PROGRAM|FLASH_INT_ACCESS);
At this point, we run a separate project application ORG’d at address 0x7000. This application is downloaded via the MONITOR code (which works). The monitor executes the code and it tries to erase the flash at 0x0000 .. the protection enabled at 0x00000000 works as expected and the erase call fails (the MONITOR code is unchanged).
PROBLEM:
From this point, we have been unable to program any changes to the MONITOR code at address 0x00000000 using JTAG and Code Composer. Changes above the protected fence work fine with the JTAG pod (e.g. applications ORG’d anywhere above the fence).
WE HAVE TRIED:
- Powering off target board and then re-loading code (using Code Composer Debug function and JTAG pod).
- Using the CPU and System Reset functions within Code Composer and attempting to re-loading the code with any changes to the original code written the first time (the one that is now locked into the flash). Any changes look like they downloaded to the target; however, nothing was changed. In fact, changes to the code caused issues with the debugger since the memory image was different.
- Modified the program at 0x7000 to include the following:
FlashProtectSet(0x0000,FlashReadWrite) Which runs before the FlashErase(0x0000) is called and it does not have any effect… “i.e. the flash is still protected.”
- Modified the program at 0x7000 to include the following:
FlashIntDisable(FLASH_INT_PROGRAM|FLASH_INT_ACCESS) Which runs before the FlashErase(0x0000) is called and it does not have any effect… “i.e. the flash is still protected.”
- Modified the program at 0x7000 to include this code:
static tFlashProtection tempx; tempx = FlashProtectGet(0x0000); UARTprintf("\n\rtempx = %x",tempx); FlashProtectSet(0x0000,FlashReadWrite); tempx = FlashProtectGet(0x0000); UARTprintf("\n\rtempx = %x",tempx);
The value for both print statements was “1” -- which is FlashReadOnly
BASICALLY: The processor is acting like FlashProtectSave() was run — although it was never run!!
Any assistance is appreciated.