c166 引导加载程序写入内部闪存
c166 bootloader write to internal flash
我正在为 c166 芯片编写引导加载程序,准确地说,是 169FH。引导加载程序当前可以打开 TCP/IP 连接,以便 PC 可以将 Intel hex 文件发送到引导加载程序。这个 intel hex 文件保存在 RAM 中。收到十六进制文件后,逐行读取以将字节设置到闪存中的正确位置。 bootloader存放的flash位置当然和主程序存放的地方不同。
这是 intel hex 文件的前两行:
:0200000400C03A
:20100000CA11EE111212341258127A129A12BC12DE12001322134413601388138813881349
第一行是获取32bit flash地址的高16位,本例为0x00C0
第二行是 32 位闪存地址的低 16 位,在本例中为 0x1000。这将创建总地址 0x00C01000,写入该地址的字节应为 0xCA。
我正在尝试使用以下代码将字节写入该地址:
uint8_t u8Byte = (uint8_t )XHugeStringToDec((const __huge char *)&Ext_RamFlashSave.Byte[u32Idx], 9+(u8ByteIdx*2), 2);
uint8_t *u8Address = (uint8_t*)((uint32_t)(u32ExtendedLinearAddress << 16) + (uint32_t)u16BaseAddress + (uint32_t)u8ByteIdx);
*u8Address = (u8Byte);
XHugeStringToDec() 是一个函数,用于从 intel 十六进制字符串中获取十六进制值。我知道这是正确的。
Ext_RamFlashSave.Byte是存放intel hex文件的数组
u32ExtendedLinearAddress 变量为 0x0C00,且设置较早。 u16BaseAddress 是 0x1000,也是在代码的前面设置的。
问题在最后一行:
*u8Address = (u8Byte);
我已经确认u8Address确实是0x0C01000,u8Byte确实是0xCA。但是当我监控我的闪存地址时,我没有看到写入的字节。
我可以想象这是某种写保护,但我不知道如何解决这个问题,或者我是否需要一种不同的方式来写入闪存地址?
有关如何构建 intel-hex 文件的更多信息,请参见此处:
https://en.wikipedia.org/wiki/Intel_HEX
我对你说的芯片不熟悉。
但是对于写入flash,一般使用以下算法:
- 解锁闪光灯。这通常是发送特定的数据序列。我现在使用的闪光灯有 0xA0A0-> 1 毫秒延迟 -> 0x0505。这将允许写入闪存
- 清除错误标志。闪存有一些错误标志,如写入错误或读取错误。此外,检查 Busy 标志以确保 Flash 已准备就绪
- 擦除页面。是的......你必须在写入之前擦除页面。即使你想改变一个位,你也必须擦除整个页面。
- 写入数据(最后)但要确保字节顺序是正确的。有时您的 Controller 是 Little Endien,而 Flash 是 Big Endien。所以你必须匹配Flash的。
- 锁定闪光灯。这通常是通过发送用于解锁的相同序列来完成的。 (参考数据表)
不能直接写入flash...必须走完整个流程。这就是 Flash 速度慢的原因。
有些闪存支持8位写入,有些只支持16位或32位等。所以,你必须在写入时发送那么多位。
当您必须修改页面的一小部分时,请读取缓冲区中的页面。修改缓冲区中的数据。擦除页面并写入整个缓冲区。
如果您正在修改
我正在为 c166 芯片编写引导加载程序,准确地说,是 169FH。引导加载程序当前可以打开 TCP/IP 连接,以便 PC 可以将 Intel hex 文件发送到引导加载程序。这个 intel hex 文件保存在 RAM 中。收到十六进制文件后,逐行读取以将字节设置到闪存中的正确位置。 bootloader存放的flash位置当然和主程序存放的地方不同。
这是 intel hex 文件的前两行:
:0200000400C03A
:20100000CA11EE111212341258127A129A12BC12DE12001322134413601388138813881349
第一行是获取32bit flash地址的高16位,本例为0x00C0 第二行是 32 位闪存地址的低 16 位,在本例中为 0x1000。这将创建总地址 0x00C01000,写入该地址的字节应为 0xCA。
我正在尝试使用以下代码将字节写入该地址:
uint8_t u8Byte = (uint8_t )XHugeStringToDec((const __huge char *)&Ext_RamFlashSave.Byte[u32Idx], 9+(u8ByteIdx*2), 2);
uint8_t *u8Address = (uint8_t*)((uint32_t)(u32ExtendedLinearAddress << 16) + (uint32_t)u16BaseAddress + (uint32_t)u8ByteIdx);
*u8Address = (u8Byte);
XHugeStringToDec() 是一个函数,用于从 intel 十六进制字符串中获取十六进制值。我知道这是正确的。
Ext_RamFlashSave.Byte是存放intel hex文件的数组
u32ExtendedLinearAddress 变量为 0x0C00,且设置较早。 u16BaseAddress 是 0x1000,也是在代码的前面设置的。
问题在最后一行:
*u8Address = (u8Byte);
我已经确认u8Address确实是0x0C01000,u8Byte确实是0xCA。但是当我监控我的闪存地址时,我没有看到写入的字节。 我可以想象这是某种写保护,但我不知道如何解决这个问题,或者我是否需要一种不同的方式来写入闪存地址?
有关如何构建 intel-hex 文件的更多信息,请参见此处: https://en.wikipedia.org/wiki/Intel_HEX
我对你说的芯片不熟悉。 但是对于写入flash,一般使用以下算法:
- 解锁闪光灯。这通常是发送特定的数据序列。我现在使用的闪光灯有 0xA0A0-> 1 毫秒延迟 -> 0x0505。这将允许写入闪存
- 清除错误标志。闪存有一些错误标志,如写入错误或读取错误。此外,检查 Busy 标志以确保 Flash 已准备就绪
- 擦除页面。是的......你必须在写入之前擦除页面。即使你想改变一个位,你也必须擦除整个页面。
- 写入数据(最后)但要确保字节顺序是正确的。有时您的 Controller 是 Little Endien,而 Flash 是 Big Endien。所以你必须匹配Flash的。
- 锁定闪光灯。这通常是通过发送用于解锁的相同序列来完成的。 (参考数据表)
不能直接写入flash...必须走完整个流程。这就是 Flash 速度慢的原因。
有些闪存支持8位写入,有些只支持16位或32位等。所以,你必须在写入时发送那么多位。
当您必须修改页面的一小部分时,请读取缓冲区中的页面。修改缓冲区中的数据。擦除页面并写入整个缓冲区。 如果您正在修改