Загрузка данных


u-boot=> setenv image bootloader_cm7.bin
u-boot=> setenv serverip 192.168.0.193
u-boot=> setenv ipaddr 192.168.0.200
u-boot=> tftpboot ${loadaddr} ${image}
u-boot=> mw.l 0x203c0000 0 0x10000
u-boot=> cp.b ${loadaddr} 0x203c0000 ${filesize}

M33:
>$ reboot_m7
[MONITOR] No boot_vector specified. Using default boot_vector.
MONITOR_Dispatch(608) reboot M7 (vector: 0x0)
LMM_SystemLmReset status=0

>$ cpu.r
000: m33p  => run-mode =   RUN, slp-mode =  RUN, vector = 0x00000000_00000000
001: m7p   => run-mode =   RUN, slp-mode =  RUN, vector = 0x00000000_00000000
002: a55c0 => run-mode =   RUN, slp-mode = WAIT, vector = 0x00000000_20480000
003: a55c1 => run-mode =  STOP, slp-mode =  RUN, vector = 0x00000000_00001000
004: a55c2 => run-mode =  STOP, slp-mode =  RUN, vector = 0x00000000_00001000
005: a55c3 => run-mode =  STOP, slp-mode =  RUN, vector = 0x00000000_00001000
006: a55c4 => run-mode =  STOP, slp-mode =  RUN, vector = 0x00000000_00001000
007: a55c5 => run-mode =  STOP, slp-mode =  RUN, vector = 0x00000000_00001000
008: a55p  => run-mode =   RUN, slp-mode = WAIT, vector = 0x00000000_00000000

M7 исходник(PRINTF не печатаются):
void tcm_bootloader_main(void)
{
    /* Mapping IPC structure onto DTCM memory region */
    struct rproc_update_ipc *ipc = (struct rproc_update_ipc *)(IPC_BASE_ADDR + IPC_DTCM_OFFSET);
    uint32_t current_ddr_ptr = 0x80000000U;       /* Target execution DDR memory address for M7 */
    uint32_t calculated_total_crc; /* Standard CRC32 initializtion vector */
    char ch;

    memset((void *)ipc, 0, sizeof(struct rproc_update_ipc));
    /* Clean initial state */
    ipc->magic_word = IPC_MAGIC_M7_READY;
    ipc->command = 0;
    ipc->status = STAT_IDLE;

    PRINTF("Wait U-BOOT magic_word 0x%X\r\n",IPC_MAGIC_UB_READY);
    while(ipc->magic_word != IPC_MAGIC_UB_READY) {
            __NOP();
            __NOP();
    }

    while (1)
    {
        ch = GETCHAR();
        PUTCHAR(ch);
    }

    PRINTF("U-BOOT magic_word 0x%X become success\r\n",IPC_MAGIC_UB_READY);
    calculated_total_crc = 0xFFFFFFFFU;
    while(1) {
        /* Force volatile read of the command flag to prevent compiler optimization loops */
        uint32_t cmd = *(volatile uint32_t *)&(ipc->command);
#if 0
        if(ipc->magic_word != IPC_MAGIC_UB_READY) {
            ipc->status = STAT_ERROR;
            break;
        }

        if (cmd == CMD_DATA_READY) {
            PRINTF("Have CMD_DATA_READY from U-BOOT\r\n");
            ipc->status = STAT_BUSY;
            __DSB(); /* Ensure status write completes before processing data */
            /* Safe memory block copy from TCM communication buffer to target DDR location */
            memcpy((void *)current_ddr_ptr, (const void *)ipc->buffer, ipc->chunk_size);
            /* Feed the chunk into the continuous stream CRC32 accumulator */
#if 0
            calculated_total_crc = calculate_crc32(calculated_total_crc, (const uint8_t *)ipc->buffer, ipc->chunk_size);
#endif
            /* Advance the DDR pointer forward by the size of the written chunk */
            current_ddr_ptr += ipc->chunk_size;
            
            /* Data Synchronization Barrier: Ensure all bus transaction write cycles to DDR are complete */
            __DSB(); __ISB();

            /* Signal U-Boot that the data chunk has been acknowledged and saved */
            ipc->command = 0;
            ipc->status = STAT_ACK;
            __DSB();
        } 
        else if (cmd == CMD_VERIFY_CRC) {
            PRINTF("Have CMD_VERIFY_CRC from U-BOOT\r\n");
            ipc->status = STAT_BUSY;
            __DSB();
            calculated_total_crc = calculated_total_crc ^ 0xFFFFFFFFU;
            if (calculated_total_crc == ipc->expected_crc) {
                PRINTF("CRC is ok\r\n");
#if 0
                /* Flush and clean Data Cache for the loaded firmware region in DDR */
                SCB_CleanDCache_by_Addr((void *)0x80000000U, (current_ddr_ptr - 0x80000000U));
                /* Invalidate Instruction Cache to force CPU reload instructions from modified DDR memory */
                SCB_InvalidateICache();
                __DSB();
                __ISB();
                /* Fetch the entry point address (Reset Handler) from the Application Vector Table */
                uint32_t jump_address = *(volatile uint32_t *)(0x80000004U);

                /* CRITICAL FOR CORTEX-M: Force the least significant bit (LSB) to 1.
                   This signals the ARM core to enter Thumb-2 state execution mode, preventing HardFaults. */
                jump_address |= 1U; 
                
                void (*entry_point)(void) = (void (*)(void))jump_address;

                /* Respond to the host with final ACK status before relinquishing control */
                ipc->command = 0;
                ipc->status = STAT_ACK;
                __DSB(); __ISB();

                /* Relocate Vector Table Offset Register (VTOR) to point to the base of DDR application */
                SCB->VTOR = 0x80000000U;

                /* Load Main Stack Pointer (MSP) from the very first word of the firmware binary */
                __set_MSP(*(volatile uint32_t *)(0x80000000U));
                
                /* Branch execution context directly to the application entry point */
                entry_point();
#else
                /* Respond to the host with final ACK status before relinquishing control */
                ipc->command = 0;
                ipc->status = STAT_ACK;
                __DSB(); __ISB();

                PRINTF("Try start M7 from DDR\r\n");
                while(1) {
                    __NOP();
                    __NOP();
                };
#endif
            } else {
                /* CRC Mismatch Error state handling */
                PRINTF("CRC Mismatch Error 0x%X != 0x%X\r\n",calculated_total_crc,ipc->expected_crc);
                ipc->command = 0;
                ipc->status = STAT_ERROR;
                __DSB();

                /* Reset internal tracking states to allow recovery or retry firmware transmission */
                calculated_total_crc = 0xFFFFFFFFU;
                current_ddr_ptr = 0x80000000U;
            }
        }
        else {
            /* Low-Power Optimization for Bare-metal: 
               Puts the Cortex-M7 core into sleep state until any hardware interrupt occurs 
               (e.g., Systick, MU Mailbox, or Timer interrupt). Prevents pinning the CPU to 100%. */
            __NOP();
            __NOP(); 
        }
#endif
    }
    return;
}

/*!
 * @brief Main function
 */
int main(void)
{
    /* Init board hardware. */
    BOARD_InitHardware();
    PRINTF("MCUX SDK version: %s\r\n", MCUXSDK_VERSION_FULL_STR);
    PRINTF("Bootloader.\r\n");

    tcm_bootloader_main();
}