10

AIR32F103(七) AIR32F103CBT6/CCT6启用96K内存 - Milton

 1 year ago
source link: https://www.cnblogs.com/milton/p/17004589.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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 的内存容量.

启用隐藏内存的流程

查看代码 https://gitee.com/openLuat/luatos-soc-air32f103/blob/master/Libraries/AIR32F10xLib/src/air32f10x_rcc_ex.c

切换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内存的源代码

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 47000uint16_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 47000uint16_t dma_buf[BUFF_SIZE];

需要确保在未完成内存容量设置前, 不要使用 dma_buf

据说除了额外的RAM, 还有额外的FLASH, 但是我没试成功, 在写入flash后校验不通过, 也可能我使用的姿势不对.

原先AIR32F103CBT6只有32K内存, 不能跑Helix MP3解码, 现在的96K内存足够跑两个, LOL


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK