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,如需转载请自行联系原作者
相关文章
|
存储 JavaScript 前端开发
node静态文件加与不加虚拟路径
本文介绍了在Node.js中设置静态资源服务时,如何配置虚拟路径前缀。通过使用`express.static`中间件,可以指定一个虚拟前缀,使得访问静态文件时需要通过这个前缀来访问。
111 3
node静态文件加与不加虚拟路径
|
12月前
void 类型
void 类型。
113 5
【分享】多人协同办公插件——宜搭talk
【分享】多人协同办公插件——宜搭talk
874 0
|
存储 机器学习/深度学习 分布式计算
Hadoop中的DataNode、工作机制、数据完整性、掉线时限参数设置
思考:如果电脑磁盘里面存储的数据是控制高铁信号灯的红灯信号(1)和绿灯信号(0),但是存储该数据的磁盘坏了,一直显示是绿灯,是否很危险?(1)一个数据块在DataNode上以文件形式存储在磁盘上,包括两个文件,一个是数据本身,一个是元数据包括数据块的长度,块数据的校验和,以及时间戳。(2)DataNode启动后向NameNode注册,通过后,周期性(6小时)的向NameNode上报所有的块信息。(4)常见的校验算法crc(32),md5(128),sha1(160)用这个网站检验CRC循环冗余校验。...
518 1
Hadoop中的DataNode、工作机制、数据完整性、掉线时限参数设置
西门子S7-1200的程序结构,块,组织块OB,功能块FB,功能FC
在S7-1200的编程中采用了块的概念,即将程序分解为独立的自成体系的各个部件,块类似于子程序的功能,但类型更多,功能更强大。在工业控制中,程序往往是非常庞大和复杂的,采用块的概念,便于大规模的程序设计和理解,也可以设计标准化的块程序进行重复调用。在S7-1200中支持以下类型的代码块,使用他们可以创建有效的用户程序结构,组织块OB、功能FC、功能块FB、数据块DB。
西门子S7-1200的程序结构,块,组织块OB,功能块FB,功能FC
|
架构师 大数据 云计算
阿里云的认证考试难不难?证书有效期是多久?
对于大多数人来说,阿里云ACP认证是一个非常好的认证,综合性价比非常高,阿里云的绝大多数认证,这个都是最高级的认证,在工作后,可以考这个认证来帮助自己提升的能力,为自己未来的发展做更好的打算。
阿里云的认证考试难不难?证书有效期是多久?
|
JavaScript 前端开发 Dart
《现代Typescript高级教程》序言
序言 自己学习过程中总结的的Typescript高级教程,适合有一定Typescipt基础的同学学习 在线阅读 解析TypeScript最新特性,包括装饰器、泛型、高级类型以及元数据反射等实战指南。 结合最新的语法特性和生动的代码示例,本教程将引领你跃过TypeScript的高级阶段,更深入理解和应用静态类型语言的优势。
212 0
|
Java C# C++
我个人总结的Halcon内存管理心得笔记,关于C#/C++内存释放
我个人总结的Halcon内存管理心得笔记,关于C#/C++内存释放
2245 0
我个人总结的Halcon内存管理心得笔记,关于C#/C++内存释放
java有关的打包文件.jar、.war、.ear
java有关的打包文件.jar、.war、.ear
188 0