manikandan
Member
Hello,
I’m working on implementing Device Firmware Update (DFU) on the Teensy 4.0. In my primary firmware, I attempt to launch a secondary firmware image located at an offset within the flash memory using the following code:
To verify a valid image and jump to it:
For the secondary application, I’ve configured the linker script to build it at 0x60100000 (i.e., 1MB into flash). I then attempt to launch it from the primary firmware using:
runApp(0x100000);
When compiling, I get the following error:
src\main.cpp:63:3: error: 'SCB' was not declared in this scope; did you mean 'SCL'?
If I comment out or remove the disableCache() function, the firmware continues to execute from the default flash address instead of jumping to the new address.
I suspect this could be due to either:
i have uploaded the custom linker script shortly for your review. Please let me know if you notice any issues or missing elements that may cause this behavior.
This is the thread i have refered for this:
I’m working on implementing Device Firmware Update (DFU) on the Teensy 4.0. In my primary firmware, I attempt to launch a secondary firmware image located at an offset within the flash memory using the following code:
C:
#if 1
FLASHMEM void disableCache() {
// Disable Data and Instruction caches, and the MPU
SCB_MPU_CTRL = 0; // Turn off MPU
SYST_CSR = 0; // Disable SysTick
// Disable all interrupts
for (int i = 0; i < NVIC_NUM_INTERRUPTS; i++) {
NVIC_DISABLE_IRQ(i);
}
// Disable D-Cache
SCB->CSSELR = 0U;
asm("dsb");
SCB->CCR &= ~(uint32_t)SCB_CCR_DC_Msk;
asm("dsb");
// Clean & Invalidate D-Cache
uint32_t ccsidr = SCB->CCSIDR;
uint32_t sets = CCSIDR_SETS(ccsidr);
do {
uint32_t ways = CCSIDR_WAYS(ccsidr);
do {
SCB->DCCISW = (sets << SCB_DCCISW_SET_Pos) | (ways << SCB_DCCISW_WAY_Pos);
} while (--ways);
} while (--sets);
asm("dsb");
asm("isb");
// Disable I-Cache
SCB->CCR &= ~(uint32_t)SCB_CCR_IC_Msk;
SCB->ICIALLU = 0UL;
asm("dsb");
asm("isb");
}
#endif
To verify a valid image and jump to it:
C:
const uint32_t FLASH_BASEADDRESS = 0x60000000;
bool checkForValidImage(uint32_t addressInFlash) {
uint32_t SPIFlashConfigMagicWord = *((uint32_t*)addressInFlash);
uint32_t VectorTableMagicWord = *((uint32_t*)(addressInFlash + 0x1000));
if ((SPIFlashConfigMagicWord == 0x42464346) && (VectorTableMagicWord == 0x432000D1))
return true;
Serial.println("Invalid magic numbers, no flash image found");
return false;
}
typedef void (*pFunction)(void);
FLASHMEM bool runApp(uint32_t offsetFromStart) {
uint32_t imageStartAddress = FLASH_BASEADDRESS + offsetFromStart;
if (!checkForValidImage(imageStartAddress)) {
while (true) {
Serial.printf("No valid image found at 0x%08X\r\n", imageStartAddress);
delay(1000);
}
}
uint32_t firstInstructionPtr = imageStartAddress + 0x1000 + sizeof(uint32_t);
Serial.printf("First instruction pointer is at address 0x%08X\r\n", firstInstructionPtr);
uint32_t firstInstructionAddr = *(uint32_t*)firstInstructionPtr;
#if 1
if ((firstInstructionAddr < (imageStartAddress + 0x1000)) || (firstInstructionAddr > (imageStartAddress + 0x3000))) {
while (true) {
Serial.printf("Address of first instruction %08X is not valid. The image may have been built incorrectly.\r\n", firstInstructionAddr);
}
}
#endif
Serial.printf("Jumping to code at 0x%08X\r\n", firstInstructionAddr);
delay(10);
pFunction Target_Code_Address = (pFunction)firstInstructionAddr;
Target_Code_Address();
while (true) {
Serial.println("Execution returned unexpectedly.");
delay(1000);
}
}
For the secondary application, I’ve configured the linker script to build it at 0x60100000 (i.e., 1MB into flash). I then attempt to launch it from the primary firmware using:
runApp(0x100000);
Issue Encountered
When compiling, I get the following error:
src\main.cpp:63:3: error: 'SCB' was not declared in this scope; did you mean 'SCL'?
If I comment out or remove the disableCache() function, the firmware continues to execute from the default flash address instead of jumping to the new address.
I suspect this could be due to either:
- A missing or incorrect include for CMSIS system registers (SCB), i have tired including #include "core_cm7.h" but it seems teensy does not support that
- A configuration issue in the linker script or memory alignment.
i have uploaded the custom linker script shortly for your review. Please let me know if you notice any issues or missing elements that may cause this behavior.
This is the thread i have refered for this: