WinCE6.0 BootloaderMain源码分析之OEMDebugInit

本文详细介绍了Bootloader中OEMDebugInit函数的工作原理及其实现过程,包括调试串口的初始化步骤,如配置寄存器、设置波特率等。

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

BootloaderMain在进行全局变量重定位后,执行的便是OEMDebugInit操作,主要完成调试串口的初始化工作,这部分内容比较简单。从函数名OEM可以看出,该函数是需要用户自己开发的,而且与硬件有关。
BOOL OEMDebugInit(void) 

        // Set up function callbacks used by blcommon. 
        g_pOEMVerifyMemory     = OEMVerifyMemory;            // Verify RAM. 
        g_pOEMMultiBINNotify    = OEMMultiBINNotify; 

        // Call serial initialization routine (shared with the OAL). 
        OEMInitDebugSerial(); 

        return(TRUE); 
}
 
         从上面的实现看,前面两条语句定义的是函数指针,在blcommom.c中会调用这两个函数。OEMVerifyMemory函数负责检测某一段虚拟内存地址区域是否映射到用户实际可使用的物理存储,包括FlashRAM;当BootLoader要下载多区段的操作系统镜像时会调用函数OEMMultiBINNotify向用户发出通知。
         OEMInitDebugSerial才是该函数的重点,实现代码在/WINCE600/PLATFORM/<BSP name>/SRC/OAL/OALLIB/debug.c文件中。
VOID OEMInitDebugSerial() 

        UINT32 DivSlot; 
        UINT32 uPCLK; 
        float Div; 

        // Map SFR Address 
        // 
        if (g_pUARTReg == NULL) 
        { 
#if        (DEBUG_PORT == DEBUG_UART0) 
                // UART0 
                g_pUARTReg = (S3C6410_UART_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_UART0, FALSE); 
#elif (DEBUG_PORT == DEBUG_UART1) 
                // UART1 
                g_pUARTReg = (S3C6410_UART_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_UART1, FALSE); 
#elif (DEBUG_PORT == DEBUG_UART2) 
                // UART2 
                g_pUARTReg = (S3C6410_UART_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_UART2, FALSE); 
#elif (DEBUG_PORT == DEBUG_UART3) 
                // UART3 
                g_pUARTReg = (S3C6410_UART_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_UART3, FALSE); 
#else 
                INVALID_DEBUG_PORT                // Error 
#endif 
        } 

        if (g_pGPIOReg == NULL) 
        { 
                g_pGPIOReg = (S3C6410_GPIO_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_GPIO, FALSE); 
        } 

        if (g_pSysConReg == NULL) 
        { 
                g_pSysConReg = (S3C6410_SYSCON_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_SYSCON, FALSE); 
        } 

        // UART I/O port initialize 
#if        (DEBUG_PORT == DEBUG_UART0) 
        // UART0 Clock Enable 
        g_pSysConReg->PCLK_GATE |= (1<<1);                // UART0 
        g_pSysConReg->SCLK_GATE |= (1<<5);                // UART0~3 
        // UART0 Port Initialize (RXD0 : GPA0, TXD0: GPA1) 
        g_pGPIOReg->GPACON = (g_pGPIOReg->GPACON & ~(0xff<<0)) | (0x22<<0);                // GPA0->RXD0, GPA1->TXD0 
        g_pGPIOReg->GPAPUD = (g_pGPIOReg->GPAPUD & ~(0xf<<0)) | (0x1<<0);                        // RXD0: Pull-down, TXD0: pull up/down disable 
#elif (DEBUG_PORT == DEBUG_UART1) 
        // UART1 Clock Enable 
        g_pSysConReg->PCLK_GATE |= (1<<2);                // UART1 
        g_pSysConReg->SCLK_GATE |= (1<<5);                // UART0~3 
        // UART1 Port Initialize (RXD1 : GPA4, TXD1: GPA5) 
        g_pGPIOReg->GPACON = (g_pGPIOReg->GPACON & ~(0xff<<16)) | (0x22<<16);        // GPA4->RXD1, GPA5->TXD1 
        g_pGPIOReg->GPAPUD = (g_pGPIOReg->GPAPUD & ~(0xf<<8)) | (0x1<<8);                        // RXD1: Pull-down, TXD1: pull up/down disable 
#elif (DEBUG_PORT == DEBUG_UART2) 
        // UART2 Clock Enable 
        g_pSysConReg->PCLK_GATE |= (1<<3);                // UART2 
        g_pSysConReg->SCLK_GATE |= (1<<5);                // UART0~3 
        // UART2 Port Initialize (RXD2 : GPAB0, TXD2: GPB1) 
        g_pGPIOReg->GPBCON = (g_pGPIOReg->GPBCON & ~(0xff<<0)) | (0x22<<0);                // GPB0->RXD2, GPB1->TXD2 
        g_pGPIOReg->GPBPUD = (g_pGPIOReg->GPBPUD & ~(0xf<<0)) | (0x1<<0);                        // RXD2: Pull-down, TXD2: pull up/down disable 
#elif (DEBUG_PORT == DEBUG_UART3) 
        // UART3 Clock Enable 
        g_pSysConReg->PCLK_GATE |= (1<<4);                // UART3 
        g_pSysConReg->SCLK_GATE |= (1<<5);                // UART0~3 
        // UART3 Port Initialize (RXD3 : GPB2, TXD3: GPB3) 
        g_pGPIOReg->GPBCON = (g_pGPIOReg->GPBCON & ~(0xff<<8)) | (0x22<<8);                // GPB2->RXD3, GPB3->TXD3 
        g_pGPIOReg->GPBPUD = (g_pGPIOReg->GPBPUD & ~(0xf<<4)) | (0x1<<4);                        // RXD3: Pull-down, TXD3: pull up/down disable 
#endif 

        // Initialize UART 
        // 
        g_pUARTReg->ULCON = (0<<6)|(0<<3)|(0<<2)|(3<<0);                                        // Normal Mode, No Parity, 1 Stop Bit, 8 Bit Data 
        g_pUARTReg->UCON = (0<<10)|(1<<9)|(1<<8)|(0<<7)|(0<<6)|(0<<5)|(0<<4)|(1<<2)|(1<<0);        // PCLK divide, Polling Mode 
        g_pUARTReg->UFCON = (0<<6)|(0<<4)|(0<<2)|(0<<1)|(0<<0);                        // Disable FIFO 
        g_pUARTReg->UMCON = (0<<5)|(0<<4)|(0<<0);                                                // Disable Auto Flow Control

        uPCLK = System_GetPCLK(); 

        Div = (float)((float)uPCLK/(16.0*(float)DEBUG_BAUDRATE)) - 1;                //< S3C6410_PCLK is macro code defined in soc_cfg.h 
        DivSlot = (UINT32)((Div-(int)Div)*16); 

        g_pUARTReg->UBRDIV = (UINT32)Div;                                                                        // Baud rate 
        g_pUARTReg->UDIVSLOT = aSlotTable[DivSlot]; 
}
 
从代码可以看出,里面加了很多编译选项,增强移植性的。当需要更改调试串口时,只需要更改编译选项就可以了。
通过OALPAtoVA先将获得调试串口、GPI以及系统控制器的虚拟地址,方便后面的初始化设置。g_pSysConReg->PCLK_GATEUART1选通PLCKg_pSysConReg->SCLK_GATEUART0~3选通特殊时钟。g_pGPIOReg->GPACON设置复用IO端口为UART功能,g_pGPIOReg->GPAPUD设置相应的串口管脚位下拉使能。
g_pUARTReg->ULCON设置串口为普通模式、无校验、1个停止位和8个数据位;g_pUARTReg->UCON设置选择PCLK作为UART的波特率时钟,接收和发送中断请求类型为电平模式,而且以中断请求或轮询模式来写发送数据到UART发送缓冲寄存器或者从UART接收缓冲寄存器读数据。
最后几条代码是获得PCLK后设置波特率参数。


本文转自jazka 51CTO博客,原文链接:http://blog.51cto.com/jazka/602183,如需转载请自行联系原作者
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值