EasyFlash在GD32F303CC上面的移植

news2024/12/24 11:29:06

记录学习的过程,如果在GD32F303CC上面移植EasyFlash。关于EasyFlash的相关介绍和源码,请参考:https://gitee.com/Armink/EasyFlash 或者 https://github.com/armink/EasyFlash

主要记录移植过程中需要注意的点,移植还是比较简单的。基本就是填充几个宏定义和FLASH的操作函数即可。

一、下载源码、添加源码和头文件到工程中

这里就不具体展开了。作者给的文档有很详细,我就不复制搬运了,贴两张图片就好。

 二、根据芯片FLASH参数修改宏定义

 主要是修改ef_cfg.h文件。GD32F303CC用于手册里面的描述,可以知道一个页大小为2KB,支持编程写入16bit或者32bit。

基本修改的宏定义如下,具体含义参考注释。

/* The minimum size of flash erasure. May be a flash sector size. */
// 芯片FLASH的扇区大小或者说页大小 查询手册我使用芯片页大小为2K
#define EF_ERASE_MIN_SIZE       2048  /* @note you must define it for a value */  //2k
/* the flash write granularity, unit: bit
 * only support 1(nor flash)/ 8(stm32f4)/ 32(stm32f1) */
// FLASH支持的写入bit位数   查询手册 支持16bit和32bit 但是EasyFlash不支持 16bit
#define EF_WRITE_GRAN         32    /* @note you must define it for a value */
/* backup area start address */
// 使用内部FLASH来存储 存储的起始地址为 0x0803F000,即从252KB开始储存
#define EF_START_ADDR      0x0803F000       /* @note you must define it for a value */
/* ENV area size. It's at least one empty sector for GC. So it's definition must more then or equal 2 flash sector size. */
// 用来存储的空间大小 4KB  即从252~256KB
#define ENV_AREA_SIZE      (EF_ERASE_MIN_SIZE * 2)       /* @note you must define it for a value if you used ENV */
/* print debug information of flash */
// 宏定义开启串口调试输出
#define PRINT_DEBUG   1

三、接口移植

集中在ef_port.c文件下。主要需要完成,对FLASH读、写、擦除、加锁以及初始化等操作的接口。接口GD32固件库里面对FLASH操作的demo和EasyFlash提供的移植demo,依葫芦画瓢即可。

GD32固件库中关于FLASH操作demo(具体上GD32官网下载即可):

EasyFlash提供的移植demo:

最后附上自己修改的接口函数代码,注意的一点就是在RTOS和裸机上面采用的保护是不同的,RTOS直接利用了二值信号量,裸机直接关中断。

/* default environment variables set for user */
static const ef_env default_env_set[] = {
	      {"iap_need_copy_app","0"},
        {"iap_copy_app_size","0"},
        {"stop_in_bootloader","0"},
        {"device_id","1"},
        {"boot_times","0"},
};

EfErrCode ef_port_init(ef_env const **default_env, size_t *default_env_size)
{
    EfErrCode result = EF_NO_ERR;

    *default_env = default_env_set;
    *default_env_size = sizeof(default_env_set) / sizeof(default_env_set[0]);
		
	//如果使用了 RTOS 一般会在这里初始化信号量  rt_sem_init(&env_cache_lock, "env lock", 1, RT_IPC_FLAG_PRIO);
    return result;
}

EfErrCode ef_port_read(uint32_t addr, uint32_t *buf, size_t size)
{
    EfErrCode result = EF_NO_ERR;
    uint8_t *buf_8 = (uint8_t *)buf;
    size_t i;
    /* You can add your code under here. */
    /*copy from flash to ram */
    for (i = 0; i < size; i++, addr++, buf_8++)
    {
        *buf_8 = *(uint8_t *)addr;
    }
    return result;
}

EfErrCode ef_port_erase(uint32_t addr, size_t size)
{
    EfErrCode result = EF_NO_ERR;
    fmc_state_enum flash_status;
    size_t erase_pages, i;

    /* make sure the start address is a multiple of EF_ERASE_MIN_SIZE */
    EF_ASSERT(addr % EF_ERASE_MIN_SIZE == 0);

    /* You can add your code under here. */

    /* calculate pages */
    erase_pages = size / EF_ERASE_MIN_SIZE;
    if (size % EF_ERASE_MIN_SIZE != 0)
    {
        erase_pages++;
    }

    /* start erase */
    fmc_unlock();

    /* clear all pending flags */
    fmc_flag_clear(FMC_FLAG_BANK0_END);
    fmc_flag_clear(FMC_FLAG_BANK0_WPERR);
    fmc_flag_clear(FMC_FLAG_BANK0_PGERR);
    // 一个扇区一个扇区的擦除
    for (i = 0; i < erase_pages; i++)
    {
        flash_status = fmc_page_erase(addr + (EF_ERASE_MIN_SIZE * i));
        fmc_flag_clear(FMC_FLAG_BANK0_END);
        fmc_flag_clear(FMC_FLAG_BANK0_WPERR);
        fmc_flag_clear(FMC_FLAG_BANK0_PGERR);
        if (flash_status != FMC_READY)
        {
            result = EF_ERASE_ERR;
            break;
        }
    }
    fmc_lock();

    return result;
}

EfErrCode ef_port_write(uint32_t addr, const uint32_t *buf, size_t size)
{
    EfErrCode result = EF_NO_ERR;

    /* You can add your code under here. */
    size_t i;
    uint32_t read_data;

    /* unlock the flash program/erase controller */
    fmc_unlock();
    fmc_flag_clear(FMC_FLAG_BANK0_END);
    fmc_flag_clear(FMC_FLAG_BANK0_WPERR);
    fmc_flag_clear(FMC_FLAG_BANK0_PGERR);

    for (i = 0; i < size; i += 4, buf++, addr += 4)
    {
        /* write data */
        fmc_word_program(addr, *buf);
        read_data = *(uint32_t *)addr;

        fmc_flag_clear(FMC_FLAG_BANK0_END);
        fmc_flag_clear(FMC_FLAG_BANK0_WPERR);
        fmc_flag_clear(FMC_FLAG_BANK0_PGERR);

        /* check data */
        if (read_data != *buf)
        {
            result = EF_WRITE_ERR;
            break;
        }
    }
    /* lock the main FMC after the program operation */
    fmc_lock();

    return result;
}

void ef_port_env_lock(void)
{

    /* You can add your code under here. */
    // TODO:这里根据实际情况来判断
    // 如果是裸机就直接关中断
    __disable_irq();
    // 如果RTOS利用互斥量  rt_sem_take(&env_cache_lock, RT_WAITING_FOREVER);
}

void ef_port_env_unlock(void)
{

    /* You can add your code under here. */
    // TODO:这里根据实际情况来判断
    // 如果是裸机就直接开中断
    __enable_irq();
    // 如果RTOS利用互斥量    rt_sem_release(&env_cache_lock);
}



 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/707928.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

6.6 极重要的复习,权限与指令间的关系

权限对于使用者账号很重要&#xff0c;因为他可以限制使用者能不能读取/创建/删除/修改文件或目录。 一、让使用者能进入某目录成为“可工作目录”的基本权限为何&#xff1a; 可使用的指令&#xff1a;例如 cd 等变换工作目录的指令&#xff1b; 目录所需权限&#xff1a;使…

liunx安装git

liunx安装git &#xff1a; 提示&#xff1a;记录自己装git 过程 执行下边命令安装 yum -y install git 安装完查看是否安装成功 git --version安装路径默认在/usr/libexe 愉快开始使用git

帆软 FineReport 绘制漏斗图

七一建党节&#xff0c;祝党生日快乐&#xff01; 夏日炎炎&#xff0c;周末在家&#xff0c;想起在用帆软做页面展示的时候&#xff0c;使用到了漏斗图&#xff0c;记录下来&#xff0c;方便查看。 以订单销量变化为例&#xff0c;分为五个阶段&#xff0c;商品浏览人数&#…

fastadmin给操作按钮添加权限菜单控制|新增权限控制菜单

1、在对应的控制器文件中&#xff0c;添加如下代码&#xff1a; $adminIds $this->getDataLimitAdminIds(); if (is_array($adminIds)) {if (!in_array($row[$this->dataLimitField], $adminIds)) {$this->error(__(You have no permission));} } 2、在对应的index…

Redis实战篇(三)

四.分布式锁 4.1.分布式锁概述 分布式锁&#xff1a;满足分布式系统或集群模式下多进程可见并且互斥的锁。分布式锁的核心思想就是让大家都使用同一把锁&#xff0c;只要大家使用的是同一把锁&#xff0c;那么我们就能锁住线程&#xff0c;不让线程并行&#xff0c;让程序串行…

通过简数实现全网文章采集的方法简介

简数是一款全网文章采集工具&#xff0c;旨在帮助站长通过设置关键词来进行全网文章采集。然而&#xff0c;使用简数可能会有一些相对复杂的操作&#xff0c;导致站长在学习和使用过程中面临较高的学习成本&#xff0c;因为其中涉及到许多专业术语和功能的作用不明确。鉴于这一…

Unity - 搬砖日志 - UGUI合批优化 - Overlap(UI AABB 有重叠), Z != 0 照样合批的方案

文章目录 环境目的Screen Space - Overlay优化限制该方案起源 环境 Unity : 2020.3.37f1 Pipeline : BRP &#xff08;另一个项目在 2021.1.xx 的 LTS 下的 URP 管线同样如此&#xff0c;目测&#xff1a;因为 UGUI 不受渲染管线切换而变化&#xff09; 目的 便于索引&#…

IDEA启动Tomcat控制台乱码问题解决方法

最近项目需要用到Tomcat跑一个项目&#xff0c;但是开发Sprintboot项目久了&#xff0c;也很少用Tomcat&#xff0c;因为Springboot是集成Tomcat等中间件的&#xff0c;所以不需要下载Tomcat&#xff0c;好了&#xff0c;回归真题&#xff0c;本博客介绍跑Tomcat过程遇到的控制…

信道编码【编码、纠错检错】

差错控制的基本概念--数字信号在传输过程中&#xff0c;由于信道传输特性不理想及加性噪声的影响&#xff0c;不可避免地会发生错误。 可通过以下三方面的措施来减小误码率&#xff1a;1&#xff09;提高信道容量&#xff1b;2&#xff09;降低编码效率&#xff1b;3&#xff…

Binder系列--ServiceManager的启动

ServiceManager的启动 hongxi.zhu Android 13 主要流程&#xff1a; 1. 启动ServiceManager进程 ServiceManager是由init(pid 1)进程启动的 system/core/rootdir/init.rc on init......# Start essential services.start servicemanager //framework层使用start hwservic…

Linux | Ubuntu卸载QQ

Linux | Ubuntu卸载QQ 终端输入&#xff1a; dpkg -l| grep qq如下图&#xff0c;找到QQ文件&#xff1a; 删除命令&#xff1a; sudo apt-get --purge remove 文件名在终端输入&#xff1a; sudo apt-get --purge remove libqqwing2v5:amd64如下图删除成功

【Java程序设计实训】基于B/S架构的MyShop商城

MYSHOP商城 实验目的实验概述系统功能概述Myshop 商城概述系统开发分析功能列表系统用例图系统活动图 数据库设计运作界面展示用户管理模块新用户注册用户登录商城首页与用户退出 商品模块商品分页展示查看商品详情信息 购物车模块空购物车页面加入商品到购物车 订单模块提交订…

4.32UDP通信实现 4.33广播 4.34组播 4.35本地套接字通信

4.32UDP通信实现 ![在这 udp_client.c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <arpa/inet.h>int main() {// 1.创建一个通信的socketint fd socket(PF_INET, SOCK_DGRAM, 0);if(fd -1) {…

springboot项目外卖管理 day08-缓存优化

文章目录 一、缓存优化问题说明环境搭建导入maven坐标配置yml文件设置序列化器&#xff0c;编写配置类 缓存短信验证码缓存菜品数据实现思路 SpringCacheSpring Cache介绍Spring Cache常用注解Spring Cache使用方式 缓存套餐数据实现思路 一、缓存优化 问题说明 环境搭建 导入…

【Framework】startService启动流程

前言 启动service有两种方式&#xff1a;startService和bindService。 这一篇先讲startService&#xff0c;读者如果只想看流程图&#xff0c;可以直接跳到总结。 1. ContextImpl 代码路径&#xff1a;frameworks\base\core\java\android\app\ContextImpl.java 1.1 startServ…

SHA-256算法及示例

1. 引言 SHA-256&#xff08;安全哈希算法&#xff0c;FIPS 182-2&#xff09;是密码学哈希函数&#xff0c;其摘要长度为256位。SHA-256为keyless哈希函数&#xff0c;即为MDC&#xff08;Manipulation Detection Code&#xff09;。【MAC消息认证码有key&#xff0c;不是key…

【数据库】外键的作用

前言 说到外键&#xff0c;一般就会牵扯出约束。不谈约束&#xff0c;起始外键就是一个普通的字段&#xff08;Column&#xff09;&#xff0c;起到一个关联的作用。 先把约束放一边&#xff0c;看看外键有哪些作用。 建立表中记录的一对一的关系 学生表&#xff1a; 手机表…

C++引用计数

文章目录 1. 什么是引用计数2. 引用计数的实现3. 示例代码 1. 什么是引用计数 引用计数&#xff08;reference count&#xff09;的核心思想是使用一个计数器来标识当前指针指向的对象被多少类的对象所使用&#xff08;即记录指针指向对象被引用的次数&#xff09;。它允许有多…

Linux--查找文件指令:find

语法&#xff1a; find pathname -name 文件名 示例&#xff1a; 从根目录下开始查找名字中带file.txt文件的路径

C++思维导图以及作业

定义一个命名空间Myspace&#xff0c;包含以下函数&#xff1a;将一个字符串中的所有单词进行反转&#xff0c;并输出反转后的结果。例如&#xff0c;输入字符串为"Hello World"&#xff0c;输出结果为"olleH dlroW"&#xff0c;并在主函数内测试该函数。 …