sf_saveenv()浅析

本文详细解析了在启动过程中SPI Flash上环境变量的保存流程,包括数据的擦除、写入操作及其条件判断。通过具体函数实现和关键步骤说明,帮助理解整个保存过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*
    先看这个,各个函数是在什么时候被调用的,
    总体流程是这样的
    start_armboot -->init_sequence[]-->env_init
                  -->env_relocate ....
                  .....   
    最终会调用到 下面的几个函数。在后面的调用流程中会说,           
*/
static struct env_common_func_t sf_env_cmn_func = {
    .env_init = sf_env_init,
    .env_get_char_spec = sf_env_get_char_spec,
    .saveenv = sf_saveenv,
    .env_relocate_spec = sf_env_relocate_spec,
    .env_name_spec = "SPI Flash",
};

先来一张图
A
这里写图片描述
B
这里写图片描述

/**
    这个函数做的事情:
                    1: 擦除
                    2: 写入
*/
int sf_saveenv(void)
{
    u32 saved_size, saved_offset;
    char *saved_buffer = NULL;
    u32 sector = 1;
    int ret;
    u_int32_t erase_length;
    /*
        为了 下面获取 擦除块的大小 spiflash_info->erasesize    : 0x10000
    */  
    struct mtd_info_ex *spiflash_info = get_spiflash_info();
    if (!env_flash) {
        puts("Environment SPI flash not initialized\n");
        return 1;
    }
    /*

        如果不相等,那么就做一些计算。
        CONFIG_ENV_SECT_SIZE 定义了 环境变量扇区的大小 0x40000(自定义)
        环境变量总长度 0x40000
        不会执行,我们配置的 他们是相等的。分析略过
    */
    if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) {
        saved_size = CONFIG_ENV_SECT_SIZE - CONFIG_ENV_SIZE;
        saved_offset = CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE;
        saved_buffer = malloc(saved_size);
        if (!saved_buffer) {
            ret = 1;
            goto done;
        }
        ret = spi_flash_read(env_flash, saved_offset, saved_size, saved_buffer);
        if (ret)
            goto done;
    }
    /*
        不会执行,我们配置的 他们是相等的。分析略过
    */  
    if (CONFIG_ENV_SIZE > CONFIG_ENV_SECT_SIZE) {
        sector = CONFIG_ENV_SIZE / CONFIG_ENV_SECT_SIZE;
        if (CONFIG_ENV_SIZE % CONFIG_ENV_SECT_SIZE)
            sector++;
    }
    erase_length = (sector * CONFIG_ENV_SECT_SIZE);// 0x40000

    /*
        如果擦除块大小 小于 64K,那么擦除块大小为64K
       erase_length : 0x40000
    */   
    if (erase_length < spiflash_info->erasesize) //spiflash_info->erasesize : 0x10000   64K.
    {
        printf("Warning: Erase size 0x%08x smaller than one erase block 0x%08x\n", erase_length, spiflash_info->erasesize);
        printf("Erasing 0x%08x instead\n", spiflash_info->erasesize);
        erase_length = spiflash_info->erasesize;
    }

    printf("Erasing SPI flash, offset 0x%08x size %s ...",CONFIG_ENV_OFFSET, ultohstr(erase_length));
    /*
        开始擦除.  从0x80000 开始,长度0x40000,  一次擦除 0x10000  64K。
    */
    ret = spi_flash_erase(env_flash, CONFIG_ENV_OFFSET, erase_length);
    if (ret)
        goto done;
    printf("done\nWriting to SPI flash, offset 0x%08x size %s ...",CONFIG_ENV_OFFSET, ultohstr(CONFIG_ENV_SIZE));
    /*
        将环境变量写入到 CONFIG_ENV_OFFSET起始地址中
        CONFIG_ENV_OFFSET    : 0x80000
        CONFIG_ENV_SIZE      : 0x40000    : 256K
    */
    ret = spi_flash_write(env_flash, CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, env_ptr);
    if (ret)
        goto done;
    /*
        不会执行,再此略过
    */  
    if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) {
        ret = spi_flash_write(env_flash, saved_offset, saved_size, saved_buffer);
        if (ret)
            goto done;
    }
    ret = 0;
    puts("done\n");
 done:
    if (saved_buffer)
        free(saved_buffer);
    return ret;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值