WINCE4.2到5.0(3)

WINCE4.2到5.0(3)

差不多完成了全部工作,系统也能正常运行。还是记录下遇到的一些问题,以备将来查找。

  1. NK.bin 文件大小的问题,如果使用中文环境,最后生成的NK.bin大小应该在30M左右,使能默认的英文环境,大小在17M左右。事实上增加了catalog, 并不会另nk.bin文件级数增长,大多数都是几十K大小。如增加对standard sdk的支持,并不会增大多少容量的flash。
  2. CS8900 驱动,将4.2的拿来用,编译排错后,发现只是可以在nk.bin烧录进flash并启动后,可以正常使用,下电重启后,连cs8900网卡都找不到。这 个问题费了我太多的时间,几乎都想放弃了,后来终于解决了:在是cs8900初始化的时候,先进行读取cs8900的id等硬件信息,然后再初始化 8900用到的总线(bank5)。这个的顺序应该反一下,先进行对总线的初始化,再读ID与初始化8900的硬件信息。具体在驱动的cs8900.c文 件的CS8900Initialize()函数内,将对CSInit()的调用放在总线与寄存器初始化之后进行即可。那为什么在4.2下,即使是这样的反 序调用也是可以的呢,因为4.2的内核在启动时,我就对cs8900用到的总线进行了初始化,而5.0的内核我没有去处理,这样层次、结构清晰了然。
  3. CS8900中断,接上次写的一篇日记。5.0的中断处理与4.2有很大的不同。我用的是EINT11中断,需要做的工作是:
    1>在网卡驱动中对8900用到的EINT11进行初始化。
    2>在BSPIntrInit()函数中,对EINT11与SYSINTR_ETHERNET进行静态映射。
    3> 修改cs8900相关的注册表信息,将键值SysIntr和InterruptNumber赋值为SYSINTR_ETHERNET对应的十六进制值。这 里为什么有两个键值,实际上SysIntr是5.0的,而InterruptNumber是4.2下的,我为了节省时间,写了两个。不知道是pdd层还是 mdd层使用了这个键值,查起来也方便。
    4>修改cs8900注册表中的IoBaseAddress键值
    5>做到以上四个步 骤后,已经可以将cs8900驱动起来了。要稳定工作,还不够,因为这里有个特定的bug。cs8900中断后,将会产生一个中断标志,然后内核产生中断 后去读数据,读完后再去清除cs8900的这个中断标志。如果内核不清除这个标志,cs8900下次再有数据传输时,将不会产生中断给内核。了解这点后, 再看内核的操作流程。内核在接到中断并读取数据后并清除cs8900的中断标志后,将会调用OEMInterruptEnable()函数,以再次开放 cs8900对应的中断,而这个OEMInterruptEnable()会依次清除SRCPND,INTPND,INTMSK,EINTMSK等寄存 器。那么如果内核在中断并读取CS8900数据并清除8900的中断标志,与,调用OEMInterruptEnable()函数之间这时cs8900接 收数据并产生中断这样一种非典型性的情况下,在这种情况下,由于8900产生了中断标志,然后OEMInterruptEnable()函数清除了 SRCPND,INTPND对应的标志,使得内核无法知道有中断产生了,而cs8900的中断标志又一直存在,这样的由于cs8900的这一特性,将会导 致cs8900不能工作了。事实证明,这种情况并不是不常见,而是很常见,经常会发生这样的情况。解决方法是在OEMInterruptEnable() 函数中不要每次对都SRCPND,INTPND进行清除。由于是5.0的系统,跟4.2有很大的不一样,在5.0中 OEMInterruptEnable()会调用OalIntrEnableIrqs(),这个函数里,会调用BSPIntrEnableIrq()函数 给BSP一个操作的机会,那就可以在BSPIntrEnableIrq()里更改,我把它改造成了这样:(原来的函数就是打印两个信息)

    BOOL g_EthInited = FALSE;

    UINT32 BSPIntrEnableIrq(UINT32 irq)
    {
        UINT32 msk;
        S3C2410X_INTR_REG * pIntrRegs; 
        S3C2410X_IOPORT_REG * pPortRegs;
        pIntrRegs = (S3C2410X_INTR_REG*)OALPAtoVA(S3C2410X_BASE_REG_PA_INTR,FALSE);
        pPortRegs = (S3C2410X_IOPORT_REG*)OALPAtoVA(S3C2410X_BASE_REG_PA_IOPORT,FALSE);
        if (irq == IRQ_EINT11)
        {
            if (g_EthInited == FALSE)
            {
                RETAILMSG(1,(TEXT("ethernet irq enable... by xiaoyunsoft 2008-09-25/r/n")));
                msk = 1 << (irq - IRQ_EINT4 + 4);
                OUTREG32(&pPortRegs->EINTPEND, msk);
                msk = 1 << IRQ_EINT8_23;
                OUTREG32(&pIntrRegs->SRCPND,msk);
            if ((INREG32(&pIntrRegs->INTPND) & msk) != 0)
            {
              OUTREG32(&pIntrRegs->INTPND, msk);
            }
            g_EthInited = TRUE;
          }
          msk = 1<<(irq-IRQ_EINT4+4);  
          CLRREG32(&pPortRegs->EINTMASK, msk);
          CLRREG32(&pIntrRegs->INTMSK, 1 << IRQ_EINT8_23);
          return OAL_INTR_IRQ_UNDEFINED ;
        }           
        OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-BSPIntrEnableIrq(irq = %d)/r/n", irq));

        return irq;
    }

    一定要注意上面的那个粗体部份的返回值,这里是根据此函数的调用者OalIntrEnableIrqs()功能写的 :

    BOOL OALIntrEnableIrqs(UINT32 count, const UINT32 *pIrqs)
    {
        BOOL rc = TRUE;
        UINT32 i, mask, irq;

        OALMSG(OAL_INTR&&OAL_FUNC, (
            L"+OALIntrEnableIrqs(%d, 0x%08x)/r/n", count, pIrqs
        ));

        for (i = 0; i < count; i++) {
    #ifndef OAL_BSP_CALLBACKS
            irq = pIrqs[i];
    #else
            // Give BSP chance to enable irq on subordinate interrupt controller
            irq = BSPIntrEnableIrq(pIrqs[i]);
    #endif
            if (irq == OAL_INTR_IRQ_UNDEFINED) continue;
            // Depending on IRQ number use internal or external mask register
            if (irq <= IRQ_ADC) {
                // Use interrupt mask register
                CLRREG32(&g_pIntrRegs->INTMSK, 1 << irq);
            } else if (irq <= IRQ_EINT7) {
                // Use external mask register
                CLRREG32(&g_pIntrRegs->INTMSK, 1 << IRQ_EINT4_7);
                CLRREG32(&g_pPortRegs->EINTMASK, 1 << (irq - IRQ_EINT4 + 4));
            } else if (irq <= IRQ_EINT23) {
                // Use external mask register
                mask = 1 << (irq - IRQ_EINT4 + 4);
                OUTREG32(&g_pPortRegs->EINTPEND, mask);
                CLRREG32(&g_pPortRegs->EINTMASK, mask);
                mask = 1 << IRQ_EINT8_23;
                if ((INREG32(&g_pIntrRegs->INTPND) & mask) != 0) {
                    OUTREG32(&g_pIntrRegs->INTPND, mask);
                }
                CLRREG32( &g_pIntrRegs->INTMSK, 1 << IRQ_EINT8_23);
            } else {
                rc = FALSE;
            }
        }       

        OALMSG(OAL_INTR&&OAL_FUNC, (L"-OALIntrEnableIrqs(rc = %d)/r/n", rc));
        return rc;   
    }

  4. 上次留下的问题,关于cs8900能生成lib,而不是dll文件,解决办法是像4.2的增加cs8900r一样,以对nmake命令的支持。但是我没有用这个方法,因为太麻烦,有更简单的方法:在cs8900r目录中找到source文件,对其进行更改:
    PREPROCESSDEFFILE=1
    DEFFILE=cs8900.def
    TARGETDEFNAME=cs8900
    TARGETNAME=cs8900
    TARGETTYPE=DYNLINK
    RELEASETYPE=PLATFORM

    TARGETLIBS= /
    $(_COMMONSDKROOT)/lib/$(_CPUINDPATH)/coredll.lib /
    $(_COMMONSDKROOT)/lib/$(_CPUINDPATH)/ndis.lib /
    $(_COMMONOAKROOT)/lib/$(_CPUINDPATH)/ceddk.lib /

    SOURCELIBS= /
    $(_PROJECTROOT)/cesysgen/sdk/lib/armv4i/retail/ndis.lib /

    DLLENTRY=DllEntry

    像这样的source文件在每个需要编译的目录下都会有一个,是为了给make提供编译“内容”的,很重要。从它的一些关键字也可以看出大概意思,具体可以参改相关的文档,make这样的命令在linux下应用很广。
  5. NandFlash的移植
    我 发现在5.0自带的bsp中的nandflash不能正常运行,也可能是我没有花更多的时间去测试。nandflash的驱动在4.2是位于bsp中的 drivers目录内,由于nandflash的驱动是eboot与kernel共享的,所以在5.0下,此驱动被移动到了bsp/src/common /下面。我把4.2的驱动拷贝到了5.0的drivers目录下,更改drivers目录下的dirs文件,将nandflsh目录加入其内,使得在 drivers目录执行build命令时,编译器也会编译nandflsh目录下的文件。编译后发现不行,有好些语法错误,大概是volatile关键 字、还有两个重复定义的宏,排除后编译还是不行,查了下,是source文件也需要调整,注释掉不必要的预编译条件,就OK了。注意你的 nandflash驱动生成最终的dll文件名,因为在实现注册表永久保存时需要用到。
  6. 注册表永久保存
    对当前pb工程加入必要的catalog,如“基于永久保存的注册表” ,binfs文件系统的支持等,这个图是5.0实现永久保存:
     注册表
    然后就是对platform.reg进行修改,跟4.2下的差不多,贴上相关代码:

    ; HIVE BOOT SECTION
    [HKEY_LOCAL_MACHINE/Drivers/Resources/IRQ]
       "Identifier"=dword:1
       "Minimum"=dword:1
       "Space"=dword:20
       "Ranges"="1-0x20"
    ;  "Shared"=""

    [HKEY_LOCAL_MACHINE/Drivers/Resources/IO]
       "Identifier"=dword:2
       "Minimum"=dword:0
       "Space"=dword:10000
       "Ranges"="0-0xFFFF"
    ; END HIVE BOOT SECTION

    ; @CESYSGEN IF FILESYS_FSREGHIVE
    ; HIVE BOOT SECTION

    ; Valid Bits for Flags registry value
    ; If no flags are set, the hive will be stored in the object store.
    ;
    ; 0x00000001    Start storage manager in boot phase 1 for hive-based registry
    ; 0x00000002    Start device manager in boot phase 1 for hive-based registry
    ; 0x00000004    Start storage manager in boot phase 1 for registry in
    ;               external ROM (such as BINFS)
    ; 0x00000008    Start device manager in boot phase 1 for registry in
    ;               external ROM (such as BINFS)

    [HKEY_LOCAL_MACHINE/init/BootVars]
    ;   "SystemHive"="Documents and Settings//system.hv"
    ;   "ProfileDir"="Documents and Settings"
    ;   "Flags"=dword:3
        "SYSTEMHIVE"="system.hv"
        "Start DevMgr"=dword:1
        "RegistryFlags"=dword:1
        "Flags"=dword:1000
        "DefaultUser"="default"

    ; END HIVE BOOT SECTION
    ; @CESYSGEN ENDIF FILESYS_FSREGHIVE

    ; @CESYSGEN IF FILESYS_FSREGHIVE
    ; HIVE BOOT SECTION
    ;[HKEY_LOCAL_MACHINE/Drivers/BuiltIn/FlashDisk]
    ;    "Profile"="FlashDisk"
    ;    "IClass"=multi_sz:"{A4E7EDDA-E575-4252-9D6B-4195D48BB865}"
    ;    "Order"=dword:0
    ;    "FriendlyName"="xiaoyunsoft NAND Flash Driver"
    ;    "Dll"="flashdisk.dll"
    ;    "Prefix"="DSK"
    ;      "Ioctl"=dword:4
    ;     "MountFlags"=dword:11
    ;     "BootPhase"=dword:0
    ;     "Flags"=dword:1000

    [HKEY_LOCAL_MACHINE/System/StorageManager/PartitionTable]
        "21"="BINFS"

    [HKEY_LOCAL_MACHINE/System/StorageManager/BINFS]
        "Folder"="BINFS"
        "FriendlyName"="Bin FileSystem"
        "Dll"="binfs.dll"
        "MountFlags"=dword:11
        "BootPhase"=dword:0
        "Flags"=dword:1000

    [HKEY_LOCAL_MACHINE/System/StorageManager/AutoLoad/FlashDrv]
        "DriverPath"="Drivers//BlockDevice//FlashDrv"
        "LoadFlags"=dword:1
        "MountFlags"=dword:11
        "BootPhase"=dword:0
        "Flags"=dword:1000

    [HKEY_LOCAL_MACHINE/Drivers/BlockDevice/FlashDrv]
        "Prefix"="DSK"
        "Dll"="FlashDrv.dll"
        "Order"=dword:0
        "Ioctl"=dword:4
        "Profile"="FlashDrv"
        "FriendlyName"="MS Flash Driver"
        "MountFlags"=dword:11
        "BootPhase"=dword:0
        "Flags"=dword:1000

    [HKEY_LOCAL_MACHINE/System/StorageManager/Profiles/FlashDrv]
        "DefaultFileSystem"="BINFS"
        "PartitionDriver"="mspart.dll"
        "AutoMount"=dword:1
        "AutoPart"=dword:1
        "AutoFormat"=dword:1
        "Folder"="ResidentFlash"
        "Name"="xiaoyunsoft Flash Disk"
        "BootPhase"=dword:0
        "Flags"=dword:1000
        "MountHidden"=dword:0

    [HKEY_LOCAL_MACHINE/System/StorageManager/Profiles/FlashDrv/FATFS]
        "MountFlags"=dword:2
        "Flags"=dword:1000

    [HKEY_LOCAL_MACHINE/System/StorageManager/FATFS]
        "MountFlags"=dword:0
        "Flags"=dword:1000

    ; END HIVE BOOT SECTION

    IF BSP_NOETHER !
    IF SYSGEN_ETHERNET
    #include "$(_TARGETPLATROOT)/src/drivers/cs8900r/cs8900.reg"
    ENDIF
    ENDIF

    注意看最后几行,它跟永久保存注册表没有关系,只是通过#include来包函一个外部的cs8900相关的驱动。

  7. 关于将空闲flash做为分区。我觉得还是跟eboot有关系,我用的还是4.2下的eboot,里面有我增加的新建分区功能代码,而且在4.2也是可以正常工作的。主要还是对catalog的操作,具体也可以参照上面一张图示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值