首先需要搞清楚我们所用硬件的flash配置情况,我们使用的mcu型号为smt32f103zet6,查看stm32开发手册,得知这个型号是大容量产品:
有256 page,page size = 2K,共512K容量的片上flash.


#include <stdint.h>
#include <string.h> // memcpy#include "hal_flash_bank_stm32.h"
#include "stm32f1xx_hal.h"#define STM32_FLASH_ALIGNMENT  4static uint32_t hal_flash_bank_stm32_get_size(void * context){hal_flash_bank_stm32_t * self = (hal_flash_bank_stm32_t *) context;return self->page_size;
}static uint32_t hal_flash_bank_memory_get_alignment(void * context){UNUSED(context);return STM32_FLASH_ALIGNMENT;
}static void hal_flash_bank_stm32_erase(void * context, int bank){hal_flash_bank_stm32_t * self = (hal_flash_bank_stm32_t *) context;if (bank > 1) return;FLASH_EraseInitTypeDef eraseInit;eraseInit.TypeErase = FLASH_TYPEERASE_PAGES;eraseInit.PageAddress = self->page_start[bank];eraseInit.NbPages = 1;uint32_t sectorError;HAL_FLASH_Unlock();HAL_FLASHEx_Erase(&eraseInit, &sectorError);HAL_FLASH_Lock();
}static void hal_flash_bank_stm32_read(void * context, int bank, uint32_t offset, uint8_t * buffer, uint32_t size){hal_flash_bank_stm32_t * self = (hal_flash_bank_stm32_t *) context;if (bank > 1) return;if (offset > self->page_size) return;if ((offset + size) > self->page_size) return;memcpy(buffer, ((uint8_t *) self->page_start[bank]) + offset, size);
}static void hal_flash_bank_stm32_write(void * context, int bank, uint32_t offset, const uint8_t * data, uint32_t size){hal_flash_bank_stm32_t * self = (hal_flash_bank_stm32_t *) context;if (bank > 1) return;if (offset > self->page_size) return;if ((offset + size) > self->page_size) return;unsigned int i;HAL_FLASH_Unlock();for (i=0;i<size;i+=STM32_FLASH_ALIGNMENT){HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, self->page_start[bank] + offset +i, *(uint32_t *)(data+i));}HAL_FLASH_Lock();
}static const hal_flash_bank_t hal_flash_bank_stm32_impl = {/* uint32_t (*get_size)() */         &hal_flash_bank_stm32_get_size,/* uint32_t (*get_alignment)(..); */ &hal_flash_bank_memory_get_alignment,/* void (*erase)(..);             */ &hal_flash_bank_stm32_erase,/* void (*read)(..);              */ &hal_flash_bank_stm32_read,/* void (*write)(..);             */ &hal_flash_bank_stm32_write,
};const hal_flash_bank_t * hal_flash_bank_stm32_init_instance(hal_flash_bank_stm32_t * context, uint32_t page_size,uint32_t bank_0_page_id, uint32_t bank_1_page_id){context->page_size = page_size;context->page_index[0] = bank_0_page_id;context->page_index[1] = bank_1_page_id;context->page_start[0] = FLASH_BASE + bank_0_page_id * page_size;context->page_start[1] = FLASH_BASE + bank_1_page_id * page_size;return &hal_flash_bank_stm32_impl;
}
#ifndef __HAL_FLASH_BANK_STM32_H
#define __HAL_FLASH_BANK_STM32_H#include <stdint.h>
#include "hal_flash_bank.h"#if defined __cplusplus
extern "C" {
#endiftypedef struct {uint32_t   page_size;uint32_t   page_start[2];uint16_t   page_index[2];
} hal_flash_bank_stm32_t;/*** Configure STM32 HAL Flash Implementation** @param context of hal_flash_bank_stm32_t* @param page_size* @param bank_0_page_id id* @param bank_0_page_id id* @return */
const hal_flash_bank_t * hal_flash_bank_stm32_init_instance(hal_flash_bank_stm32_t * context, uint32_t page_size,uint32_t bank_0_page_id, uint32_t bank_1_page_id);#if defined __cplusplus
}
#endif
#endif

从0x08000000开始存放的是程序代码,我们需要避开存放程序部分的flash地址,查看编译生成后的hex文件,大小为64KB,所以为了安全起见,我们写flash的地址范围为:
0x08000000(flash起始地址)+641024(程序大小)+101024(reserve) = 0x08012800
[0x08012800 - 0x0807FFFF]

为了方便计算,我们划分[0x080C0000 - 0x080C0800] 的范围用来作为NVDM

遇到问题记录如下:

1.使用如下flash配置,在读page0时发生hard_fault error:

//#define HAL_FLASH_PAGE_0_ADDR 0x080C0000      //flash page0 start address
//#define HAL_FLASH_PAGE_1_ADDR 0x080C0800      //flash page1 start address
#define HAL_FLASH_PAGE_SIZE   (2 * 1024)//page size
#define HAL_FLASH_PAGE_0_ID 384//((HAL_FLASH_PAGE_0_ADDR - FLASH_BASE) / HAL_FLASH_PAGE_SIZE) //page0 ID 384
#define HAL_FLASH_PAGE_1_ID 385//((HAL_FLASH_PAGE_1_ADDR - FLASH_BASE) / HAL_FLASH_PAGE_SIZE) //page1 ID 385

改为如下配置,可以正常读写flash:

//#define HAL_FLASH_PAGE_0_ADDR 0x08032000      //flash page0 start address
//#define HAL_FLASH_PAGE_1_ADDR 0x08032800      //flash page1 start address
#define HAL_FLASH_PAGE_SIZE   (2 * 1024)//page size
#define HAL_FLASH_PAGE_0_ID   100//((HAL_FLASH_PAGE_0_ADDR - FLASH_BASE) / HAL_FLASH_PAGE_SIZE) //page0 ID 100
#define HAL_FLASH_PAGE_1_ID   101//((HAL_FLASH_PAGE_1_ADDR - FLASH_BASE) / HAL_FLASH_PAGE_SIZE) //page1 ID 101

犯了低级错误,前面已经计算出flash可安全访问的地址范围:[0x08012800 - 0x0807FFFF],我还选[0x080C0000 - 0x080C0800] 的范围用来作为NVDM,当然会因为非法访问而产生hard_fault error.

[0x08012800 - 0x0807FFFF]对应的flash page ID:[37, 255],所以选取[100,101]没有问题。

参考:
https://doc.embedfire.com/mcu/stm32/f103mini/hal/zh/latest/book/FLASH.html
https://blog.csdn.net/u013385925/article/details/51140619

bluekitchen-stm32f1/csr8311移植笔记(4)-database driver相关推荐

  1. bluekitchen-stm32f1/csr8311移植笔记(1)-开发环境配置

    bluekitchen是一个代码完全开源的蓝牙协议栈,支持ble,ble mesh,edr.它的功能丰富,且可配置性极高,支持多个不同的软件平台,以及多种知名的蓝牙芯片,具有很高的可移植性,非常适合蓝 ...

  2. micropython STM32移植笔记(一)

    micropython STM32移植笔记(一) 首先,我是一个搞硬件的,说白了是做电路的,呵呵... 一直想学一些软件,只会搞硬件的工程师是没有灵魂的,画了7年的PCB板卡了,但是每次调试硬件都要求 ...

  3. 瑞芯微 | 摄像头ov13850移植笔记

    <1.瑞芯微rk356x板子快速上手> <2.Linux驱动|瑞芯微rtc-hym8563移植笔记> <3.Linux驱动 | Linux内核 RTC时间架构-基于瑞芯微 ...

  4. AT91RM9200Linux移植笔记(三)-移植Linux kernel 2.6.17

    AT91RM9200Linux移植笔记(三)-移植Linux kernel 2.6.17 手上板子原来自带的是2.4.19的内核, 打算移植新的2.6的内核,从网上下了2.6.17的kernel,下载 ...

  5. 解决 springboot 启动报错 -- Cannot determine embedded database driver class for database type NONE

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. 1. 问题描述 我只是新建一个全新的 springboot 工程,什么都没有写的情况下启动报错如题: ...

  6. 报错Cannot determine embedded database driver class for database type NONE解决方法

    由于我不需要数据库,启动springboot报错: Cannot determine embedded database driver class for database type NONE If ...

  7. SpringBoot项目在启动时出现了Cannot determine embedded database driver class for database type NONE 错误

    问题描述:SpringBoot项目在启动时出现了以下错误无法启动 Cannot determine embedded database driver class for database type N ...

  8. SpringBoot项目报错Cannot determine embedded database driver class for database type NONE

    原因: Cannot determine embedded database driver class for database type NONE 这是因为spring boot默认会加载org.s ...

  9. 以太网芯片W3100A到W3150A+的移植笔记(一)

    最近很多用户咨询 W3100A,由于W3100A已经停产.在此希望给大家介绍一下,W3100A可移植到其他芯片的方式及途径,供大家更好的拓展您项目的沿用性,期待能对您有所帮助.今天先为大家介绍第一部分 ...

最新文章

  1. 埃隆·马斯克:比特币拥有着“极为出色”的结构,而纸质货币终将消失
  2. git 提交到某分支_Git如何拉取某个分支的某段提交
  3. 你多久没换过壁纸了?新年了,换一换吧!
  4. GHOST_XP详细制作过程
  5. Windows平台下SVN安装配置及使用
  6. maven snapshot和release版本号之间的差
  7. HTML、 CSS、 JavaScript三者的关系
  8. 整理了一些面试题,还在更新中,有时间的可以看看
  9. java中的@param参数_java – @RequestParam在Spring MVC中处理可选参数
  10. ubuntu 两行命令自动安装最合适的NVIDIA驱动
  11. this 自引用指针
  12. Ping++中的AlipaySDK和AlicloudUTDID冲突解决方案
  13. 所有的困苦都是有用意的
  14. CorelDRAW VBA 插件开发入门视频教程
  15. java html加密_能提供加密与解密
  16. Cannot add or update a child row: a foreign key constraint fails都有哪些原因
  17. 树莓派安装配置MFRC522模块
  18. 解决Android应用签名和系统不一致的问题
  19. TGA图像文件格式分析
  20. 听见丨美国大型连锁创客空间TechShop破产 首汽约车获7亿元B+轮融资 百度和蔚来汽车等领投

热门文章

  1. 有n只蚂蚁在一根木棍上,蚂蚁们只知道距左端的距离,棍子的长度,但不知道他们的朝向,蚂蚁们走到端点的时候会落下木棍,求所有蚂蚁们走过的最短和最长路程。
  2. MN316_OPEN(NBIOT)物联网模块环境搭建
  3. 深圳市有关事假、病假、婚假、丧假、产假、哺乳假、生育看护假的规定
  4. 嵌入式C语言自我修养:从芯片、编译器到操作系统-习题、笔记
  5. 回文子串是什么意思?
  6. 恶性淋巴瘤及其实验诊断题库【1】
  7. 奥迪A4显示服务器出故障,奥迪A4变速箱锁挡、没倒挡、红屏、传感器故障维修总结...
  8. OSChina 周五乱弹 ——程序员脱单攻略!
  9. VTK笔记-CT图像获取皮肤等值面-vtkContourFilter类的使用
  10. 2018.03.18 临汾市游记