⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ethdown.c

📁 这个是嵌入式arm系列的一个bootloader程序。对需要编写bootloader的很有参考价值
💻 C
📖 第 1 页 / 共 2 页
字号:
				EdbgOutputDebugString( "%B ", pbData[i] );
			}
			break;

		default:
			EdbgOutputDebugString( "EthDown::Illegal Operation Code %u\r\n", Operation );
			return 1;
			break;

	} // switch
	return 0;
}

UINT16 FlashErase(DWORD dwPhysStart, DWORD dwPhysLen) 
{
    int FLASH_SIZE = 16777216 * 2;
    int ERASE_BLOCKS = 128;
    int BLOCK_SIZE = FLASH_SIZE / ERASE_BLOCKS;
    DWORD i,j;
    DWORD num_blocks;
    volatile DWORD *pdwFlash;
	int status;

    // Determine the number of blocks to erase.
	num_blocks = (dwPhysLen / (BLOCK_SIZE));
	if (dwPhysLen % (BLOCK_SIZE))
		num_blocks++;

    if (num_blocks < 1)
    {
        num_blocks = 1;
        EdbgOutputDebugString("Calculation error.  Erase blocks = %d\n\r", num_blocks);
    } 

	else if (num_blocks > 128)
    {
        num_blocks = 128;
        EdbgOutputDebugString("Calculation error.  Erase blocks = %d\n\r", num_blocks);
    }

    pdwFlash = (volatile DWORD *)(dwPhysStart | CACHED_TO_UNCACHED_OFFSET);

	//Issue the clear lock bits and confirm command.
	*pdwFlash = 0x00600060;
	*pdwFlash = 0x00d000d0;

	i = 0;
	while((i & 0x00800080) != 0x00800080)
	{
		i = *pdwFlash;
	}
	
	if ((i & 0x00000008) == 0x00000008)
		EdbgOutputDebugString("\r\nVoltage Range Error ... Lower flash.\r\n");
	if ((i & 0x00080000) == 0x00080000)
		EdbgOutputDebugString("\r\nVoltage Range Error ... Upper flash.\r\n");

	if ((i & 0x00000030) == 0x00000030)
		EdbgOutputDebugString("\r\nCommand Sequence Error ... Lower flash.\r\n");
	if ((i & 0x00300000) == 0x00300000)
		EdbgOutputDebugString("\r\nCommand Sequence Error ... Upper flash.\r\n");

	if ((i & 0x00000020) == 0x00000020)
		EdbgOutputDebugString("\r\nClear Lock Bits Error ... Lower flash.\r\n");
	if ((i & 0x00200000) == 0x00200000)
		EdbgOutputDebugString("\r\nClear Lock Bits Error ... Upper flash.\r\n");

	if (i != 0x00800080)
	{
		EdbgOutputDebugString("Status register returned 0x%X\r\n", i);
		EdbgOutputDebugString("Unrecoverable failure encountered while erasing flash.  System halted!\r\n");
		while(1);
	}


	// Clear the status register
	*pdwFlash = 0x00500050;

	EdbgOutputDebugString("\r\nErasing Flash %X to %X: Please wait ... \r\n", dwPhysStart, dwPhysStart + (num_blocks*256*1024) - 1);

	// Erase each block.  
    for(j = 0; j < num_blocks; j++)
    {
		//EdbgOutputDebugString("Erasing 0x%X\r\n", pdwFlash);

		// Issue erase and confirm command
		*pdwFlash = 0x00200020;
		*pdwFlash = 0x00d000d0;
		while((*pdwFlash & 0x00800080) != 0x00800080);
		
		// Check if the flash block erased successfully.  
		// Was either block locked?
		status = *pdwFlash;
		if ((status & 0x00200000) || (status & 0x00000020))
		{
			if (status & 0x00200000)
			{
				EdbgOutputDebugString("\n\rBlock erase failure.  Lock bit upper flash set!\r\n");
			}

			if (status & 0x00000020)
			{
				EdbgOutputDebugString("\n\rBlock erase failure.  Lock bit lower flash set!\r\n");
			}
			
		 	EdbgOutputDebugString("Unrecoverable failure encountered while erasing flash.  System halted!\r\n");
			while(1);
		}
		EdbgOutputDebugString(".");
		pdwFlash += (BLOCK_SIZE / 4); 
        
    }

    // Put flash back into read mode
    pdwFlash = (volatile DWORD *)(dwPhysStart | CACHED_TO_UNCACHED_OFFSET);
    *pdwFlash = 0x00FF00FF;

    EdbgOutputDebugString("\r\nPerforming erase verification ... \r\n");
	for(i = 0; i < dwPhysLen / 4; i++)
	{
		if (*pdwFlash++ != 0xFFFFFFFF)
		{
			EdbgOutputDebugString("\r\nErase verification failure at address 0x%X Data 0x%X. \r\n", pdwFlash-1, *(pdwFlash-1));
		 	EdbgOutputDebugString("Unrecoverable failure encountered while erasing flash.  System halted!\r\n");
			while(1);
		}
	}

	EdbgOutputDebugString("\r\nFlash erasing complete. \r\n");
	return 0;
}

#if defined ( RTECH_FLAG )
UINT16 FlashWrite( DWORD dwPhysStart, DWORD dwFlashCache, DWORD dwPhysLen) 
{
    volatile DWORD *pdwFlash;
    volatile DWORD *pdwBlockAddress;
    volatile DWORD *pdwDeviceAddress;
    volatile DWORD *pdwFlashCache;
	volatile DWORD *pdwFlashStart;
	volatile DWORD *pdwRamStart;
	DWORD dwLength = dwPhysLen;
	DWORD i,j,b;
	DWORD val = 0;
	DWORD count;

	// If we are loading a .BIN file into FLASH, we'll need to write it above EBOOT
	// so that EBOOT is not written over by this file.  Then, when the system next boots,
	// EBOOT can allow the user to choose whether to copy the flashed image into RAM,
	// or continue with normal EBOOT image loading services.  

	pdwFlash =			(volatile DWORD *)(dwPhysStart | CACHED_TO_UNCACHED_OFFSET);
    pdwBlockAddress =	(volatile DWORD *)(dwPhysStart | CACHED_TO_UNCACHED_OFFSET);
    pdwDeviceAddress =	(volatile DWORD *)(dwPhysStart | CACHED_TO_UNCACHED_OFFSET);
	pdwFlashCache =		(volatile DWORD *)(dwFlashCache | CACHED_TO_UNCACHED_OFFSET);

	EdbgOutputDebugString("FStartAddr = 0x%x , FCacheAddr = 0x%x.\r\n", pdwFlash, pdwFlashCache );
	
	FlashErase((DWORD)pdwFlash, dwPhysLen);

	b = 0;

	EdbgOutputDebugString("\n\rNow programming Flash ... \r\n");
    while( dwPhysLen > 0)
    {
        // The Flash can write BLOCK_WRITE_SIZE (16) WORDS at a time (32 bytes) into each Flash device.
        // Calculate the number of DWORDS to program in each iteration.
        if (dwPhysLen > 64)
            count = 16;
        else
            count = dwPhysLen / 4;

        // Issue Write to Buffer Command
        *pdwBlockAddress = 0x00E800E8;

        // Check that the write buffer is available.
        // Read the Extended Status Register and
        // wait for the assertion of XSR[7] before continuing.
        while( (*pdwBlockAddress & 0x00800080) != 0x00800080)
        {
            *pdwBlockAddress = 0x00E800E8;
        }
        
        // Configure the size of the buffer that we will write.
        // Write the word count (device expects a 0 based number)
        *pdwBlockAddress = ((count - 1) << 16 | (count - 1));

		pdwFlashStart = pdwDeviceAddress;
		pdwRamStart = pdwFlashCache;

        // Write up to 16 DWORDS into the Flash memory staging area
		for(i = 0; i < count; i++)
        {
            *pdwDeviceAddress++ = *pdwFlashCache++;
	    }

		// increment the number of 64 byte segments written.
		b++;

        // Now program the buffer into Flash
        *pdwBlockAddress = 0x00D000D0;
        
        i = 0;
        while((i & 0x00800080) != 0x00800080)
        {
            i = *pdwBlockAddress;
        }

        dwPhysLen -= count << 2;

		// Read back the segment just written
	    *pdwFlash = 0x00FF00FF;
		for (i = 0; i < count; i++)
		{
			if(*pdwFlashStart++ != *pdwRamStart++)
			{
				EdbgOutputDebugString( "\r\nFlash programming failure at address\r\n%X: Ideal %X Actual %X\r\n", pdwFlashStart-1, *(pdwRamStart-1), *(pdwFlashStart-1) );
				return 1;
			}
		}

        if ((b % 4096) == 0) // every 64 * 4096 bytes (256K bytes) (128K each device)
		{
			EdbgOutputDebugString(".");
		}
    }
	
	pdwFlash =	(volatile DWORD *)( dwPhysStart | CACHED_TO_UNCACHED_OFFSET);

	// Put Flash into read mode.
    *pdwFlash = 0x00FF00FF;

	EdbgOutputDebugString( "\r\nComparing Flash vs RAM image ...\n\r");

	pdwFlashCache = (volatile DWORD *)( dwFlashCache | CACHED_TO_UNCACHED_OFFSET);
	
    for( j = 0; j < dwLength/4; j++ ) 
    {

		if(*pdwFlash++ != *pdwFlashCache++)
        {
			EdbgOutputDebugString( "\r\nBeat!\r\n%X: Ideal %X Actual %X\r\n", pdwFlash-1, *(pdwFlashCache-1), *(pdwFlash-1) );
			return 1;
		}
	}
	EdbgOutputDebugString( "Flash programmed successfully!\r\n" );

    return 0;
}

#else
UINT16 FlashWrite( DWORD dwPhysStart, DWORD dwPhysLen) 
{

    volatile DWORD *pdwFlash;
    volatile DWORD *pdwBlockAddress;
    volatile DWORD *pdwDeviceAddress;
    volatile DWORD *pdwFlashCache;
	volatile DWORD *pdwFlashStart;
	volatile DWORD *pdwRamStart;
	DWORD dwLength = dwPhysLen;
	DWORD i,j,b;
	DWORD val = 0;
	DWORD count;

	pdwFlash =			(volatile DWORD *)((FLASH_START + dwEBOOT_OFFSET) | CACHED_TO_UNCACHED_OFFSET);
    pdwBlockAddress =	(volatile DWORD *)((FLASH_START + dwEBOOT_OFFSET) | CACHED_TO_UNCACHED_OFFSET);
    pdwDeviceAddress =	(volatile DWORD *)((FLASH_START + dwEBOOT_OFFSET) | CACHED_TO_UNCACHED_OFFSET);
	pdwFlashCache =		(volatile DWORD *)(dwPhysStart | CACHED_TO_UNCACHED_OFFSET);

	FlashErase((DWORD)pdwFlash, dwPhysLen);

	b = 0;

	EdbgOutputDebugString("\n\rNow programming Flash ... \r\n");
    while( dwPhysLen > 0)
    {
        // The Flash can write BLOCK_WRITE_SIZE (16) WORDS at a time (32 bytes) into each Flash device.
        // Calculate the number of DWORDS to program in each iteration.
        if (dwPhysLen > 64)
            count = 16;
        else
            count = dwPhysLen / 4;

        // Issue Write to Buffer Command
        *pdwBlockAddress = 0x00E800E8;

        // Check that the write buffer is available.
        // Read the Extended Status Register and
        // wait for the assertion of XSR[7] before continuing.
        while( (*pdwBlockAddress & 0x00800080) != 0x00800080)
        {
            *pdwBlockAddress = 0x00E800E8;
        }
        
        // Configure the size of the buffer that we will write.
        // Write the word count (device expects a 0 based number)
        *pdwBlockAddress = ((count - 1) << 16 | (count - 1));

		pdwFlashStart = pdwDeviceAddress;
		pdwRamStart = pdwFlashCache;

        // Write up to 16 DWORDS into the Flash memory staging area
		for(i = 0; i < count; i++)
        {
            *pdwDeviceAddress++ = *pdwFlashCache++;
	    }

		// increment the number of 64 byte segments written.
		b++;

        // Now program the buffer into Flash
        *pdwBlockAddress = 0x00D000D0;
        
        i = 0;
        while((i & 0x00800080) != 0x00800080)
        {
            i = *pdwBlockAddress;
        }

        dwPhysLen -= count << 2;

		// Read back the segment just written
	    *pdwFlash = 0x00FF00FF;
		for (i = 0; i < count; i++)
		{
			if(*pdwFlashStart++ != *pdwRamStart++)
			{
				EdbgOutputDebugString( "\r\nFlash programming failure at address\r\n%X: Ideal %X Actual %X\r\n", pdwFlashStart-1, *(pdwRamStart-1), *(pdwFlashStart-1) );
				return 1;
			}
		}

        if ((b % 4096) == 0) // every 64 * 4096 bytes (256K bytes) (128K each device)
		{
			EdbgOutputDebugString(".");
		}
    }
	
	pdwFlash =	(volatile DWORD *)((FLASH_START+dwEBOOT_OFFSET) | CACHED_TO_UNCACHED_OFFSET);

	// Put Flash into read mode.
    *pdwFlash = 0x00FF00FF;

	EdbgOutputDebugString( "\r\nComparing Flash vs RAM image ...\n\r");

	pdwFlashCache = (volatile DWORD *)(dwPhysStart | CACHED_TO_UNCACHED_OFFSET);
	
    for( j = 0; j < dwLength/4; j++ ) 
    {

		if(*pdwFlash++ != *pdwFlashCache++)
        {
			EdbgOutputDebugString( "\r\nBeat!\r\n%X: Ideal %X Actual %X\r\n", pdwFlash-1, *(pdwFlashCache-1), *(pdwFlash-1) );
			return 1;
		}
	}
	EdbgOutputDebugString( "Flash programmed successfully!\r\n" );

    return 0;
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -