本帖最后由 mzy2364 于 2022-8-25 08:23 编辑
KungFu32 型号提供 1K 的可选数据空间 ,但是在正常使用的时候这 1K 的空间是没有明确表示如何使用的,不过从某些代码和文档里面是可以看出来的。 首先看下 KF32A 芯片的存储空间分布: 可以看到,在 512K 的 FLASH 以外,从地址 0X0008 0000 到 0X1000 000 这一段区域是保留的,手册里面也没有明确表示这里面是干嘛的,但是通过链接脚本文件可以看出来如下信息: MEMORY { flash : ORIGIN = 0x00008000, LENGTH = 0x00076000 ram : ORIGIN = 0x10000000, LENGTH = 0x00020000 da_mem : ORIGIN = 0x0C001C00, LENGTH = 0x00000400 mode_mem : ORIGIN = 0x0C001800, LENGTH = 0x00000004 pro_mem : ORIGIN = 0x0C001000, LENGTH = 0x00000004 ee_mem : ORIGIN = 0x7F000000, LENGTH = 0x00001000 config_mem1 : ORIGIN = 0x31000000, LENGTH = 0x00000010 config_mem2 : ORIGIN = 0x31000010, LENGTH = 0x00000010 } |
在链接脚本的 memory 分布中,用一个 da_mem 区域,其中大小为 1K ,而且这个命名应该也是 data_mem。我们大致猜测这个就是用来存在数据的 1K 区域,跟 FLASH 是独立的。
在 KF32APRO 软件中,也有一个显示 “HEX 显示 FLASH SPACE” 和 “HEX 显示 DATA SPACE” 的选项,我们切换到 DATA SPACE 显示,然后修改这 1K 的内容后进行编程,然后再回读,发现数据一致,就可以判断这 1K 的数据空间是可以正常使用的。
在 《KungFu32 Programmer Assistant User Manual CN V1.0.2.pdf》 这个文档中,我也找到了关于数据空间的描述:
结合我们在链接脚本文件和 KF32APRO 软件中得到的信息,我们就可以判断链接脚本中的 da_mem 就是实际可用的数据空间,而且在脚本的后面我们还找到了这个数据空间的其他内容: .flashdata : { KEEP (*(.flashdata*)) /* Flash Data */ . = 0x0400; /* length limit */ } > da_mem |
这里提供了一个 .flashdata 的段,我们尝试使用一下这个段,首先定义一个数组到这个段里面,并且给一个初始值,然后进行编译: __attribute__((section(".flashdata"))) \ uint8_t flashdata_Keep_Buffer[4] = {0X01,0X09,0X55,0X33}; |
编译以后使用软件看一下 HEX 文件的内容: 可以看到的是,HEX 里面新增了一个区域,地址是 0X0CCC 1C00 ,数据也跟我们代码里面体现的一致,说明这个区域是正常参与编译并且生效了。然后我们把这个 HEX 导入到 KF32A PRO 软件里面看一下 DATA SPACE 的内容: 可以看到数据也是生效的,说明数据空间可以正常使用了。 以上内容我们实现了利用调试器对 data flash 的操作,并且在程序中也可以定义 data flash 的内容,下面来看一下如何在程序中使用这些数据,首先看下怎么读取 data flash 的内容,既然是 flash 的内容,首先想到的就是通过指针去访问他,我们直接用 UDS 的 0X23 服务看一下,用 0X23 服务读一下 0X0C00 0000 这个地址的数据,看下跟我们写进去的是不是一样的。 首先通过调试器在 DATA SPACE 写入以下内容,并且读出来校验一次:
然后直接用 0X2E 服务读取对应的数据: 可以看到这个地址是可以读取出来的数据,但是这个跟我们写进去的似乎风马牛不相及,然后我也进调试模式进去看了一下,直接用指针访问这个地址确实数据是错的,于是可以断定这个 data flash 是不能通过指针访问的。但是 chipon 的资料里面也没有提及到如何使用这个 data flash , 于是陷入了僵局......
在思考了许久以后,想起来之前读取过 KF32A 单片机的芯片 ID ,是有一个头文件来管理这些 API 的,文件名叫 ChipMessageApi.h,在 V1.0.19 里面长这样: 笔者在里面找到了一个熟悉的函数 __FLASHCFGUSER_Program__ 然后看到这个函数的输入参数描述里面的 //Parameter:address must is 0x1C00 ,这就非常似曾相识了,而且这个名字也是可以顾名思义,猜测就是 data flash 的操作函数: 由于笔者手头环境是 V1.0.18 的,API 相对就很少: 但是里面也是有 data flash 的读取函数的,我们用这个函数尝试一下:unsigned int __getChipMessages(unsigned int addr,unsigned int len,unsigned int buffers[]); 看注释可以发现这个输入参数 addr 的范围有说明,我们这里就直接使用 0X1C00 作为形参,注:原文件里面的注释 return 可能打错了
通过注释我们可以看到实际数据是从 buffers[1] 开始的,第一个 word 的数据被用来记录函数返回标志,那么我们在读取的时候,也要多读取一个字的内容。 这里直接用 UDS 的 0X22 服务开一个 DID 进行读取: 编译下载验证: 读取的数据跟我们写入的一致。
1K的数据空间在实际产品中发挥了很重要的作用,比如我们可以利用这 1K 的空间存放产品的唯一 ID 等信息,这个信息也不会因为程序的更新而被损坏。
|