WinCE Eboot中的OEM Flash函数

在EBOOT中提供了操作Flash的功能,可以将下载的WinCE image烧到Flash当中,这需要实现一些Flash相关的OEM函数。

这些OEM函数会在BLCOMMON模块中被调用,也就是在blcommon.c文件的DownloadImage函数中被调用。在DownloadImage函数中,一般image文件的header会被先下载并进行解析。然后调用OEMIsFlashAddr判断image所在的区域,如果是在Flash的地址空间内,那么接下来会下载image文件并调用Flash相关的OEM函数将Flash擦除并写入。下面简单介绍一下这些函数:

1. BOOL OEMIsFlashAddr(DWORD dwAddr)

该函数用于判断下载的WinCE image文件是在Flash区域中还是在RAM区域中,dwAddr是image文件的地址,如果在Flash区域中返回TRUE,否则返回FALSE,给个微软的例子:

#define FLASH_START      0
#define FLASH_LENGTH     0x02000000
BOOL OEMIsFlashAddr(DWORD dwAddr)
{
        //根据Flash的起始地址和长度判断该地址是否在Flash区域内
        if ((dwAddr >= FLASH_START) && (dwAddr < (FLASH_START + FLASH_LENGTH)))
        {
                return(TRUE);
        }

    return(FALSE);
}

2. BOOL OEMStartEraseFlash(DWORD dwStartAddr, DWORD dwLength)

该函数用于初始化Flash的擦除,dwStartAddr表示要擦除的起始地址,dwLength为长度。通过这两个参数计算Flash中要被擦除的起始block和最后一个block,以及要擦除多少个block,给个微软的例子:

BOOL OEMStartEraseFlash (DWORD dwStartAddr, DWORD dwLength)
{
    ULONG i = 0;
    ULONG nNumBlocks = 0;

    //判断起始地址和终止地址是否都在Flash区域内
    if (!OEMIsFlashAddr(dwStartAddr) || !OEMIsFlashAddr(dwStartAddr + dwLength - 1))
    {
        return(FALSE);
    }

    //确认该起始地址是Block对齐的
    if (dwStartAddr % FLASH_BLOCK_SIZE)
    {
        return(FALSE);
    }
    //确认长度是4字节对齐
    if (dwLength & 0x03)
    {
        return(FALSE);
    }

    //根据Flash的基地址和Flash的Block大小计算要擦除的起始block和最后一个
    //block以及多少个Block
    gnStartBlock = (dwStartAddr - FLASH_BASE) / FLASH_BLOCK_SIZE;
    gnEndBlock   = ((dwStartAddr + dwLength + (FLASH_BLOCK_SIZE - 1) - FLASH_BASE) / FLASH_BLOCK_SIZE);
    gnBlocks     = (int)(gnEndBlock - gnStartBlock);
    gnBlockCount = gnStartBlock;

    EdbgOutputDebugString("Erasing flash blocks: start block = %d  end block = %d/r/n", gnStartBlock, gnEndBlock);


    return(TRUE);
}

3. void OEMContinueEraseFlash (void)

该函数用于擦除Flash区域,它会在image下载后被调用来擦除Flash中的block,给个微软的例子:

void OEMContinueEraseFlash(void)
{
    UCHAR nEraseCount = BLOCK_ERASE_STEP;   //要擦除的块


    //确认所有需要擦除的block都被擦除了
    if (!gnBlocks || (gnBlockCount == gnEndBlock))
        return;

    //擦除block
    while ((gnBlockCount < gnEndBlock) && nEraseCount)
    {
        if (CFI_Erase_Block((unsigned32*)BLOCK_ADDR(gnBlockCount), 0, NULL) != PASS)
        {
            EdbgOutputDebugString("ERROR: OEMContinueEraseFlash - flash erase error (block number %d)./r/n", gnBlockCount);
            return;
        }

        ++gnBlockCount;
        --nEraseCount;
    }


    return;
}

4. BOOL OEMFinishEraseFlash (void)

该函数用于确认Flash中所有的block都被擦除完成,给个微软的例子:

BOOL OEMFinishEraseFlash(void)
{
    EdbgOutputDebugString("INFO: Finishing flash erase.../r/n");

    while(gnBlocks && (gnBlockCount != gnEndBlock))
    {
        OEMContinueEraseFlash();
    }

    return(TRUE);
}

5. BOOL OEMWriteFlash(DWORD dwImageStart, DWORD dwImageLength)

该函数用于将下载的image写入到Flash当中,dwImageStart为被写入image在Flash中的起始地址,dwImageLength为image的大小,给个微软的例子:

BOOL OEMWriteFlash(DWORD dwImageStart, DWORD dwImageLength)
{
    DWORD dwFlashAddr, dwExtraBytes = 0;
    LPBYTE pbCache = NULL;
    UCHAR nNumBlocks = 0;


    //确认起始地址和长度都在Flash区域内
    if (!OEMIsFlashAddr(dwImageStart) || !OEMIsFlashAddr(dwImageStart + dwImageLength - 1))
    {
        return(FALSE);
    }

    //确认起始地址是Block字节对齐的
    if (dwImageStart % FLASH_BLOCK_SIZE)
    {
        return(FALSE);
    }

    //计算要写入的block数量
    nNumBlocks   = (UCHAR)(dwImageLength / FLASH_BLOCK_SIZE);
    dwExtraBytes = (dwImageLength % FLASH_BLOCK_SIZE);
    dwFlashAddr  = dwImageStart;
    pbCache      = OEMMapMemAddr (dwImageStart, dwFlashAddr);


    //写Flash 
    while(nNumBlocks)
    { 
        if (CFI_Write_Block((unsigned32*)dwFlashAddr, (unsigned32*)pbCache, FLASH_BLOCK_SIZE, NULL) != PASS)
        {
            EdbgOutputDebugString("ERROR: OEMWriteFlash - unable to write to block (block address=0x%x)./r/n", dwFlashAddr);
            return(FALSE);
        }

        dwFlashAddr += FLASH_BLOCK_SIZE;
        pbCache = OEMMapMemAddr (dwImageStart, dwFlashAddr);
        --nNumBlocks;
    }

    //将额外的数据写入Flash中
    if (dwExtraBytes)
    {
        if (CFI_Write_Block((unsigned32*)dwFlashAddr, (unsigned32*)pbCache, dwExtraBytes, NULL) != PASS)
        {
            EdbgOutputDebugString("ERROR: OEMWriteFlash - unable to write to block (block address=0x%x)./r/n", dwFlashAddr);
            return(FALSE);
        }
    }

    return(TRUE);

上面的5个函数用于在eboot中支持Flash操作功能。一般在开发BSP的时候,如果需要在EBOOT中实现Flash的功能,会在EBOOT中创建一个Flash.c文件,在该文件中实现上述这些函数。建议看看blcommon.c中的DownloadImage函数,可以帮助理解。


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/nanjianhui/archive/2008/11/12/3283072.aspx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值