原先用的开发板的开机LOGO是用数组的形式放进EBOOT.BIN和NK.BIN中的,这样带来的问题是:图片分辨率很大的时候需要修改EBOOT.BIN。另外如果我们需要经常更新LOGO的话,还要重新编译,这个如果源码不开放,那就抓狂了。用EBOOT来下载更新LOGO,就是把LOGO放到NAND的固定块中去。让系统起来后自己去读它。然后显示出来。
开发平台:
SC32440+64MB NAND+64MB SDRAM + WINCE5.0
基本流程:
1,在EBOOT中MAIN.C中添加下载图片二进制文件的驱动命令函数,并且在loader.h中申请函数定义;
//add for logo判断二进制文件是不是LOGO.bin else if ((dwStartAddr >= LOGO_STORE_ADDRESS) && ((dwStartAddr + dwLength - 1) < (LOGO_STORE_ADDRESS + LOGO_STORE_MAX_LENGTH))) { OALMSG(1, (TEXT(" LOGO image is ture,beginning downloading /r/n"))); 这个地址和大小在loader.h中声明
//ADD FOR LOGO case IMAGE_TYPE_LOGO: //if (!WriteLogoToBootMedia(IMAGE_FRAMEBUFFER_UA_BASE, 800*600*2, IMAGE_FRAMEBUFFER_UA_BASE)) if (!WriteLogoToBootMedia(dwImageStart, dwImageLength,dwLaunchAddr)) { OALMSG(OAL_ERROR, (TEXT("ERROR: OEMLaunch: Failed to download LOGO image./r/n"))); } OALMSG(TRUE, (TEXT("INFO: DOWNIMAGE IS OK...RESTART,SHOW LOGO/r/n")));
调用下载LOGO到NAND的函数(这个函数在NAND.CPP中实现),具体实现可以参考NK的下载函数,举例仅此参考: BOOL WriteLogoToBootMedia(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr) { DWORD dwBlock,dwNumBlocks; LPBYTE pbBuffer; SectorInfo si; dwBlock = LOGO_BLOCK; //dwBlock = LOGO_BLOCK+ dwNumBlocks-1; //pbBuffer = (LPBYTE)IMAGE_FRAMEBUFFER_UA_BASE; OALMSG(1, (TEXT("dwImageStart: =0x%x./r/n"), dwImageStart)); pbBuffer = OEMMapMemAddr(dwImageStart, dwImageStart); OALMSG(1, (TEXT("pbBuffer: =0x%x./r/n"), pbBuffer)); // Compute number of blocks. //dwNumBlocks = (dwImageLength / 0x4000) + 1; dwNumBlocks = (dwImageLength / (g_FlashInfo.wDataBytesPerSector*g_FlashInfo.wSectorsPerBlock)) + (dwImageLength%(g_FlashInfo.wDataBytesPerSector*g_FlashInfo.wSectorsPerBlock) ? 1: 0); OALMSG(TRUE, (TEXT("dwImageLength = 0x%x /r/n"), dwImageLength)); OALMSG(TRUE, (TEXT("dwNumBlocks = 0x%x /r/n"), dwNumBlocks)); //dwBlock = LOGO_BLOCK+dwNumBlocks; //添加数据取反 考虑图片位置颠倒,所以对BUFF里数据前后交换2010.4.12 //int a=960000; //int i=0; //unsigned int * p1=(unsigned int *)pbBuffer; //for(i=0;i<a;i++) //{p1[i]=p1[a-1]; //a--; // } while (dwNumBlocks--) { // If the block is marked bad, skip to next block. Note that the assumption in our error checking // is that any truely bad block will be marked either by the factory during production or will be marked // during the erase and write verification phases. If anything other than a bad block fails ECC correction // in this routine, it's fatal. OALMSG(TRUE, (TEXT("dwBlock(0x%x) X "), dwBlock)); OALMSG(TRUE, (TEXT("g_FlashInfo.wSectorsPerBlock(0x%x)"), g_FlashInfo.wSectorsPerBlock)); OALMSG(TRUE, (TEXT(" = 0x%x /r/n"), dwBlock*g_FlashInfo.wSectorsPerBlock)); FMD_ReadSector(dwBlock*32, NULL, &si, 1); // Stepldr & Eboot image in nand flash // block mark as BLOCK_STATUS_RESERVED & BLOCK_STATUS_READONLY & BLOCK_STATUS_BAD if ((si.bBadBlock == 0x0) && (si.bOEMReserved !=3 )) { ++dwBlock; //--dwBlock; ++dwNumBlocks; // Compensate for fact that we didn't write any blocks. continue; } if (!ReadBlock(dwBlock, NULL, g_pSectorInfoBuf)) { OALMSG(OAL_ERROR, (TEXT("WriteData: failed to read block (0x%x)./r/n"), dwBlock)); return(FALSE); } if (!FMD_EraseBlock(dwBlock)) { OALMSG(OAL_ERROR, (TEXT("WriteData: failed to erase block (0x%x)./r/n"), dwBlock)); return FALSE; } if (!WriteBlock(dwBlock, pbBuffer, g_pSectorInfoBuf)) { OALMSG(OAL_ERROR, (TEXT("WriteData: failed to write block (0x%x)./r/n"), dwBlock)); return(FALSE); } ++dwBlock; //--dwBlock; OALMSG(1, (TEXT("pbBuffer: =0x%x./r/n"), pbBuffer)); pbBuffer += 0x4000; //pbBuffer +=g_FlashInfo.wSectorsPerBlock; } OALMSG(1, (TEXT("_WriteLOGOImageToBootMedia/r/n"))); return TRUE; }
1, 在EBOOT初始化LCD的时候添加显示LOGO的函数,此函数可以在NAND.CPP中实现,具体可以参考NK的读取函数,这里给个DEMO:
/add for read logo BOOL Display_LOGO(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr) //added for diplaylogo { unsigned int * pFB32 = (unsigned int *)IMAGE_FRAMEBUFFER_UA_BASE; unsigned int * dst = pFB32; SectorInfo si; DWORD dwBlock,dwNumBlocks; dwBlock = LOGO_BLOCK; OALMSG(TRUE, (TEXT("dwImageLength = 0x%x /r/n"), dwImageLength)); dwNumBlocks = (dwImageLength / (g_FlashInfo.wDataBytesPerSector*g_FlashInfo.wSectorsPerBlock)) + (dwImageLength%(g_FlashInfo.wDataBytesPerSector*g_FlashInfo.wSectorsPerBlock) ? 1: 0); // Compute number of blocks. //dwNumBlocks = 1; OALMSG(TRUE, (TEXT("dwNumBlocks = 0x%x /r/n"), dwNumBlocks)); OALMSG(1, (TEXT(" ~~~~~~~~~~~~~~~~START~~~~~~~~~~~~~~~~~~~~~~~~~~ /r/n" ))); OALMSG(1, (TEXT(" show logo 800*600 ./r/n" ))); //dwBlock = LOGO_BLOCK+dwNumBlocks; while (dwNumBlocks--) { OALMSG(TRUE, (TEXT("dwBlock(0x%x) X "), dwBlock)); OALMSG(TRUE, (TEXT("g_FlashInfo.wSectorsPerBlock(0x%x)"), g_FlashInfo.wSectorsPerBlock)); OALMSG(TRUE, (TEXT(" = 0x%x /r/n"), dwBlock*g_FlashInfo.wSectorsPerBlock)); FMD_ReadSector(dwBlock*g_FlashInfo.wSectorsPerBlock, NULL, &si, 1); //FMD_ReadSector(dwBlock*32, (LPBYTE)p, &si, 1); // Stepldr & Eboot image in nand flash // block mark as BLOCK_STATUS_RESERVED & BLOCK_STATUS_READONLY & BLOCK_STATUS_BAD if ((si.bBadBlock == 0x0) && (si.bOEMReserved !=3 )) { ++dwBlock; //--dwBlock; ++dwNumBlocks; // Compensate for fact that we didn't write any blocks. continue; } if (!ReadBlock(dwBlock,(LPBYTE)dst, g_pSectorInfoBuf)) //注意这个地方g_pSectorInfoBuf指Sector spare 大小是32*16 { OALMSG(OAL_ERROR, (TEXT("WriteData: failed to read block (0x%x)./r/n"), dwBlock)); return(FALSE); } dst += g_FlashInfo.dwBytesPerBlock/4; ++dwBlock; } return TRUE;
注意:如果出现读取的时候显示初始阶段屏幕抖的问题,可以采用先读取LOGO,后点亮背光,这样就看不到抖了,最后注意在调用NAND相关函数的时候,要在EBOOT main.c下面先初始化,还要注意LOADER.H中对NAND分区的了解和处理
好了本人人生第一篇博文诞生了!!haha~~