您的位置:首页 > 其它

wince 5.0 .2440 5.0BSP的中断过程(转)

2010-05-05 11:17 567 查看
以前在CSDN写过一些wince5.0中断的文章,现在重新看看,发现以前的有些理解是错误的,想翻开来改改,可是郁闷的CSDN在前台没有返回后台的编辑功能,所以现在重新写一篇纠正一下。

首先描述wince5.0 (2440BSP)的中断流程

注册表等——》KernelIoControl(——》OEMIoControl——》OALIntrRequestIrqs )把物理中断转换成系统中断——》InterruptInitialize调用OEMInterruptEnable使能中断并用中断绑定线程——》OEMInterruptHandler屏蔽中断——》执行线程——》InterruptDone——》调用OEMInterruptDone——》调用OALIntrDoneIrqs完成中断线程并重新使能中断

现在看来,5.0BSP和4.2BSP的中断并没有太大差别,一个是动态,一个是静态,OEMInterruptEnable,OEMInterruptHandler函数位置不一样而已——有空看看中断的汇编部分和PB帮助,那么一切都会明了。

这样就完成了物理中断和系统中断之间的转换,比4.2BSP的方法聪明多了。

15 RegSetValueEx(DEVLOAD_SYSINTR_VALNAME,REG_DWORD,(PBYTE)&ddi.dwSysintr, sizeof(UINT32));

16 }

17 else

18 return FALSE;

19 m_pDTRPort = (volatile ULONG *)&(m_pIOPregs->GPDDAT);

20 m_pDSRPort = (volatile ULONG *)&(m_pIOPregs->GPDDAT);

21 m_dwDTRPortNum = 0;

22 m_dwDSRPortNum = 1;

23

24 m_pIOPregs->GPHCON &= ~(0x3<<0 | 0x3<<2 | 0x3<<4 | 0x3<<6 );//tx,rx,rts,cts

25 m_pIOPregs->GPHCON |= (0x2<<0 | 0x2<<2 | 0x2<<4 | 0x2<<6 );

26 m_pIOPregs->GPHCON |= (0x2<<0 | 0x2<<2);

27 m_pIOPregs->GPHUP |= 0xf;

28

29 m_pIOPregs->GPDCON &= ~(0x3<<0 | 0x3<<2);//dtr,dsr

30 m_pIOPregs->GPDCON |= (0x1<<0 | 0x0<<2);

31 m_pIOPregs->GPDUP |= 0x3;

32

33 return CPdd2440Uart::Init();//这里有大量的读注册表的操作,读出的中断是被上面修改过的系统中断了

34 }

35 return FALSE;

36 };

37

38 //---------------------------- 来看看这个再次读注册表的情况吧---------------------

39 BOOL CPdd2440Uart::Init()

40 {

41 if ( CSerialPDD::Init() && IsKeyOpened() && m_XmitFlushDone!=NULL) {

42 // IST Setup .--------Get IRQ forom regedit

43 DDKISRINFO ddi;

44 //再次读出注册表的中断,已经是系统中断了。

45 if (GetIsrInfo(&ddi)!=ERROR_SUCCESS) {

46 return FALSE;

47 }

48 m_dwSysIntr = ddi.dwSysintr;

49 if (m_dwSysIntr != MAXDWORD && m_dwSysIntr!=0 )

50 m_hISTEvent= CreateEvent(0,FALSE,FALSE,NULL);//创建事件,线程创建在后

51

52 //绑定中断PDD线程 ,和MDD中的线程有什么区别?

53 //ThreadRun

54 if (m_hISTEvent!=NULL)

55 InterruptInitialize(m_dwSysIntr,m_hISTEvent,0,0);

56 else

57 return FALSE;

58

59 // Get Device Index.

60 if (!GetRegValue(PC_REG_DEVINDEX_VAL_NAME, (PBYTE)&m_dwDevIndex, PC_REG_DEVINDEX_VAL_LEN)) {

61 m_dwDevIndex = 0;

62 }

63 if (!GetRegValue(PC_REG_SERIALWATERMARK_VAL_NAME,(PBYTE)&m_dwWaterMark,sizeof(DWORD))) {

64 m_dwWaterMark = 8;

65 }

66 if (!GetRegValue(PC_REG_2440UART_INTBIT_VAL_NAME,(PBYTE)&m_dwIntShift,sizeof(DWORD))) {

67 RETAILMSG(1,(TEXT("Registery does not have %s set. Drivers fail!!!\r\n"),PC_REG_2440UART_INTBIT_VAL_NAME));

68 m_dwIntShift =0;

69 return FALSE;

70 }

71 if (!GetRegValue(PC_REG_2440UART_IST_TIMEOUTS_VAL_NAME,(PBYTE)&m_dwISTTimeout, PC_REG_2440UART_IST_TIMEOUTS_VAL_LEN)) {

72 m_dwISTTimeout = INFINITE;

73 }

74 if (!MapHardware() || !CreateHardwareAccess()) {

75 return FALSE;

76 }

77

78 return TRUE;

79 }

80 return FALSE;

81 }

82

83

84

根据我以前在CSDN写的博客,这个KernelIoControl是通过IOCTL_HAL_REQUEST_SYSINTR达到目的,在File: oal_ioctl_tab.h有

{ IOCTL_HAL_REQUEST_SYSINTR, 0, OALIoCtlHalRequestSysIntr },

这个OALIoCtlHalRequestSysIntr正是前面实现物理中断和系统中断转换的函数。

OK,大功告成了!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: