CH32V系列,例如CH32V203G6,只有前32K字节的闪存区域是零等待区域,而总闪存区域则达到了224K,作为极低代码密度的RISC-V,32K字节的代码区域是完全不够用的。
举个例子:在使用USB CDC和串口printf的情况下,32K字节的零等待区域就用了将近一半,而此时业务代码还没有开始编写,所以把初始化等不常用的代码放在非零等待区域是很有必要的。
遗憾的是:WCH给的例程里面并没有说明如何使用非零等待区域。故在此说明
在Ld/Link.ld文件中:
// 在MEMORY大括号中,添加:
SFLASH (rx) : ORIGIN = 0x00008000, LENGTH = 192K
// 在SECTION大括号中,添加:
.stext :
{
. = ALIGN(4);
*(.stext .ssrodata)
. = ALIGN(4);
} >SFLASH
在c文件中,可以使用__attribute__((section("")))语句指定数据的存放位置:
__attribute__((section(".stext"))) void GPIO_Toggle_INIT(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
__attribute__((section(".ssrodata"))) const u8 aa[] = {1,2,3,4,5,6,7,8,9,10};
当然,也可以用宏定义简化代码。
既然能把代码放进非零等待区了,那就顺便测个性能(计算PI):
__attribute__((noinline)) __attribute__((section(".stext"))) double getpi(){
volatile double n = 200000, sum = 0;
volatile int i;
for(i = 1; i <= n; i++)
sum += 1.0/(4*i-3)-1.0/(4*i-1);
return 4.0*sum;
}
| 是否零等待区 | 运行主频 | 时间 |
| ----------- | -------- | ------- |
| 1 | 144 | 1.6016 |
| 1 | 96 | 2.4064 |
| 1 | 48 | 4.8185 |
| 0 | 144 | 4.0496 |
| 0 | 96 | 6.0822 |
| 0 | 48 | 12.1999 |
结果非常出乎意料,GD32F1x0的非零等待闪存运行速度测试 对比GD32的测试情况,运行速度只慢了2.5倍显得非常的不可思议。按照国产MCU“手册里没写就是烂到不敢写”的尿性,怀疑是测试方法存在问题。下次跑个Coremark试试。
离线
也许是CH32V太新了,网上完全没有资料。
离线
楼主测试时使用的系统时钟频率是多少呢?一般时钟频率越高则Flash的延迟周期数越大,如果时钟频率较低,此时的性能可能不会落后太多,但时钟频率提升性能差距会逐渐扩大,甚至可能在当前时钟频率下无法正常使用。
在表格的第二列有写,单位是MHz。分别用144Mhz、96MHz、48Mhz测试的,都是相差2.5倍。
别的系统时钟频率由于我用到了USB CDC回传数据,暂时没有测试。
最近编辑记录 abgelehnt (2023-01-31 12:52:20)
离线
使用CH32V203G6U6进行Coremark测试,由于零等待闪存区域太小,-O3优化会爆闪存,这里使用-Os优化。
| 是否零等待区 | Coremark | 运行主频(Mhz) | Coremark/MHz |
| ----------- | -------- | ------------- | ------------ |
| 1 | 239.1396 | 144 | 1.660691 |
| 1 | 159.3494 | 96 | 1.65989 |
| 1 | 79.5574 | 48 | 1.657446 |
| 0 | 8.835473 | 144 | 0.061357 |
| 0 | 5.885135 | 96 | 0.061303 |
| 0 | 2.934796 | 48 | 0.061142 |
非零等待区与零等待区之间有27倍的性能差距,不知道大伙能不能接受。
冷知识:AT89C51 Coremark2.36分,0.11Coremark/MHz。
研究了一下手册,发现有个增强读模式,打开试试:
48MHz下Coremark分数:2.934718
FLASH不分频(直接使用HCLK):2.934718
感觉这两个选项不是给CH32V203G6U6用的。
又试了一下HCLK 2分频 :2.919156(有一点点区别)
离线