Windows CE嵌入式开发入门——基于Xscale架构(2)

本文分析了SMDK2410平台BootLoader的主要组件及其实现过程,包括OEMDebugInit函数用于调试串口初始化、OEMPlatformInit函数负责硬件初始化配置、OEMPreDownload函数控制操作系统下载前的准备工作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

下面是SMDK2410中的BootLoader中的main函数实现代码:

 

void main(void)

{

     //清空LED

     OEMWriteDebugLED(0, 0xF);

     //通用BootLoader (blcommon)主入口

    BootloaderMain();

//注意,在此调用了BootloaderMain函数,并且没有返回值

     SpinForever();

}

 

1BLCOMMON模块函数

下面列举出BLCOMMON中的控制函数并分析它们,这些函数在Blcommon.h中声明,代码实现在Blcommon.lib里:

n     OEMDebugInit函数:

在运行BootloaderMain程序后,将首先调用OEMDebugInit函数,它用来初始化调试信息的I/O设备,最常见的是串口设备。由于RS232协议简单性,在系统没有启动前对串口初始化较适用。在OEMDebugInit里,又通常调用OEMInitDebugSerial函数来初始化串口。

n     OEMPlatformInit函数

OEM层的初始化函数,它主要负责目标机上的硬件初始化。在汇编阶段只是初始化了很小一部分硬件,这是由于BootLoader要求处理时间短,因此在汇编阶段的硬件初始化是十分简单的。所以有必要用高级语言完成对目标机的硬件设置,这包括具体的时钟设置、驱动和传输设备接口的初始化。

下面是此函数代码实例:

 

BOOL OEMPlatformInit(void)

{

    BYTE BootDelay;

    BYTE KeySelect;

    EBOOT_CFG EbootCfg;

    DWORD dwStartTime, dwPrevTime, dwCurrTime;

    PCI_REG_INFO NANDInfo;

EdbgOutputDebugString("Microsoft Windows CE Bootloader for the Samsung SMDK2410 Version %d.%d Built %s/r/n/r/n", EBOOT_VERSION_MAJOR, EBOOT_VERS
ION_MINOR, __DATE__);

    //初始化LCD显示器

    InitDisplay();

    // 初始化驱动全局区域

    memset(pDriverGlobals, 0, sizeof(DRIVER_GLOBALS));

    pDriverGlobals->MajorVer = DRVGLB_MAJOR_VER;

    pDriverGlobals->MinorVer = DRVGLB_MINOR_VER;

    pDriverGlobals->eth.EbootMagicNum = EBOOT_MAGIC_NUM;

    // 初始化FlashSMDK2410上的FLASHAMD AM29LV800型。

    if (!AM29LV800_Init(AMD_FLASH_START))

    {

       RETAILMSG(1, (TEXT("ERROR: OEMPlatformInit: Flash 初始化

           failed./r/n")));

       return(FALSE);

    }

    ........  

    // 让用户选择启动选项

    while((dwCurrTime - dwStartTime) < EbootCfg.BootDelay)

    {

        KeySelect = OEMReadDebugByte();

        ......

    }

    switch(KeySelect)//判别用户命令

    {

    case 0x20: // 根菜单项

        g_bDownloadImage = MainMenu(&EbootCfg);

        break;

    case 0x00: //无按键失败

    case 0x0d: //用户取消了倒计时

    default:

        if (EbootCfg.ConfigFlags & CONFIG_FLAGS_AUTOBOOT)

        {

             EdbgOutputDebugString ( "/r/nLaunching flash image  ... /r/n");

             g_bDownloadImage = FALSE;

        }

        else

        {

             EdbgOutputDebugString ( "/r/nStarting auto-download ... /r/n");

             g_bDownloadImage = TRUE;

        }

        break;

    }

    //如果用户指定了静态IP地址,那么就使用静态IP地址(不使用DHCP)

    if (g_bDownloadImage && !(EbootCfg.ConfigFlags & CONFIG_FLAGS_DHCP))

    {

       pDriverGlobals->eth.TargetAddr.dwIP = EbootCfg.IPAddr;

       pDriverGlobals->eth.SubnetMask      = EbootCfg.SubnetMask;

    }

    //配制以太网控制器

    if (!InitEthDevice(&EbootCfg))

    {

       DEBUGMSG(1, (TEXT("OEMPlatformInit: Failed to initialize Ethernet

           controller./r/n")));

       return(FALSE);

    }

    return(TRUE);

}

 

n     OEMPreDownload函数

在下载操作系统前执行这个函数,它可以用来设置如何进行Image文件下载。例如,可以设置成从网络下载或者跳过下载直接加载Flash中的Image文件。

下面是此函数代码实例:

 

DWORD OEMPreDownload(void)

{

    CHAR szDeviceName[EDBG_MAX_DEV_NAMELEN];

    BOOL  bGotJump = FALSE;

    DWORD dwDHCPLeaseTime = 0;

    PDWORD pdwDHCPLeaseTime = &dwDHCPLeaseTime;

    DWORD dwBootFlags = 0;

    //如果用户想进入已存在的映像,那么跳过下载

    if (!g_bDownloadImage)

    {

         g_bWaitForConnect = FALSE;  // 不等待宿主机连接

         return(BL_JUMP);

    }

    //如果用户想用一个静态IP地址,那么就不要从DHCP服务器请求一个地址

    //DHCP租期时间变量设置为NULL

    if (pDriverGlobals->eth.TargetAddr.dwIP &&

         pDriverGlobals->eth.SubnetMask)

    {

         pdwDHCPLeaseTime = NULL;

         RETAILMSG(1, (TEXT("INFO: Using static IP address %s./r/n"),

              inet_ntoa(pDriverGlobals->eth.TargetAddr.dwIP)));

RETAILMSG(1, (TEXT("INFO: Using subnet mask %s./r/n"),
inet_ntoa(pDriverGlobals->eth.SubnetMask)));

    }

    //创建基于以太网地址的设备名称(也就是Platform Builder如何定义设备)

    //

    memset(szDeviceName, 0, EDBG_MAX_DEV_NAMELEN);

    CreateDeviceName(&pDriverGlobals->eth.TargetAddr, szDeviceName,

        PLATFORM_STRING);

    EdbgOutputDebugString("INFO: Using device name: '%s'/n", szDeviceName);

    //初始化TFTP传送

    //

    if (!EbootInitEtherTransport(&pDriverGlobals->eth.TargetAddr,

                                   &pDriverGlobals->eth.SubnetMask,

                                  &bGotJump,

                                  pdwDHCPLeaseTime,

                                  EBOOT_VERSION_MAJOR,

                                   EBOOT_VERSION_MINOR,

                                   PLATFORM_STRING,

                                   szDeviceName,

                                   EDBG_CPU_ARM720,

                                   dwBootFlags))

    {

        return(BL_ERROR);

    }

    //保存DHCP租期时间(注意,本例中使用的是静态IP)

    pDriverGlobals->eth.DHCPLeaseTime = dwDHCPLeaseTime;

    return(bGotJump ? BL_JUMP : BL_DOWNLOAD);

}

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值