AIR32F103(七) AIR32F103CBT6/CCT6启用96K内存
目录
- AIR32F103(一) 合宙AIR32F103CBT6开发板上手报告
- AIR32F103(二) Linux环境和LibOpenCM3项目模板
- AIR32F103(三) Linux环境基于标准外设库的项目模板
- AIR32F103(四) 27倍频216MHz,CoreMark跑分测试
- AIR32F103(五) FreeRTOSv202112核心库的集成和示例代码
- AIR32F103(六) ADC,I2S,DMA和ADPCM实现的录音播放功能
- AIR32F103(七) AIR32F103CBT6/CCT6启用96K内存
AIR32F103CBT6和CCT6的隐藏内存空间
| TYPE | AIR32F103CBT6 | AIR32F103CCT6 | AIR32F103RPT6 |
|---|---|---|---|
| Flash | 128K | 256K | 256K |
| RAM | 32K | 64K | 96K |
| Pack | lqfp48 | lqfp48 | lqfp64 |
根据数据手册, AIR32F103CBT6 和 AIR32F103CCT6 分别带 32K Byte和 64K Byte 内存. 对于48pin封装的 AIR32F103, 32K和64K的内存已经是市面上M3芯片中相当不错的容量, 至于64pin封装的AIR32F103RPT6, 96K的内存只在市场上的高端型号中出现, 例如雅特力的AT32F403A系列.
但是实际上这两个型号和 AIR32F103RPT6 一样, 内存空间为96K.
这个隐藏的内存空间, 是 Hedley Rainnie 在观察切换216MHz的过程中发现的. 这个容量也得到了合宙技术的确认.
具体的记录可以查看 http://www.hrrzi.com/2022/12/the-air32f103.html. 在切换216MHz的过程中, 在将RCC->RCC_SYSCFG_CONFIG置零之前, 可以通过SYSCFG->SYSCFG_RSVD0[5]这个寄存器设置内存空间的结束地址. 将这个地址设为 0x20018000 后, 在代码中就可以使用 96K Byte 的内存容量.
启用隐藏内存的流程
切换216MHz的代码
#define SysFreq_Set (*((void (*)(uint32_t, FlashClkDiv , uint8_t, uint8_t))(*(uint32_t *)0x1FFFD00C)))
uint32_t AIR_RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t RCC_PLLMul, FlashClkDiv Latency)
{
volatile uint32_t sramsize = 0;
assert_param(IS_RCC_PLL_SOURCE(RCC_PLLSource));
assert_param(IS_RCC_PLL_MUL(RCC_PLLMul));
*(volatile uint32_t *)(0x400210F0) = BIT(0);//开启sys_cfg门控
*(volatile uint32_t *)(0x40016C00) = 0xa7d93a86;//解一、二、三级锁
*(volatile uint32_t *)(0x40016C00) = 0xab12dfcd;
*(volatile uint32_t *)(0x40016C00) = 0xcded3526;
// 这一步记录了RAM大小
sramsize = *(volatile uint32_t *)(0x40016C18);
*(volatile uint32_t *)(0x40016C18) = 0x200183FF;//配置sram大小, 将BOOT使用对sram打开
*(volatile uint32_t *)(0x4002228C) = 0xa5a5a5a5;//QSPI解锁
SysFreq_Set(RCC_PLLMul,Latency ,0,1);
RCC->CFGR = (RCC->CFGR & ~0x00030000) | RCC_PLLSource;
// 在这一步, 将之前的RAM大小再设置回去, 如果把这个sramsize直接改为 0x20018000, 就使得整个96K都可用了
*(volatile uint32_t *)(0x40016C18) = sramsize;
*(volatile uint32_t *)(0x400210F0) = 0;//开启sys_cfg门控
*(volatile uint32_t *)(0x40016C00) = ~0xa7d93a86;//加一、二、三级锁
*(volatile uint32_t *)(0x40016C00) = ~0xab12dfcd;
*(volatile uint32_t *)(0x40016C00) = ~0xcded3526;
*(volatile uint32_t *)(0x4002228C) = ~0xa5a5a5a5;//QSPI解锁
return 1;
}
上面的代码用地址表示比较难阅读, 能换成寄存器表达的都换成寄存器表达后, 看起来会简单些
uint32_t AIR_RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t RCC_PLLMul, FlashClkDiv Latency)
{
assert_param(IS_RCC_PLL_SOURCE(RCC_PLLSource));
assert_param(IS_RCC_PLL_MUL(RCC_PLLMul));
RCC->RCC_SYSCFG_CONFIG = 1; // Unlock sys_cfg gate control
SYSCFG->SYSCFG_LOCK = 0xa7d93a86; // Unlock from level 1 to 3
SYSCFG->SYSCFG_LOCK = 0xab12dfcd;
SYSCFG->SYSCFG_LOCK = 0xcded3526;
SYSCFG->SYSCFG_RSVD0[5] = 0x200183FF; // Set sram size, enable BOOT for sram
*(__IO uint32_t *)(FLASH_R_BASE + 0x28C) = 0xa5a5a5a5; // Unlock QSPI
AIR_SysFreq_Set(RCC_PLLMul, Latency, 0, 1);
RCC->CFGR = (RCC->CFGR & ~0x00030000) | RCC_PLLSource;
// Restore previous config
SYSCFG->SYSCFG_RSVD0[5] = 0x20018000;
RCC->RCC_SYSCFG_CONFIG = 0; // Lock sys_cfg gate control
SYSCFG->SYSCFG_LOCK = ~0xa7d93a86; // Lock from level 1 to 3
SYSCFG->SYSCFG_LOCK = ~0xab12dfcd;
SYSCFG->SYSCFG_LOCK = ~0xcded3526;
*(__IO uint32_t *)(FLASH_R_BASE + 0x28C) = ~0xa5a5a5a5;// Lock QSPI
return 1;
}
测试 96K 内存的例子
测试96K内存的源代码
- GitHub https://github.com/IOsetting/air32f103-template/tree/master/Examples/NonFreeRTOS/DMA
- Gitee https://gitee.com/iosetting/air32f103-template/tree/master/Examples/NonFreeRTOS/DMA
DMA_TC_Interrupt_96k_Malloc 和 DMA_TC_Interrupt_96k_Static 这两个示例分别演示动态和静态使用超过64K内存的情况. 在运行这两个例子前, 需要对项目代码做一些调整
1. 编辑 Libraries/LDScripts/air32f103cbt6.ld 或 air32f103cct6
修改 RAM LENGTH 为 96K
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 256K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 96K <---- 修改这个值为 96K
MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K
}
2. 编辑 Libraries/AIR32F10xLib/src/system_air32f10x.c
确认启用了 SYSCLK_FREQ_216MHz 这个宏配置
//#define SYSCLK_FREQ_HSE HSE_VALUE
//#define SYSCLK_FREQ_24MHz 24000000
//#define SYSCLK_FREQ_36MHz 36000000
//#define SYSCLK_FREQ_48MHz 48000000
//#define SYSCLK_FREQ_56MHz 56000000
//#define SYSCLK_FREQ_72MHz 72000000
#define SYSCLK_FREQ_216MHz 216000000 <---- 启用这个配置
3. 动态和静态申请
47000 个 uint16_t, 对应了 47K * 2 = 94K 内存
动态申请
#define BUFF_SIZE 47000
uint16_t *dma_buf;
...
dma_buf = (uint16_t *)malloc(BUFF_SIZE * sizeof(uint16_t));
printf("Malloc size: %d\r\n", BUFF_SIZE * sizeof(uint16_t));
静态申请
#define BUFF_SIZE 47000
uint16_t dma_buf[BUFF_SIZE];
需要确保在未完成内存容量设置前, 不要使用 dma_buf
最后
据说除了额外的RAM, 还有额外的FLASH, 但是我没试成功, 在写入flash后校验不通过, 也可能我使用的姿势不对.
原先AIR32F103CBT6只有32K内存, 不能跑Helix MP3解码, 现在的96K内存足够跑两个, LOL
AIR32F103(七) AIR32F103CBT6/CCT6启用96K内存的更多相关文章
- 如何启用“锁定内存页”选项 (Windows)
默认情况下,禁用 Windows 策略"锁定内存页"选项.必须启用此权限才能配置地址窗口化扩展插件 (AWE).此策略将确定哪些帐户可以使用进程将数据保留在物理内存中,从而阻止系统 ...
- InnoDB启用大内存页
在 Linux 操作系统上运行内存需求量较大的应用程序时,由于其采用的默认页面大小为 4KB,因而将会产生较多 TLB Miss 和缺页中断,从而大大影响应用程序的性能.当操作系统以 2MB 甚至更大 ...
- 七.OC基础加强--1.内存管理 2.野指针,内存泄露 3.set方法的内存管理 4.@property参数 5.@class和循环retain的使用 6.NSString的内存管理
1,内存管理简单介绍 1,为什么要有内存管理? malloc selloc dealloc```需要回头复习 一般的内存 4s 是512m内存:6 是1024m内存: 当内存过大时,会耗尽内存.出现程 ...
- JVM 专题十二:运行时数据区(七)对象的实例化内存布局与访问定位
1. 对象的实例化 1.1 创建对象的方式 new 最常见的方式 变形1 : Xxx的静态方法 变形2 : XxBuilder/XxoxFactory的静态方法 Class的newInstance() ...
- linux内存基础知识和相关调优方案
内存是计算机中重要的部件之中的一个.它是与CPU进行沟通的桥梁. 计算机中全部程序的执行都是在内存中进行的.因此内存的性能对计算机的影响很大.内存作用是用于临时存放CPU中的运算数据,以及与硬盘等外部 ...
- xcode 手动管理内存 的相关知识点总结
一.XCode4.2以后支持自动释放内存ARC xcode自4.2以后就支持自动释放内存了,但有时我们还是想手动管理内存,这如何处理呢. 很简单,想要取消自动释放,只要在 Build Setting ...
- python统计某一个进程名所占用的内存
设计思路: 通过python,执行cmd中tasklist命令,获取要统计的进程的相关信息:通过正则表达式,查找出进程名称.进程pid.内存使用,然后打印出来. 作为pythoner,有时候需要统计p ...
- Memcache 内存分配策略和性能(使用)状态检查
前言: 一直在使用Memcache,但是对其内部的问题,如它内存是怎么样被使用的,使用一段时间后想看看一些状态怎么样?一直都不清楚,查了又忘记,现在整理出该篇文章,方便自己查阅.本文不涉及安装.操作. ...
- iOS-OC内存管理
目标 1.[理解]内存管理 2.[掌握]第一个MRC程序 3.[掌握]内存管理的原则 4.[理解]野指针与僵尸对象 5.[理解]单个对象的内存管理 6.[理解]多个对象的内存管理 7.[掌握]set方 ...
- C++内存分析
在C++中,内存分成5个区,他们分别是堆.栈.自由存储区.全局/静态存储区和常量存储区. 栈:就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区.里面的变量通常是局部变量.函数参数 ...
随机推荐
- 记Windows的一个存在了十多年的bug
bug Windows有一个bug,持续了十多年,从Windows Visita开始(2007年),一直存在,直到Windows11(2021年)才修复(其实也不叫修复,后面我再具体说),而Windo ...
- Sun 的 BASE64Encoder替代
可以使用 org.apache.commons.codec.binary.Base64替代 Maven依赖如下 <dependency> <groupId>commons-co ...
- VM运行centos网络配置(出现错误)详解
一般按照正常安装流程到这一步的时候可以直接点击网络和主机名,但是我这里并没有连接成功,因此我跳过了这里想着后面再配置 后面通过ping www.baidu.com以及ping 百度的ip地址(如何获得 ...
- 『现学现忘』Git后悔药 — 33、revert撤销(二)
目录 4.一次移除某几次提交 (1)git revert移除某几次提交的修改 (2)git revert 移除某几次连续的提交的修改 5.revert命令常用参数 6.git revert和git r ...
- Windows活动目录_初识
计算机组织形式 工作组(用户本地登录时构造SID进行权限分配): 域(统一身份验证与管理) 域注意事项 实体:域控.域用户.加入域的机子. 依赖的服务:netlogon服务 强制刷新组策略gpupda ...
- 使用工厂方法模式设计能够实现包含加法(+)、减法(-)、乘法(*)、除法(/)四种运算的计算机程序,要求输入两个数和运算符,得到运算结果。要求使用相关的工具绘制UML类图并严格按照类图的设计编写程序实
2.使用工厂方法模式设计能够实现包含加法(+).减法(-).乘法(*).除法(/)四种运算的计算机程序,要求输入两个数和运算符,得到运算结果.要求使用相关的工具绘制UML类图并严格按照类图的设计编写程 ...
- 齐博x1where 标签动态变量查询/where 实现条件筛选与数据关联
大家可能对union参数不太习惯的话,也可以用where语句加入动态变量查询,比如 where="fid=$fid&uid=$info[uid]&pid>=$info. ...
- 1.轮询、长轮询、websocket简介
一.轮询 前端每隔固定时间向后台发送一次请求,询问服务器是否有新数据 缺点: 延迟,需要固定的轮询时间,不一定是实时数据 大量耗费服务器内存和宽带资源,因为不停的请求服务器,很多时候 并没有新的数 ...
- Gitea 1.18 功能前瞻(其三):增强文本预览效果、继续扩展软件包注册中心、增强工单实用功能、完善了用户邀请机制和SEO
今天是 10 月 26 日星期三,Gitea 周期性地发布了 1.18 的第一个 RC0 版本,在此阶段会收集一些功能和使用上的问题,随后还会发布 RC1,新功能的完整性和健壮性会逐步趋近正式版. 继 ...
- Linux软件安装方式 - Tarball&RPM&YUM
软件安装 简介 概念详解 # 概念详解 - 开放源码: 程序码, 写给人类看的程序语言, 但机器并不认识, 所以无法执行; - 编译器: 将程序码转译成为机器看的懂得语言, 就类似翻译者的角色; - ...