GD32 flash FMC/bootloade操作

本文介绍了GD32芯片的FMC(Flash Memory Controller)和BOOTLOADER的相关知识,包括GD32的三种启动模式及其作用,详细解析了BOOT1和BOOT0的配置方法,并探讨了OTA固件升级时引导程序和应用程序的角色与交互,强调了固件存储布局规划及完整性校验的重要性。

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

    GD32的Flash的名字是FMC,BOOT的操作主要基于这些进行实现


    .GD32有三种启动模式,对应的存储介质均是芯片内置的,他们是: 1)用户闪存=芯片内置的闪存2)SRAM =芯片内置的RAM区,就是内存啦0.3)系统存储器=芯片内部一块特定的区域,芯片出厂时在这个区域预置了一段引导程序,就是通常说的ISP程序。这个区域的内容在芯片出厂后没有人能够修改或擦除,即它是一个ROM区。    在每个GD32的芯片上都有两个管脚BOOT1和BOOT0,两个这管脚在芯片复位时的电平状态决定了芯片复位后从哪个区域开始执行程序1)BOOT1 = X BOOT0 = 0从用户闪存启动,这是正常的工作模式。2)BOOT1 = 0 BOOT0 = 1从系统存储器启动,这种模式启动的程序功能由厂家设置3) BOOT1 = 1 BOOT0 = 1从内置SRAM启动,这种模式可用于调试。    要注意的是,一般不使用内置SRAM启动(BOOT1 = 1 BOOT0 = 1),因为SRAM 电后数据就丢失。多数情况下SRAM只是在调试时使用,也可以做其他一些用途。如做故障的局部诊断,写一段小程序加载到SRAM中诊断板上的其他电路,或用此方法读写板上的闪存EEPROM或等。还可以通过这种方法解除内部闪存的读写保护,当然解除读写保护的同时闪光的内容也被自动清除,以防止恶意的软件拷贝。一般BOOT0和BOOT1跳线都跳到0(地)    在GD32的芯片函数库gd32f1x0_fmc.c中,我们可以查找到这样的函数:









/ **



### 关于GD32E230 FMC Flash读写实现 在GD32E230系列微控制器中,FMCFlash Memory Controller)用于管理内部闪存的操作。以下是基于引用中的代码片段以及常见实践整理的完整示例代码和注意事项。 #### 示例代码:FMC Flash 写入数据 以下是一个改进版的 `FMC_FLASH_Write` 函数,解决了可能存在的问题并增加了错误处理逻辑: ```c #include "gd32e230_fmc.h" uint8_t FMC_FLASH_Write(uint32_t addr, uint32_t *data, uint8_t len) { fmc_state_enum FLASHStatus; uint16_t i; /* 解锁 */ fmc_unlock(); /* 清除状态标志 */ fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGAERR | FMC_FLAG_PGERR); /* Step 1: 擦除目标页 */ FLASHStatus = fmc_page_erase(addr); if (FLASHStatus != FMC_READY) { fmc_lock(); return 1; // 返回错误码表示擦除失败 } /* Step 2: 循环写入数据 */ for (i = 0; i < len; i++) { FLASHStatus = fmc_word_program(addr, *(data + i)); if (FLASHStatus != FMC_READY) { fmc_lock(); return 2; // 返回错误码表示编程失败 } addr += 4; // 地址偏移至下一个字位置 } /* 锁定 */ fmc_lock(); return 0; // 成功返回0 } ``` 此代码实现了以下几个重要特性: - **解锁/锁定机制**:确保每次操作前后都调用了 `fmc_unlock()` 和 `fmc_lock()`[^1]。 - **状态清除**:通过 `fmc_flag_clear()` 清除了所有可能导致干扰的状态标志位[^1]。 - **逐字写入**:支持连续多个字的数据写入,并自动调整地址指针。 - **错误检测**:每一步都有状态检查,如果发生异常会立即退出并返回相应的错误码[^1]。 --- #### 示例代码:FMC Flash 读取数据 对于读取操作相对简单,只需按照指定地址访问即可完成: ```c void FMC_FLASH_Read(uint32_t addr, uint32_t *buffer, uint8_t len) { for (int i = 0; i < len; i++) { buffer[i] = *(volatile uint32_t *)addr; addr += 4; // 增加偏移量以指向下一字节 } } ``` 该函数接受三个参数——起始地址 (`addr`)、缓冲区指针 (`buffer`) 和要读取的字数 (`len`)。它将从给定地址处依次取出所需数量的字并存储到用户提供的缓冲区内[^2]。 --- #### 注意事项与调试建议 当遇到无法正常写入的情况时,请考虑以下几点: 1. **硬件保护触发**:确认当前尝试修改区域未处于只读模式或其他形式的安全防护之下。 2. **地址范围验证**:确保所选地址位于允许改写的范围内;超出有效边界可能会引发不可预期行为[^1]。 3. **电源电压稳定性**:低供电水平下某些敏感指令执行可能出现偏差甚至损坏设备永久性结构[^2]。 4. **固件版本兼容性**:不同修订批次间可能存在细微差异影响具体API表现效果。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值