今天看汉字库示例,发现字库在扩展内存中的布局是一个一个紧挨着的,最开始是字库的基本信息。但是这样的安排有个问题,每个字库起始地址都不是 4k 的整数倍。这样导致随后更新该字库时,每次写 4096 字节时,都会横跨两个扇区,也就是写一个扇区都会对两个扇区进行读写甚至擦除操作。(即一个扇区可能会被擦除两遍)。
因此,考虑牺牲一点空间,让字库更新更顺畅些。这里就要求每个字库起始地址都是 4k 的整数倍即可。
相关的核心代码如下
[mw_shl_code=c,true]bool _UpdateFontMatrix(u8 aFontIndex)
{
u8 *lBuffer;
u32 lBufferLength;
u32 lSize;
u32 lByteIndex;
u32 lBaseAddress = 0;
lBuffer = MEM_Alloc(InSRAM, ExFLASH_SECTOR_SIZE); // 分配 4096 个字节空间
if(lBuffer == NULL)
return FALSE;
oDebug("@");
// 从串口读取点阵大小
lSize = 0;
while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) != SET);
lSize |= (u32)(USART_ReceiveData(USART1) & 0xFF);
while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) != SET);
lSize |= (u32)(USART_ReceiveData(USART1) & 0xFF) << 8;
while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) != SET);
lSize |= (u32)(USART_ReceiveData(USART1) & 0xFF) << 16;
while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) != SET);
lSize |= (u32)(USART_ReceiveData(USART1) & 0xFF) << 24;
oDebug("@");
switch(aFontIndex)
{
case 0: // 更新UNIGBK.BIN
gGBKInfo.gbkUniAddr = ExFLASH_FONT_BASE + (sizeof(gGBKInfo) + ExFLASH_SECTOR_SIZE - 1) / ExFLASH_SECTOR_SIZE * ExFLASH_SECTOR_SIZE; // 信息头之后,紧跟UNIGBK转换码表
gGBKInfo.gbkUniSize = lSize; // UNIGBK大小
lBaseAddress = gGBKInfo.gbkUniAddr;
break;
case 16:
gGBKInfo.gbk16Addr = gGBKInfo.gbkUniAddr + (gGBKInfo.gbkUniSize + ExFLASH_SECTOR_SIZE - 1) / ExFLASH_SECTOR_SIZE * ExFLASH_SECTOR_SIZE; // UNIGBK之后,紧跟GBK16字库,地址对齐 4096 字节。
gGBKInfo.gbk16Size = lSize; // GBK16字库大小
lBaseAddress = gGBKInfo.gbk16Addr; // GBK16的起始地址
break;
case 24:
gGBKInfo.gbk24Addr = gGBKInfo.gbk16Addr + (gGBKInfo.gbk16Size + ExFLASH_SECTOR_SIZE - 1) / ExFLASH_SECTOR_SIZE * ExFLASH_SECTOR_SIZE; // GBK16之后,紧跟GBK24字库,地址对齐 4096 字节。
gGBKInfo.gbk24Size = lSize; // GBK24字库大小
lBaseAddress = gGBKInfo.gbk24Addr; // GBK24的起始地址
break;
case 32:
gGBKInfo.gbk32Addr = gGBKInfo.gbk24Addr + (gGBKInfo.gbk24Size + ExFLASH_SECTOR_SIZE - 1) / ExFLASH_SECTOR_SIZE * ExFLASH_SECTOR_SIZE; // GBK24之后,紧跟GBK32字库,地址对齐 4096 字节。
gGBKInfo.gbk32Size = lSize; // GBK32字库大小
lBaseAddress = gGBKInfo.gbk32Addr; // GBK32的起始地址
break;
}
lBufferLength = 0;
for(lByteIndex = 1; lByteIndex <= lSize; lByteIndex++)
{
while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) != SET);
lBuffer[lBufferLength++] = USART_ReceiveData(USART1) & 0xFF;
// 缓冲区满
if(lBufferLength == ExFLASH_SECTOR_SIZE || lByteIndex == lSize)
{
ExFLASH_Write(lBuffer, lBaseAddress + lByteIndex - lBufferLength, lBufferLength); // 写入 4096 个数据
lBufferLength = 0;
LCD_DrawNum(FONTSIZE_16, lByteIndex * 100 / lSize, 138, 221, 3, FALSE, COLOR_BLACK, COLOR_WHITE);
oDebug("@");
}
}
MEM_Free(InSRAM, lBuffer); // 释放内存
return TRUE;
}[/mw_shl_code]
自己在Windows 上写了个 .Net 程序,通过串口将字库发送到战舰,更新字库成功。
顺便解释下,我的字库去掉了12点阵的,加了个32点阵的,字库起始从 8M 开始。供需空间将近 6M。
|