WinCE6.0 BootloaderMain源码分析之OEMDebugInit

简介:
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 函数负责检测某一段虚拟内存地址区域是否映射到用户实际可使用的物理存储,包括 Flash RAM ;当 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_GATE UART1 选通 PLCK g_pSysConReg->SCLK_GATE UART0~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,如需转载请自行联系原作者
相关文章
|
3月前
|
中间件 Linux 芯片
一张图秒懂嵌入式Linux系统的启动流程
一张图秒懂嵌入式Linux系统的启动流程
60 0
|
4月前
|
数据可视化 Linux UED
QT基础教程(GUI程序原理分析)
QT基础教程(GUI程序原理分析)
39 0
|
Linux API 开发工具
嵌入式linux/鸿蒙开发板(IMX6ULL)开发(十七)多线程编程(下)
嵌入式linux/鸿蒙开发板(IMX6ULL)开发(十七)多线程编程
283 0
嵌入式linux/鸿蒙开发板(IMX6ULL)开发(十七)多线程编程(下)
|
Linux 调度 开发工具
嵌入式linux/鸿蒙开发板(IMX6ULL)开发(十七)多线程编程(上)
嵌入式linux/鸿蒙开发板(IMX6ULL)开发(十七)多线程编程
207 0
嵌入式linux/鸿蒙开发板(IMX6ULL)开发(十七)多线程编程(上)
|
存储 API 调度
基于STM32移植UCGUI图形界面框架(3.9.0源码版本)
基于STM32移植UCGUI图形界面框架(3.9.0源码版本)
506 0
基于STM32移植UCGUI图形界面框架(3.9.0源码版本)
|
NoSQL 小程序 Linux
开源代码分析技巧之——高效Windows源码分析
引言:项目开发中,我们免不了在已有代码或版本的基础上新增代码。这个时候,如何高效的读懂别人代码逻辑,如何从几十万乃至上百万行代码中找到自己需要的逻辑显得尤为重要。
142 0
开源代码分析技巧之——高效Windows源码分析
|
开发工具 git
(2/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
原文:(2/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序 版权声明:本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
913 0
|
XML 物联网 开发工具
(1/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
原文:(1/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序 版权声明:本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
1229 0
|
编解码 自然语言处理 C语言
x264源代码分析-转
相关说明: 1.     使用版本:  x264-cvs-2004-05-11 2.     这次的分析基本上已经将代码中最难理解的部分做了阐释,对代码的主线也做了剖析,如果这个主线理解了,就容易设置几个区间,进行分工阅读,将各个区间击破了.
955 0