It's done!

[不指定 2007/04/10 20:30 | by coldfly ]
今天终于把论文写完,整个研究过程应该告一段落了,得好好休息一下了,DotA!。
下面简单介绍一下吧,谢谢~
论文写了一万多字,就不全贴了,发个绪论先!
引用
基于RFID的嵌入式奥运信息平台
摘要
北京奥运信息平台由“主控中心计算机系统”和“嵌入式服务终端”两部分组成,各个“嵌入式服务终端”通过局域网与“主控中心”相连接。
“嵌入式服务终端”以三星ARM9 S3C2410嵌入式平台为载体,采用8寸大屏幕触摸屏作为人机交互平台。安全方面,运用RFID(无线射频识别)技术进行奥运村人员识别并分类管理;信息查询方面,使用迪杰斯特拉算法根据道路繁忙情况给出最短路径;环境管理方面,工作人员可以通过下挂的单片机系统对外围环境硬件进行控制。
“主控中心计算机系统”为整个系统的服务核心。人员管理方面,采用分级数据库进行管理,采用HSV(色彩空间变换)及边缘检测算法对远程“嵌入式终端”的登陆人员进行人脸识别,并采用DirectX 8.0进行硬件驱动实现了摄像头采集影像的实时处理;安全方面,“主控中心”可实时管理所有嵌入式终端并且提供详细的日志记录。
关键字:嵌入式,ARM9,RFID,DirectX,人脸识别,HSV变换,Robert边缘检测,迪杰斯特拉算法,数据库
绪论
1.1、奥运信息平台
从1948年伦敦奥运会到2004年雅典奥运会,参赛的运动员及国家和地区由4062人、58个国家和地区增加到11099人、202个国家和地区(Wikipedia统计)。
但目前运动员、代表团、记者及游客要了解赛事安排及进展,主要依靠组委会新闻中心发布后各种媒介的传播,以致信息不能随时随地获得。
要参观景点则主要依靠人工询问、导游及地图。由于他们来自不同的国家(包括大量小语种国家),语言不同,交流困难;加上普通印刷地图的语言标识受版面限制,不超过两种语言,不便于他们浏览阅读,从而导致他们对奥运信息的了解颇为欠缺。
针对此类问题,我们可以在奥运村及主要路口建设信息亭提供触摸屏上网信息查询。目前北京市内已经有一些“数字北京信息亭”,该数字信息亭仅仅提供普通的信息查询,地图查询功能,不能对不同的用户群提供个性化的查询服务。因此,针对这个问题我们提出了我们的“嵌入式奥运服务终端”。
在某个固定区域的设置一台“主控中心计算机”,该计算机上使用分级数据库存储所有用户的资料,并且可以对该区域内所有“嵌入式奥运服务终端”进行控制。“嵌入式奥运服务终端”通过局域网与“主控中心计算机”连接,根据用户需求发送不同的查询请求并将查询结果反馈显示给用户。对于不同的用户,“嵌入式终端”会以不同的界面显示,比如:观众、志愿者、管理员;对于不同国家的用户,“嵌入式终端”也能提供不同的语言支持。
由于采用了ARM9 S3C2410处理器的嵌入式处理器,该套系统比起传统的基于PC机的查询终端成本大大降低,更加适合大范围推广。另外,专一任务的嵌入式系统比起PC系统更加稳定,功耗更小。
点击在新窗口中浏览此图片
1.2、RFID(无线射频识别)人员识别
奥运会是一个作为四年一届的体育盛会,将会有大量人员参与其中,本届奥运会预计游客将超过百万人。如何对这些人员进行有效管理,将是北京奥运安全管理的一个重要问题。
这几年RFID技术逐渐发展成熟,开始向各个行业大举进军,在了解了奥运会人员管理的现状后,基于这种动态、高效和数字化的管理手段将极大方便整个奥运会的安全管理。
在每个“嵌入式终端”上,将附加一个RFID读卡器,这使得“嵌入式终端”能够实时监控周围一定范围内的所有人员,并且能够将这些人员信息发送“主控中心计算机”及时分析处理,主控中心能够实时监视所有嵌入式终端周围的人员动态,据此可以分析实现一套行之有效的安全管理方案。
点击在新窗口中浏览此图片
1.3、基于DirectX的人脸识别
“科技奥运”提供给人们的是人性化的服务,在我们这套系统中,加入了人脸识别系统,这不仅在人员登陆方面提供了一定的智能化的便捷,更重要的是在安全方面给管理人员提供了极大的参考资料。
在每个“嵌入式终端”上都安装有一个摄像头,每当用户持RFID卡靠近终端并选择要登陆的用户名时,系统会自动调出该人员数据库中的登记照片,并对摄像头拍摄到的图片进行分析处理,将人脸分离、对比,如果相似度达到某个值,则系统自动为之登陆,如果长时间系统无法识别该人信息,该人员则只能通过自己设定的密码登陆系统进行查询。
DirectX技术的使用使得快速处理海量的图像信息成为可能,这样用户只需要在摄像头前一晃而过,系统就能够完成所有的识别计算并且将其间最大的相似度作为最终的对比结果。
1.4、地图查询
北京的交通一直以来是人们出行的大问题。2008年奥运会在北京举行时,世界各国的人们都聚集到了首都,特别是在各个比赛场馆附近,人员的高度集中使得交通问题更加突出。而在我们设在奥运村和各个路口的“嵌入式奥运服务终端”下挂的RFID系统则可以承担流动人员的信息采集,最终“嵌入式终端”将所有信息汇总到“主控中心计算机”由主控中心综合分析处理。
传统的地图查询仅仅根据预先设定的查询算法进行单一的地图查询,由于“嵌入式终端”与“主控中心计算机”有着密切的联系,主控中心可以随时根据“嵌入式终端”反馈回来的路况信息设定道路的繁忙程度,并且采用迪杰斯特拉算法根据道路繁忙情况给出最优路径,这样有效避免车辆人员拥堵,实现道路的优化使用。
再补上一些项目的照片。
点击在新窗口中浏览此图片
嵌入式终端
点击在新窗口中浏览此图片
奥运村模型
点击在新窗口中浏览此图片
主控中心软件
点击在新窗口中浏览此图片
嵌入式终端软件
KO!
Tags: , ,

S3C2410的BSP添加串口支持

[不指定 2007/03/01 14:33 | by coldfly ]
最近在调优龙ST2410的板子,总体来说,优龙的板子做的不错,技术支持也还可以,至少比广州斯道好~
不过呢,优龙提供的WinCE BSP也只是在三星的公版BSP上少量修改而成的,虽然三星S3C2410能够提供3个UART支持,也就是说每个UART控制器都可以工作在Interrupt(中断)模式或DMA(直接内存访问)模式,但是三星提供的公版BSP上只添加了UART0(COM1)和UART2(红外)的支持,所以优龙提供的BSP也就只有一个串口能用,另外一个红外我也不知道怎么用(没有红外设备测试)。
这样的话,我买的板子上面的两个串口岂不是浪费了一个,这可不行,因为COM1是默认作为调试串口了,系统的启动信息都是靠这个串口输出的,总不能调试和使用共用一个吧!
优龙官方论坛寻觅未果,他们好像就没做UART1的BSP支持,这样,只好自己动手,丰衣足食了。
还好,虽然广州斯道的技术支持差,但我有他们公司内部测试的BSP,这个BSP是支持两个串口的,有了这个参照,修改起来就方便多了~
我的平台是WinCE 5.0和Platform Builder 5.0,虽然手头的资料都是WinCE 4.2的,但根据修改比较,好像没有区别,不知道WinCE 5.0到底升级了什么question
首先列举一下要修改文件的清单:
SMDK2410\FILES\platform.reg
SMDK2410\INC\oalintr.h
SMDK2410\DRIVERS\SERIAL\ser2410_hw.c
SMDK2410\DRIVERS\SERIAL\ser2410_ser.c
SMDK2410\KERNEL\HAL\cfw.c
SMDK2410\KERNEL\HAL\ARM\armint.c
SMDK2410\smdk2410.cec

好了,Let's gooooooooo~
1、打开platform.reg文件,这个是WinCE注册表文件,在这里,我们要修改并添加串口。
搜索:[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\SER2410],这就是串口1。
将其下面的键值改为:
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\SER2410]
  "DeviceArrayIndex"=dword:0
  "Irq"=dword:13
  "IoBase"=dword:50000000
  "IoLen"=dword:2C
  "Prefix"="COM"
  "Dll"="SER2410.Dll"
  "Order"=dword:0
  "Priority"=dword:0
  "Port"="COM1:"
  "DeviceType"=dword:0
  "FriendlyName"="Serial Cable on COM1:"
  "Tsp"="Unimodem.dll"
  "DevConfig"=hex: 10,00, 00,00, 05,00,00,00, 10,01,00,00, 00,4B,00,00, 00,00, 08, 00, 00, 00,00,00,00
再在其后面添加串口2:
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\SER2410_2]
  "DeviceArrayIndex"=dword:1
  "Irq"=dword:23
  "IoBase"=dword:50004000
  "IoLen"=dword:2C
  "Prefix"="COM"
  "Dll"="SER2410.Dll"
  "Order"=dword:1
  "Priority"=dword:0
  "Port"="COM2:"
  "DeviceType"=dword:0
  "FriendlyName"="Serial Cable on COM2:"
  "Tsp"="Unimodem.dll"
  "DevConfig"=hex: 10,00, 00,00, 05,00,00,00, 10,01,00,00, 00,4B,00,00, 00,00, 08, 00, 00, 00,00,00,00

[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\SER2410_2\Unimodem]
  "Tsp"="Unimodem.dll"
  "DeviceType"=dword:0
  "FriendlyName"="SER2410_2 UNIMODEM"
  "DevConfig"=hex: 10,00, 00,00, 05,00,00,00, 10,01,00,00, 00,4B,00,00, 00,00, 08, 00, 00, 00,00,00,00
再搜索:[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\IRDA2410],这个是红外,也要修改下:
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\IRDA2410]
  "DeviceArrayIndex"=dword:2
  "Irq"=dword:19
  "IoBase"=dword:50008000
  "IoLen"=dword:2C
  "Prefix"="COM"
  "Dll"="IRDA2410.Dll"
  "Order"=dword:0
  "Priority"=dword:0
  "Port"="COM3:"
  "DeviceType"=dword:0  ; IRDA modem, 0 -> null modem
  "FriendlyName"="S2410 IRDA2410"
  "Index"=dword:2
  "IClass"="{A32942B7-920C-486b-B0E6-92A702A99B35}"
好了,注册表就改到这里,以上要特别注意Irq的值,要和oalintr.h里面的中断定义对应,并且注意Order的顺序,DeviceArrayIndex的值以及IoBase,后面串口源代码中要用到该值作判断。
2、打开oalintr.h文件,我们添加一个新的串口,并定义中断号。
添加:
#define SYSINTR_SERIAL1  (SYSINTR_FIRMWARE+19)
这里,我们可以看到SYSINTR_SERIAL1定义到16+19=35=0x23,与注册表中一致。
然后修改下这个地方:
MapIrq2SysIntr(DWORD _Irq)
{
   if( _Irq<=19 )
       return ( SYSINTR_FIRMWARE + _Irq );
   else
       return (0xffffffff);
}
3、打开串口源文件中ser2410_hw.c文件。
搜索:
S2410_SetSerialIOP(
      PVOID   pHead // @parm points to device head
      )
将其函数改为:
{
 PS2410_UART_INFO   pHWHead   = (PS2410_UART_INFO)pHead;
 PSER_INFO     pHWHead1  = (PSER_INFO)pHead;

 RETAILMSG(DEBUGMODE, (TEXT("S2410_SetSerialIOP \r\n")));
 if(pHWHead1->dwIOBase == 0x50004000)
 {
 #if USEVIRTUAL
   EnterCriticalSection(&(pHWHead->RegCritSec));
   v_pIOPregs->rGPHCON &= ~(0x3<<8 | 0x3<<10 /*| 0x3<<12 | 0x3<<14*/); // clear uart 1 - rx, tx
   v_pIOPregs->rGPHCON |= (0x2<<8 | 0x2<<10 /*| 0x1<<12 | 0x0<<14*/);
   v_pIOPregs->rGPHCON |= (0x2<<0 | 0x2<<2 );
   v_pIOPregs->rGPHUP  |= 0x03;
   pHWHead->rDTRport = (volatile unsigned int *)&(v_pIOPregs->rGPHDAT);
   pHWHead->rDSRport = (volatile unsigned int *)&(v_pIOPregs->rGPHDAT);
   pHWHead->DtrPortNum = 0;
   pHWHead->DsrPortNum = 1;
 #else
   volatile IOPreg *s2410IOP;
   s2410IOP   = (volatile IOPreg *)IOP_BASE;
 
   EnterCriticalSection(&(pHWHead->RegCritSec));
   s2410IOP->rGPHCON &= ~(0x3<<8 | 0x3<<10/* | 0x3<<12 | 0x3<<14*/); // clear uart 1 - rx, tx
   s2410IOP->rGPHCON |= (0x2<<8 | 0x2<<10 /*| 0x1<<12 | 0x0<<14*/);
   s2410IOP->rGPHCON |= (0x2<<0 | 0x2<<2 );
   s2410IOP->rGPHUP  |= 0x03;
   pHWHead->rDTRport = (volatile unsigned int *)(IOP_BASE+0x74); //s2410IOP->rGPHDAT
   pHWHead->rDSRport = (volatile unsigned int *)(IOP_BASE+0x74);
   pHWHead->DtrPortNum = 0;
   pHWHead->DsrPortNum = 1;
 #endif
 }
 else if(pHWHead1->dwIOBase == 0x50008000)
 {
 #if USEVIRTUAL
   EnterCriticalSection(&(pHWHead->RegCritSec));
   v_pIOPregs->rGPHCON &= ~( 0x3<<12 | 0x3<<14); // clear uart 2 - rx, tx
   v_pIOPregs->rGPHCON |= ( 0x2<<12 | 0x2<<14);
   v_pIOPregs->rGPHCON |= (0x2<<0 | 0x2<<2 );
   v_pIOPregs->rGPHUP  &= ~0xc0;
   pHWHead->rDTRport = (volatile unsigned int *)&(v_pIOPregs->rGPHDAT);
   pHWHead->rDSRport = (volatile unsigned int *)&(v_pIOPregs->rGPHDAT);
   pHWHead->DtrPortNum = 0;
   pHWHead->DsrPortNum = 1;
 #else
   volatile IOPreg *s2410IOP;
   s2410IOP   = (volatile IOPreg *)IOP_BASE;
 
   EnterCriticalSection(&(pHWHead->RegCritSec));
   s2410IOP->rGPHCON &= ~(0x3<<12 | 0x3<<14); // clear uart 2 - rx, tx
   s2410IOP->rGPHCON |= ( 0x02<<12 | 0x02<<14);
   s2410IOP->rGPHCON |= (0x2<<0 | 0x2<<2 );
   s2410IOP->rGPHUP  &= ~0xc0;
   pHWHead->rDTRport = (volatile unsigned int *)(IOP_BASE+0x74); //s2410IOP->rGPHDAT
   pHWHead->rDSRport = (volatile unsigned int *)(IOP_BASE+0x74);
   pHWHead->DtrPortNum = 0;
   pHWHead->DsrPortNum = 1;
 #endif    
 }
 else
 {
 #if USEVIRTUAL
   EnterCriticalSection(&(pHWHead->RegCritSec));
   v_pIOPregs->rGPHCON &= ~(0x3<<0 | 0x3<<2 | 0x3<<4 | 0x3<<6/* | 0x3<<12 | 0x3<<14*/); // clear uart 0 - rx, tx
   v_pIOPregs->rGPHCON |= (0x2<<4 | 0x2<<6/* | 0x1<<12 | 0x0<<14*/);
   v_pIOPregs->rGPHCON |= (0x2<<0 | 0x2<<2 );
   v_pIOPregs->rGPHUP  |= 0x03;
   pHWHead->rDTRport = (volatile unsigned int *)&(v_pIOPregs->rGPHDAT);
   pHWHead->rDSRport = (volatile unsigned int *)&(v_pIOPregs->rGPHDAT);
   pHWHead->DtrPortNum = 0;
   pHWHead->DsrPortNum = 1;
 #else
   volatile IOPreg *s2410IOP;
   s2410IOP   = (volatile IOPreg *)IOP_BASE;
 
   EnterCriticalSection(&(pHWHead->RegCritSec));
   s2410IOP->rGPHCON &= ~(0x3<<0 | 0x3<<2 | 0x3<<4 | 0x3<<6 /*| 0x3<<12 | 0x3<<14*/); // clear uart 0 - rx, tx
   s2410IOP->rGPHCON |= (0x2<<4 | 0x2<<6 /*| 0x1<<12 | 0x0<<14*/);
   s2410IOP->rGPHCON |= (0x2<<0 | 0x2<<2 );
   s2410IOP->rGPHUP  |= 0x03;
   pHWHead->rDTRport = (volatile unsigned int *)(IOP_BASE+0x74); //s2410IOP->rGPHDAT
   pHWHead->rDSRport = (volatile unsigned int *)(IOP_BASE+0x74);
   pHWHead->DtrPortNum = 0;
   pHWHead->DsrPortNum =1;
 #endif
 }
 LeaveCriticalSection(&(pHWHead->RegCritSec));
}
接着搜索:
SL_Init(
      PVOID   pHead, // @parm points to device head
      PUCHAR  pRegBase, // Pointer to 16550 register base
      UINT8   RegStride, // Stride amongst the 16550 registers
      EVENT_FUNC EventCallback, // This callback exists in MDD
      PVOID   pMddHead,   // This is the first parm to callback
      PLOOKUP_TBL   pBaudTable  // BaudRate Table
      )
在PS2410_UART_INFO   pHWHead   = (PS2410_UART_INFO)pHead;这一句后面添加:
PSER_INFO     pHWHead1  = (PSER_INFO)pHead;
再搜索:
 if ( pHWHead->UseIrDA )
 {
   pHWHead->bINT = BIT_UART2;
   pHWHead->bTxINT = INTSUB_TXD2;
   pHWHead->bRxINT = INTSUB_RXD2;
   pHWHead->bErrINT = INTSUB_ERR2;
#if USEVIRTUAL
   pHWHead->s2410SerReg = (S2410_UART_REG *)v_pUART2regs;
   pRegBase = (PUCHAR)pHWHead->s2410SerReg;
#else    
   pRegBase = (PUCHAR)UART2_BASE;
   pHWHead->s2410SerReg = (S2410_UART_REG *)pRegBase;
#endif
 }
 else
 {
 把这其中的代码修改为以下代码
 }
   if(pHWHead1->dwIOBase == 0x50004000)
   {
     pHWHead->bINT = BIT_UART1;
     pHWHead->bTxINT = INTSUB_TXD1;
     pHWHead->bRxINT = INTSUB_RXD1;
     pHWHead->bErrINT = INTSUB_ERR1;
   #if USEVIRTUAL
     pHWHead->s2410SerReg = (S2410_UART_REG *)v_pUART1regs;
     pRegBase = (PUCHAR)pHWHead->s2410SerReg;
   #else    
     pRegBase = (PUCHAR)UART1_BASE;
     pHWHead->s2410SerReg = (S2410_UART_REG *)pRegBase;
   #endif
     
   }
   else if(pHWHead1->dwIOBase == 0x50008000)
   {
     pHWHead->bINT = BIT_UART2;
     pHWHead->bTxINT = INTSUB_TXD2;
     pHWHead->bRxINT = INTSUB_RXD2;
     pHWHead->bErrINT = INTSUB_ERR2;
   #if USEVIRTUAL
     pHWHead->s2410SerReg = (S2410_UART_REG *)v_pUART2regs;
     pRegBase = (PUCHAR)pHWHead->s2410SerReg;
   #else    
     pRegBase = (PUCHAR)UART2_BASE;
     pHWHead->s2410SerReg = (S2410_UART_REG *)pRegBase;
   #endif
   }
   else
   {
     
     pHWHead->bINT = BIT_UART0;
     pHWHead->bTxINT = INTSUB_TXD0;
     pHWHead->bRxINT = INTSUB_RXD0;
     pHWHead->bErrINT = INTSUB_ERR0;
   #if USEVIRTUAL
     pHWHead->s2410SerReg = (S2410_UART_REG *)v_pUART0regs;
     pRegBase = (PUCHAR)pHWHead->s2410SerReg;
   #else    
     pRegBase = (PUCHAR)UART0_BASE;
     pHWHead->s2410SerReg = (S2410_UART_REG *)pRegBase;
   #endif
   }
再搜索:
 if ( pHWHead->UseIrDA )
 {
   pHWHead->pUFTXH = (volatile unsigned char *)&(v_pUART2regs->rUTXH);
   pHWHead->pUFRXH = (volatile unsigned char *)&(v_pUART2regs->rURXH);    
 }
 else
 {
 把这其中的代码修改为以下代码
 }
   if(pHWHead1->dwIOBase == 0x50004000)
   {
     pHWHead->pUFTXH = (volatile unsigned char *)&(v_pUART1regs->rUTXH);
     pHWHead->pUFRXH = (volatile unsigned char *)&(v_pUART1regs->rURXH);
   }
   else if(pHWHead1->dwIOBase == 0x50008000)
   {
     pHWHead->pUFTXH = (volatile unsigned char *)&(v_pUART2regs->rUTXH);
     pHWHead->pUFRXH = (volatile unsigned char *)&(v_pUART2regs->rURXH);      
   }
   else
   {
     pHWHead->pUFTXH = (volatile unsigned char *)&(v_pUART0regs->rUTXH);
     pHWHead->pUFRXH = (volatile unsigned char *)&(v_pUART0regs->rURXH);    
   }
4、打开ser2410_ser.c文件。
搜索:
const HWOBJ IoObj = {
 THREAD_AT_INIT,
 SYSINTR_SERIAL,
 (PHW_VTBL) &IoVTbl
};
在其后面添加:
const HWOBJ Io1Obj = {
 THREAD_AT_INIT,
 SYSINTR_SERIAL1,
 (PHW_VTBL) &IoVTbl
};

const HWOBJ Io2Obj = {
 THREAD_AT_INIT,
 SYSINTR_IR,
 (PHW_VTBL) &IoVTbl
};
接着搜索:
const PCHWOBJ HWObjects[] = {
 &IoObj,
 &IrObj
};
将其修改为:
const PCHWOBJ HWObjects[] = {
 &IoObj,
 &Io1Obj,
 &Io2Obj
};
再搜索:
GetSerialObject(
              DWORD DeviceArrayIndex
              )
将其函数改为:
{
 PHWOBJ pSerObj;

 DEBUGMSG(DEBUGMODE,(TEXT("GetSerialObject : DeviceArrayIndex = %d\r\n"), DeviceArrayIndex));

 // Now return this structure to the MDD.
 if ( DeviceArrayIndex == 2 )
 {  
   RETAILMSG(1,(TEXT("GetSerialObject Io2Obj\r\n")));
   pSerObj = (PHWOBJ)(&Io2Obj);
 }
 else if(DeviceArrayIndex == 1)
   pSerObj = (PHWOBJ)(&Io1Obj);
 else
   pSerObj = (PHWOBJ)(&IoObj);

 return (pSerObj);
}
5、打开cfw.c文件,这就是中断处理。
搜索:
BOOL
OEMInterruptEnable(DWORD  idInt,  // @parm Interrupt ID to be enabled. See <l Interrupt ID's.Interrupt ID's>  for a list of possble values.
          LPVOID pvData,  // @parm ptr to data passed in in the <f InterruptInitialize> call
              DWORD  cbData)  // @parm Size of data pointed to be <p pvData>
找到这一句:case SYSINTR_SERIAL:
在其后面添加:
 case SYSINTR_SERIAL1:  // Serial port1.
   s2410INT->rSUBSRCPND  = (INTSUB_RXD1 | INTSUB_TXD1 | INTSUB_ERR1);
   s2410INT->rINTSUBMSK &= ~INTSUB_RXD1;
   s2410INT->rINTSUBMSK &= ~INTSUB_TXD1;
   s2410INT->rINTSUBMSK &= ~INTSUB_ERR1;
   s2410INT->rSRCPND     = BIT_UART1;
   // S3C2410X Developer Notice (page 4) warns against writing a 1 to a 0 bit in the INTPND register.
   if (s2410INT->rINTPND & BIT_UART1) s2410INT->rINTPND = BIT_UART1;
   s2410INT->rINTMSK    &= ~BIT_UART1;
   break;
搜索:
void
OEMInterruptDisable(DWORD idInt)  // @parm Interrupt ID to be disabled. See <t Interrupt ID's>
还是这一句:case SYSINTR_SERIAL:
在其后面添加:
 case SYSINTR_SERIAL1:
   s2410INT->rINTMSK    |= BIT_UART1;
   s2410INT->rINTSUBMSK |= INTSUB_RXD1;
   s2410INT->rINTSUBMSK |= INTSUB_TXD1;
   s2410INT->rINTSUBMSK |= INTSUB_ERR1;
   break;
搜索:
void
OEMInterruptDone(DWORD idInt)  // @parm Interrupt ID. See <t Interrupt ID's>
依旧找到case SYSINTR_SERIAL:
在其后面添加:
 case SYSINTR_SERIAL1:
   s2410INT->rINTMSK    &= ~BIT_UART1;
   s2410INT->rINTSUBMSK &= ~INTSUB_RXD1;
   break;
6、打开armint.c文件。
搜索:else if(IntPendVal == INTSRC_UART0)
在其后面添加:
 else if(IntPendVal == INTSRC_UART1)
 {
   SubIntPendVal = s2410INT->rSUBSRCPND;

   // Note that we only mask the sub source interrupt - the serial driver will clear the
   // sub source pending register.
   //
   if(SubIntPendVal & INTSUB_ERR1)
   {
     s2410INT->rINTSUBMSK |= INTSUB_ERR1;
   }
   else if(SubIntPendVal & INTSUB_RXD1)
   {
     s2410INT->rINTSUBMSK |= INTSUB_RXD1;
   }
   else if(SubIntPendVal & INTSUB_TXD1)
   {
     s2410INT->rINTSUBMSK |= INTSUB_TXD1;
   }
   else
   {
     return(SYSINTR_NOP);
   }
 
   // NOTE: Don't clear INTSRC:UART1 here - serial driver does that.
   //
   s2410INT->rINTMSK |= BIT_UART1;
   if (s2410INT->rINTPND & BIT_UART1) s2410INT->rINTPND  = BIT_UART1;

   return(SYSINTR_SERIAL1);
   
 }
7、打开smdk2410.cec文件,添加UART1这个feature。
搜索
ComponentType
(
 Name ( "Serial" )
 GUID ( {6563AD6C-E71C-11D4-B892-0050FC049781} )
 MaxResolvedImpsAllowed( 999 )
 Implementations
 (
   Implementation
   (
     Name ( "S32410 Serial UART" )
在其后面添加:
   Implementation  
   (
     Name ( "S32410 Serial UART1" )
     GUID ( {7C4427A5-286C-4C7A-B687-4E3B364D079B} )
     Description ( "Samsung S32410 serial UART controller." )
     BSPPlatformDir ( "smdk2410" )
     Version ( "5.0.0.0" )
     Locale ( 0409 )
     Vendor ( "Microsoft" )
     Date ( "2003-1-13" )
     SizeIsCPUDependent( 1 )
     BuildMethods
     (
       BuildMethod
       (
         GUID ( {07DA2083-6261-4ED6-B5BB-70CF4D930D68} )
         Step ( BSP )
         CPU ( "ARMV4" )
         CPU ( "ARMV4I" )
         Action ( '#BUILD(SOURCES,"$(_WINCEROOT)\PLATFORM\SMDK2410\drivers\serial")')
        )
     )
   )
我感觉这个改不改没什么关系,反正网上有人这样改了,我也就改了,但是实际内核定制时中并没有添加上这个feature。

到这里,整个过程就结束了,耗费了我整整一天!其实改动量并不大,但是调试一次光编译就要15分钟,还要下载,烧写,启动~唉,没有仿真器就是麻烦。调了好多次没有成功,就是在注册表的中断号那儿出了问题,但没事!
Tags: , , , , ,

又是几个牛气冲天的Demo

[不指定 2007/02/26 13:02 | by coldfly ]
接着在硬盘里面淘宝,又有新发现grin
2000年底的时候,德国的the produkkt小组发布了一款大小仅仅为63.5KB的视频Demo,该Demo画质在当时来说算是极佳了,并且长达10分钟的3D动画加上音乐仅仅需要63.5KB的硬盘空间,这不得不让人折服,当时有评论说,这个Demo的诞生,是不是意味着我们又可以回到用软盘玩游戏的时代?注意,是3D游戏!
这就是在硬盘里找到的fr-08:.the .product
接下来,我顺藤摸瓜,又在他们的网站有了新的发现:
一年半之后,fr-019:poemtoahorse,使用了他们新一代的开发工具.werkkzeug1
又是一年之后,fr-030:candytron,又是新的开发工具.werkkzeug3
所有这些,大小都在64KB以内,再仔细看看,仔细听听,画质音质是不是不断提高?
接下来又是一系列的Demo发布,到了2004年,终于重量级的产品出现了,我们的愿望实现了:kkrieger!3D游戏!只有96KB,操作跟CS一样,但画质超过CS,但不要忘了,CS可是将近1G啊~
点击在新窗口中浏览此图片
kkrieger游戏截图
虽然kkrieger只有96KB,但要想运行游戏,硬件要求却很高,以下是具体的配置要求:
·P3 1.5GHz/Athlon以上CPU
·512M以上内存
·支持Pixel Shader 1.3以上特效,拥有128MB以上显存的显卡,即至少为Geforce4 Ti或者ATI Radeon8500以上显卡
·声卡支持
·Windows Me/2000/XP+DirectX 9.0b

我承认我现在的笔记本跑这个游戏还是有点卡,估计是显存没有到128M吧,有兴趣的同学可以试试~
在进入游戏后,按Enter进入游戏菜单,ESC返回菜单,游戏的操作比较简单,WASD是方向,鼠标左键射击,Space是跳,数字键是换枪,和CS一模一样。
在这个硬盘空间并不紧缺的今天,严谨的德国人们还能够孜孜不倦地秉承初衷,一直坚持把这个项目开发下来,终于,他们完成了当时的设想,的确,我们能够回到软盘玩游戏的时代~
更可贵的是,他们还公开了这所有Demo的开发工具.werkkzeug1,大家都可以制作自己的Demo了~
想要知道更详细的介绍吗?他们的产品网站:http://www.theproduct.de/
Tags: ,

牛气冲天的程序

[不指定 2007/02/26 01:33 | by coldfly ]
今天不慎在电脑硬盘里发现了这个好早以前的号称史上最强的程序,一时还没想起来怎么运行,经过实验,原来是这样的:
这个程序并不是一般的可执行的exe程序,而是一大串代码,需要调用DOS里面的Debug命令编译。
方法一:
1、将这个txt文件打开后把里面所有的内容复制,然后点击Windows的开始-运行,输入“command”,进入命令提示符(或者点击开始-所有程序-附件-命令提示符)。
2、在DOS的光标处输入“debug”,就进入了debug状态。
3、在这个DOS窗口的左上角图标处鼠标点击一下,出现一个菜单,选择编辑-粘贴,这样就可以把刚刚复制的内容一行一行粘进去,然后程序就运行了。
方法二:
1、把这个txt文件保存到某个盘下面,例如:D:\1.txt,然后同样进入命令提示符。
2、在命令提示符中输入“D:”,这样就进入了D盘的根目录,接下来,输入“debug <1.txt”,接下来,程序也运行了。
推荐使用第二种方法,反正我的电脑在粘贴那一大串代码时很慢。

友情提示:该程序是一段带音乐的3D动画,在运行时可以按ESC退出,另外,按Alt+Enter键可以从DOS的全屏状态切换回窗口状态。
Tags:

EVC 4.0的一些入门基础

[不指定 2007/02/25 01:29 | by coldfly ]
EVC(Embedded Visual C++)是微软公司推出的针对Windows CE嵌入式系统的应用程序开发工具,目前版本发展到EVC 4.0 SP4,支持到WinCE 5.0版本。
EVC 4.0具有如下特点:
1、网上资料少,但是可以通过VC++移植。
2、编程复杂,继承了VC++的光荣传统。
3、调试困难,模拟器支持差,微软的一贯作风。
基于不完全统计的以上几点,微软在放弃了EVB(Embedded Visual Basic) 4.0后,决定再放弃EVC的后续版本开发,所有的嵌入式开发将整合到Visual Studio 2005 .NET中,完成历史性的统一。
虽然如此,鉴于现在.NET 2.0平台的如此不完善(连WinCE 5.0还只附带.NET Compact Framework 1.0,没比WinCE 4.2进步多少,在Platform Builder中加入.NET 2.0后系统居然无法启动),使用VS 2005 .NET(主打.NET 2.0)开发程序还是较为困难,只好忍痛放弃VS .NET,投奔到EVC的怀抱。
初学EVC,在反复的尝试之后,总结出一点点心得:
首先,我们新建一个工程,注意在CPUs的选择上,除了把要用的CPU钩选上,别忘了钩选emulator,在本机模拟器(WinCE 5.0WinCE 4.2)调试时要用到它。
点击在新窗口中浏览此图片

下一步,确定MFC是共享DLL还是静态链接库,如果WinCE的镜像不带MFC,那么这里必须设置成静态的,不过最好还是在Platform Builder把WinCE的镜像中加上MFC这个feature,静态的总是不好,这个设置可以在Project Settings里面改。
点击在新窗口中浏览此图片

然后就一路Next,都完成后,进入了EVC的编辑界面。首先,我们要让程序支持中文。在VC++中,可以直接在向导中选择中文,可是EVC就比较扯淡,只能在这里重新设置一遍。
点击在新窗口中浏览此图片

还有这里,所有的窗体都要设置成Chinese(P.R.C)。
点击在新窗口中浏览此图片

如果程序用到了外部的链接,需要在这里设置,并且要万分注意的是,对于每个编译项目这些设置都是独立的,所以每一个编译平台(例如Debug,Release)都要重新做这些设置(包括语言设置)。
点击在新窗口中浏览此图片

基本设置完成之后,就可以开始像VC++一样编程了。
如果我是从网上下载的程序,在开始向导时没有钩选我用的CPU怎么办呢?
比如这个程序,它只钩选了ARMV4和emulator,于是在WinCE 4.2下的SDK中,有如下四个平台:
点击在新窗口中浏览此图片

但是当我把环境改成WinCE 5.0时,会发现ARMV4的两项没了,这是因为WinCE 5.0只支持ARMV4I。
点击在新窗口中浏览此图片

这样我们就要手动添加ARMV4I到程序编译环境中。在Build的Configurations中选择Add。
点击在新窗口中浏览此图片

然后手动把ARMV4I的Debug和Release都添加进去。
点击在新窗口中浏览此图片

注意在这个Copy settings from中,不要选择Default Configurations,不然会有我也无法解释的错误。
点击在新窗口中浏览此图片

这样,就可以在编译平台中看到新的CPU了。
点击在新窗口中浏览此图片

不过还没完,因为我们是拷贝的别的平台的设置,所以新的平台编译肯定是会有问题的,果然,问题出来了:
引用
--------------------Configuration: PocketLian - Win32 (WCE ARMV4I) Debug--------------------
Compiling resources...
Compiling...
Command line warning D4002 : ignoring unknown option '/Gs8192'
StdAfx.cpp
Compiling...
Command line warning D4002 : ignoring unknown option '/Gs8192'
PocketLian.cpp
PocketLianDlg.cpp
Generating Code...
Linking...
.\ARMV4IDbg\PocketLian.obj : fatal error LNK1112: module machine type 'ARM' conflicts with target machine type 'X86'
Error executing link.exe.

PocketLian.exe - 1 error(s), 2 warning(s)
根据错误提示,我们找到设置中的Link,把这个conflict的machine改成ARM。
点击在新窗口中浏览此图片

再次编译,还是有问题:
引用
--------------------Configuration: PocketLian - Win32 (WCE ARMV4I) Debug--------------------
Compiling resources...
Compiling...
Command line warning D4002 : ignoring unknown option '/Gs8192'
StdAfx.cpp
Compiling...
Command line warning D4002 : ignoring unknown option '/Gs8192'
PocketLian.cpp
PocketLianDlg.cpp
Generating Code...
Linking...
MFCCE400d.lib(mfcce400d.dll) : fatal error LNK1112: module machine type 'THUMB' conflicts with target machine type 'ARM'
Error executing link.exe.

PocketLian.exe - 1 error(s), 2 warning(s)
有完没完!kill只好再改一次。
点击在新窗口中浏览此图片

这一次就好了,同样地,你需要把每一个平台的设置都给改了,这个Release就成功了:
引用
--------------------Configuration: PocketLian - Win32 (WCE ARMV4I) Release--------------------
Compiling resources...
Compiling...
Command line warning D4002 : ignoring unknown option '/Gs8192'
StdAfx.cpp
Compiling...
Command line warning D4002 : ignoring unknown option '/Gs8192'
PocketLian.cpp
PocketLianDlg.cpp
Generating Code...
Linking...

PocketLian.exe - 0 error(s), 2 warning(s)
Downloading files
这样,别人的劳动果实就可以在自己的板子上跑起来了。
分页: 1/2 第一页 1 2 下页 最后页 [ 显示模式: 摘要 | 列表 ]