把数组数据放到指定的 Flash 自定义 section 中:
数组定义与声明:
#define LOCATION_EXTFLASH_ATTRIBUTE __attribute__ ((section ("Myapp"))) __attribute__ ((aligned(4)))const unsigned char _aclwip_ping_bm[0x12880] LOCATION_EXTFLASH_ATTRIBUTE = {
0, 0, 0,
};
修改 scf 文件:
;Define new block m_text_data, place it at the beginning of the scf file
#define m_text_data_start 0x60030000
#define m_text_data_size 0x00013000;Place at the end of the scf file, as a new block of m_text_data
LR_m_data_text m_text_data_start m_text_data_size{ ER_m_data_text m_text_data_start FIXED m_text_data_size { ; load address = execution address*.o(Myapp)}
}
添加 flexspi 操作函数文件到工程中。
在主函数所在文件中添加:
#include "fsl_flexspi.h"
#include "app.h"
#include "fsl_cache.h"
/************************************************FlexSPI********************************************************************/
//add FlexSPI Functions
/* Program data buffer should be 4-bytes alignment, which can avoid busfault due to this memory region is configured asDevice Memory by MPU. */
SDK_ALIGN(static uint8_t s_nor_program_buffer[256], 4);
static uint8_t s_nor_read_buffer[256];extern status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address);
extern status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t dstAddr, const uint32_t *src);
extern status_t flexspi_nor_get_vendor_id(FLEXSPI_Type *base, uint8_t *vendorId);
extern status_t flexspi_nor_enable_quad_mode(FLEXSPI_Type *base);
extern status_t flexspi_nor_erase_chip(FLEXSPI_Type *base);
extern void flexspi_nor_flash_init(FLEXSPI_Type *base);
/******************************************************************************** Code******************************************************************************/
flexspi_device_config_t deviceconfig = {.flexspiRootClk = 133000000,.flashSize = FLASH_SIZE,.CSIntervalUnit = kFLEXSPI_CsIntervalUnit1SckCycle,.CSInterval = 2,.CSHoldTime = 3,.CSSetupTime = 3,.dataValidTime = 0,.columnspace = 0,.enableWordAddress = 0,.AWRSeqIndex = 0,.AWRSeqNumber = 0,.ARDSeqIndex = NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD,.ARDSeqNumber = 1,.AHBWriteWaitUnit = kFLEXSPI_AhbWriteWaitUnit2AhbCycle,.AHBWriteWaitInterval = 0,
};const uint32_t customLUT[CUSTOM_LUT_LENGTH] = {/* Normal read mode -SDR *//* Normal read mode -SDR */[4 * NOR_CMD_LUT_SEQ_IDX_READ_NORMAL] =FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x03, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),[4 * NOR_CMD_LUT_SEQ_IDX_READ_NORMAL + 1] =FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),/* Fast read mode - SDR */[4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST] =FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x0B, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),[4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST + 1] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_1PAD, 0x08, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),/* Fast read quad mode - SDR */[4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD] =FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xEB, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_4PAD, 0x18),[4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD + 1] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_4PAD, 0x06, kFLEXSPI_Command_READ_SDR, kFLEXSPI_4PAD, 0x04),/* Read extend parameters */[4 * NOR_CMD_LUT_SEQ_IDX_READSTATUS] =FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x81, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),/* Write Enable */[4 * NOR_CMD_LUT_SEQ_IDX_WRITEENABLE] =FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x06, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),/* Erase Sector */[4 * NOR_CMD_LUT_SEQ_IDX_ERASESECTOR] =FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x20, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),/* Page Program - single mode */[4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_SINGLE] =FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x02, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),[4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_SINGLE + 1] =FLEXSPI_LUT_SEQ(kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),/* Page Program - quad mode */[4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD] =FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x32, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),[4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD + 1] =FLEXSPI_LUT_SEQ(kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_4PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),/* Read ID */[4 * NOR_CMD_LUT_SEQ_IDX_READID] =FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x9F, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),/* Enable Quad mode */[4 * NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG] =FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x01, kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x04),/* Enter QPI mode */[4 * NOR_CMD_LUT_SEQ_IDX_ENTERQPI] =FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x35, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),/* Exit QPI mode */[4 * NOR_CMD_LUT_SEQ_IDX_EXITQPI] =FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_4PAD, 0xF5, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),/* Read status register */[4 * NOR_CMD_LUT_SEQ_IDX_READSTATUSREG] =FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x05, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),/* Erase whole chip */[4 * NOR_CMD_LUT_SEQ_IDX_ERASECHIP] =FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xC7, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
};/************************************************FlexSPI********************************************************************/uint8_t flespi_test()
{/************************************************FlexSPI********************************************************************/ uint32_t i = 0;status_t status;uint8_t vendorID = 0;flexspi_nor_flash_init(EXAMPLE_FLEXSPI);PRINTF("\r\nFLEXSPI example1 started!\r\n");/* Get vendor ID. */status = flexspi_nor_get_vendor_id(EXAMPLE_FLEXSPI, &vendorID);if (status != kStatus_Success){return status;}PRINTF("Vendor ID: 0x%x\r\n", vendorID);PRINTF("Enter quad mode 1\n");/* Enter quad mode. */status = flexspi_nor_enable_quad_mode(EXAMPLE_FLEXSPI);if (status != kStatus_Success){return status;}PRINTF("Enter quad mode 2\n");for(int i = 0; i<= sizeof(_aclwip_ping_bm)/SECTOR_SIZE; i++){/* Erase sectors. */PRINTF("Erasing Serial NOR over FlexSPI...\r\n");status = flexspi_nor_flash_erase_sector(EXAMPLE_FLEXSPI, APP_BASE_ADDRESS + SECTOR_SIZE * i);if (status != kStatus_Success){PRINTF("Erase sector failure !\r\n");return -1;}}for(int j = 0; j<= sizeof(_aclwip_ping_bm)/FLASH_PAGE_SIZE; j++){if(j>sizeof(_aclwip_ping_bm)/256-1){memset(s_nor_program_buffer, 0xFFU, sizeof(s_nor_program_buffer));DCACHE_InvalidateByRange(EXAMPLE_FLEXSPI_AMBA_BASE + APP_BASE_ADDRESS + FLASH_PAGE_SIZE * j, FLASH_PAGE_SIZE);memcpy(s_nor_program_buffer, &_aclwip_ping_bm[(j)*256], sizeof(_aclwip_ping_bm)%256);}else{DCACHE_InvalidateByRange(EXAMPLE_FLEXSPI_AMBA_BASE + APP_BASE_ADDRESS + FLASH_PAGE_SIZE * j, FLASH_PAGE_SIZE);memcpy(s_nor_program_buffer, &_aclwip_ping_bm[(j)*256], sizeof(s_nor_program_buffer));}status =flexspi_nor_flash_page_program(EXAMPLE_FLEXSPI, APP_BASE_ADDRESS + FLASH_PAGE_SIZE*(j), (void *)s_nor_program_buffer);if (status != kStatus_Success){PRINTF("Page program failure !\r\n");return -1;}}return 0;
}
/************************************************FlexSPI********************************************************************/
跳转函数代码:
/*******************************************Jump Function********************************************************/
#define APP_ADDR 0x60010000 //APP1 : 0x60010000 APP2 : 0x60030000typedef void (*pFunc)(void);volatile uint32_t AppAddr;
volatile uint32_t app_start_address;
pFunc JumpToApp;void jump_to_application(uint32_t applicationAddress)
{app_start_address = applicationAddress + 0x00002000;PRINTF("App Start Address : 0x%x\r\n",app_start_address);SCB->VTOR = app_start_address;AppAddr = *(uint32_t*)app_start_address;PRINTF("App Top of Stack : 0x%x\r\n",AppAddr);__set_MSP(AppAddr);AppAddr = *(uint32_t*)(app_start_address + 4);JumpToApp = (pFunc)AppAddr;JumpToApp();
}
/*******************************************Jump Function********************************************************/
主函数:
/*!* @brief Main function*/
int main(void)
{char ch;/* Init board hardware. */BOARD_ConfigMPU();BOARD_InitBootPins();BOARD_InitBootClocks();BOARD_InitDebugConsole();/* Just enable the trace clock, leave coresight initialization to IDE debugger */SystemCoreClockUpdate();CLOCK_EnableClock(kCLOCK_Trace);PRINTF("hello world.\r\n");PRINTF("0x = %x\r\n",_aclwip_ping_bm[0]);flespi_test();jump_to_application(APP_ADDR);while (1){