I.MXRT FreeRTOS环境下擦写外部Flash

在freertos环境下,如果外部擦写 flash,禁用指令缓存以避免在多个任务中使用来自flash 的分支预测和应用程序同步操作 flash的缓存预加载指令。因为代码是xip,所以向量表也在flash 中。所以,当发生中断时,内核将读取此中断向量表。如果同时,flash闪存被编程写入,读取操作将失败。用户通过禁用中断来保护关键代码,以避免这种情况。
    使用 taskenter/exit_critical() 函数,最后它会调用如下图这个函数vportraisebasepri。该函数只能禁用优先级低于configmax_syscall_interrupt_priority的中断,这可以确保系统仍然可以工作。因此,需要检查所有其他外设中断的优先级,比如lcdipv2_irqn,lpuart,lpspi 等等。要确保优先级低于configmax_syscall_interrupt_priority,或将configmax_syscall_interropt_priority配置为更高的优先级。
不需要逐一禁用所有irq。因此,如果使用上述方式还有问题,请尝试如下api:
__set_primask(1);//关闭总中断
//擦,写,读 flash//
__set_primask(0);//开启总中断
    参考示例代码:
/* freertos kernel includes. */
#include freertos.h
#include task.h
#include queue.h
#include timers.h
/* freescale includes. */
#include fsl_device_registers.h
#include fsl_debug_console.h
#include fsl_flexspi.h
#include pin_mux.h
#include clock_config.h
#include board.h
#include app.h
#include fsl_common.h
/* task priorities. */
#define hello_task_priority           (configmax_priorities - 2)
#define flash_operation_task_priority (configmax_priorities - 1)
static void hello_task(void *pvparameters);
static void flash_operation_task(void *pvparameters);
status_t flexspi_nor_flash_read_sector(flexspi_type *base, uint32_t address, const uint32_t *src, size_t leng);
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 void flexspi_nor_flash_init(flexspi_type *base);
extern void flexspi_clear_buffer(flexspi_type *base);
flexspi_device_config_t deviceconfig = {
    .flexspirootclk       = 12000000,
    .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,
};
constuint32_tcustomlut[custom_lut_length]={
    /* 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, 0xd7, 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),
};
int main(void)
{
    /* init board hardware. */
    board_configmpu();
    board_initpins();
    board_bootclockrun();
    board_initdebugconsole();
    printf(flash operation on freertos in xip mode! );
    if (xtaskcreate(hello_task, hello_task, configminimal_stack_size + 100, null, hello_task_priority, null) !=
        pdpass)
    {
        printf(task creation failed!. );
        while (1)
            ;
    }
    if (xtaskcreate(flash_operation_task, flash_operation_task, configminimal_stack_size + 800, null,
                    flash_operation_task_priority, null) != pdpass)
    {
        printf(task creation failed!. );
        while (1)
            ;
    }
    vtaskstartscheduler();
    for (;;)
        ;
}
static void hello_task(void *pvparameters)
{
    for (;;)
    {
        printf(hello world. );
        /* delay 2s */
        vtaskdelay(2 * configtick_rate_hz);
    }
}
static void flash_operation_task(void *pvparameters)
{
    status_t status;
    uint8_t vendorid = 0;
    /*programe buffer must be 4 and 4's multiplier bytes alignment */
    uint8_t *nor_program_buffer = pvportmalloc(256);
    if (null == nor_program_buffer)
    {
        printf(nor_program_buffer memory allocation failed! );
        configassert(null);
    }
    uint8_t *nor_read_buffer = pvportmalloc(256);
    if (null == nor_read_buffer)
    {
        printf(nor_read_buffer memory allocation failed! );
        configassert(null);
    }
    taskenter_critical();
    flexspi_nor_flash_init(example_flexspi);
    taskexit_critical();
    /* get vendor id. */
    status = flexspi_nor_get_vendor_id(example_flexspi, &vendorid);
    if (status != kstatus_success)
    {
        printf(get vendor id failure!);
        configassert(null);
    }
    printf(flash vendor id: 0x%x , vendorid);
    /* disable i cache to avoid cache pre-fatch instruction with branch prediction from flash       and application operate flash synchronously in multi-tasks. */
#if defined(__icache_present) && (__icache_present == 1u)
    volatile bool icacheenableflag = false;
    /* disable i cache. */
    if (scb_ccr_ic_msk == (scb_ccr_ic_msk & scb->ccr))
    {
        scb_disableicache();
        icacheenableflag = true;
    }
#endif /* __icache_present */
    /* enter quad mode. */
    taskenter_critical();
    status = flexspi_nor_enable_quad_mode(example_flexspi);
    taskexit_critical();
#if defined(__icache_present) && (__icache_present == 1u)
    if (icacheenableflag)
    {
        /* enable i cache. */
        scb_enableicache();
        icacheenableflag = false;
    }
#endif /* __icache_present */
    if (status != kstatus_success)
    {
        configassert(null);
    }
    /* erase sectors. */
    printf(erasing serial nor over flexspi... );
    /* disable i cache to avoid cache pre-fatch instruction with branch prediction from flash and application operae flash synchronously inmulti-tasks.*/
#if defined(__icache_present) && (__icache_present == 1u)
    /* disable i cache. */
    if (scb_ccr_ic_msk == (scb_ccr_ic_msk & scb->ccr))
    {
        scb_disableicache();
        icacheenableflag = true;
    }
#endif /* __icache_present */
    taskenter_critical();
    status = flexspi_nor_flash_erase_sector(example_flexspi, example_sector * sector_size);
    taskexit_critical();
#if defined(__icache_present) && (__icache_present == 1u)
    if (icacheenableflag)
    {
        /* enable i cache. */
        scb_enableicache();
        icacheenableflag = false;
    }
#endif /* __icache_present */
    if (status != kstatus_success)
    {
        printf(erase sector failure ! );
        configassert(null);
    }
    /* invalidate the d cache before reading data from qspi flash */
#if defined(cache_maintain) && cache_maintain
    dcache_invalidatebyrange(example_flexspi_amba_base + example_sector * sector_size, flash_page_size);
#endif
    memcpy(nor_read_buffer, (void *)(example_flexspi_amba_base + example_sector * sector_size), flash_page_size);
    for (uint16_t i = 0; i < flash_page_size; i++)
    {
        if (0xff != nor_read_buffer[i])
        {
            printf(erase data -  read out data value incorrect ! );
            configassert(null);
        }
    }
    printf(sector erase successfully ! );
    /* program sector */
    for (uint16_t i = 0u; i ccr))
    {
        scb_disableicache();
        icacheenableflag = true;
    }
#endif /* __icache_present */
    taskenter_critical();
    status = flexspi_nor_flash_page_program(example_flexspi, example_sector * sector_size, (void *)nor_program_buffer);
    taskexit_critical();
#if defined(__icache_present) && (__icache_present == 1u)
    if (icacheenableflag)
    {
        /* enable i cache. */
        scb_enableicache();
        icacheenableflag = false;
    }
#endif /* __icache_present */
    if (status != kstatus_success)
    {
        printf(page program failure ! );
        configassert(null);
    }
    printf(page program successfully ! );
    /* clean the d cache before reading data from qspi flash */
#if defined(cache_maintain) && cache_maintain
    dcache_invalidatebyrange(example_flexspi_amba_base + example_sector * sector_size, flash_page_size);
#endif
    /* the below read sector api can be used in both code in qspi mode and code in sram mode */
    taskenter_critical();
    memcpy(nor_read_buffer, (void *)(example_flexspi_amba_base + example_sector * sector_size), flash_page_size);
    taskexit_critical();
    printf(read sector content: );
    for (uint16_t i = 0; i < flash_page_size; i++)
    {
        printf(%d, , nor_read_buffer[i]);
    }
    printf( flash operation done, suspend this task now. );
    /* suspend itself */
    vtasksuspend(null);
}


长电科技实现4nm工艺制程手机芯片封装
LED舞台误区方案
HTC因侵犯Ipcom专利被禁止在英国销售手机
奎芯科技获超亿元首轮融资 莱迪思加入OPC基金会
一期性价比高,音质好的蓝牙耳机,实测好评推荐
I.MXRT FreeRTOS环境下擦写外部Flash
干货 | 氮化镓GaN驱动器的PCB设计策略概要
电源滤波器有用吗?该怎么选择呢?
热处理生产线淬火技术策略的设计与通讯
晶圆制造重镇遇地震,对半导体产业影响几何?
无可替代的封装技术LTCC——工艺及设备篇
PLC工控组态软件有哪些?
巡检机器人替代消防工作势在必行!
浅析2012年下半年LED背光市场
iOS11测试版正式首发:苹果iOS11预览版Beta1固件下载大全,iOS10.3.3公测版推送只为阻拦iOS10.2越狱和iOS10.3越狱?
关于中兴通讯推出的中兴骐骥系列Wi-Fi 6路由器浅解
线路板加工技术简介
3.7v升压5v电路图分享
华为Watch GT 2搭载全新麒麟A1芯片即将在印度出售
变频器凝露的危害_变频器凝露的处理办法