wince 5.0 .2440 5.0BSP的中断过程

S3C2440开发板WinCE5.0触摸屏驱动程序源代码完整分析 本文还有配套的精品资源,点击获取 简介:S3C2440开发板是基于Samsung公司的S3C2440 ARM920T处理器设计的嵌入式平台,拥有丰富的外围接口。WinCE5.0是一种适用于嵌入式设备的实时操作系统,支持多种处理器架构。触摸屏驱动程序在WinCE5.0上负责将触摸操作转换为系统输入事件。本源代码压缩包为开发者提供了研究和定制S3C2440开发板触摸屏驱动程序的... 阅读详情

转载请标明:作者wogoyixikexie@gliet.桂林电子科技大学一系科协,原文地址:http://www.cnblogs.com/wogoyixikexie/(或者我在优快云的博客:http://blog.youkuaiyun.com/gooogleman

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

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

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

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

 

File: oem.c

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--  1 //
  2 // Copyright (c) Microsoft Corporation.  All rights reserved.
  3 //
  4 //
  5 // Use of this source code is subject to the terms of the Microsoft end-user
  6 // license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
  7 // If you did not accept the terms of the EULA, you are not authorized to use
  8 // this source code. For a copy of the EULA, please see the LICENSE.RTF on your
  9 // install media.
 10 //
 11 //------------------------------------------------------------------------------
 12 //
 13 //  File: oem.c
 14 //
 15 //  This file implements a standard implementation of OEMInterrupt functions
 16 //  relating to enabling, disabling and finishing interrupts.
 17 //
 18 #include <windows.h>
 19 #include <nkintr.h>
 20 #include <oal.h>
 21  
 22 
 23 //------------------------------------------------------------------------------
 24 //
 25 //  Function:  OEMInterruptEnable
 26 //
 27 //  This function enables the IRQ given its corresponding SysIntr value.
 28 //  Function returns true if SysIntr is valid, else false.
 29 //
 30 BOOL OEMInterruptEnable(DWORD sysIntr, LPVOID pvData, DWORD cbData)
 31 {
 32     BOOL rc = FALSE;
 33     const UINT32 *pIrqs;
 34     UINT32 count;
 35 
 36     OALMSG(OAL_INTR&&OAL_VERBOSE, 
 37         (L"+OEMInterruptEnable(%d, 0x%x, %d)/r/n", sysIntr, pvData, cbData
 38     ));
 39 
 40     // SYSINTR_VMINI & SYSINTR_TIMING are special cases
 41     if (sysIntr == SYSINTR_VMINI || sysIntr == SYSINTR_TIMING) {
 42         rc = TRUE;
 43         goto cleanUp;
 44     }
 45 
 46     // Obtain the SYSINTR's underlying IRQ number
 47     if (!OALIntrTranslateSysIntr(sysIntr, &count, &pIrqs)) {
 48         // Indicate invalid SysIntr
 49         OALMSG(OAL_ERROR, (
 50             L"ERROR: OEMInterruptEnable: IRQs are undefined for SysIntr %d/r/n", 
 51             sysIntr 
 52         ));
 53         goto cleanUp;
 54     }
 55 
 56     // Enable the interrupt
 57     rc = OALIntrEnableIrqs(count, pIrqs);
 58 
 59 cleanUp:    
 60     OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-OEMInterruptEnable(rc = 1)/r/n"));
 61     return rc;
 62 }
 63 
 64 
 65 //------------------------------------------------------------------------------
 66 //
 67 //  Function:  OEMInterruptDisable(DWORD sysIntr)
 68 //
 69 //  This function disables the IRQ given its corresponding SysIntr value.
 70 //
 71 //
 72 VOID OEMInterruptDisable(DWORD sysIntr)
 73 {
 74     const UINT32 *pIrqs;
 75     UINT32 count;
 76 
 77     OALMSG(OAL_INTR&&OAL_VERBOSE, (L"+OEMInterruptDisable(%d)/r/n", sysIntr));
 78 
 79     // Obtain the SYSINTR's underlying IRQ number
 80     if (!OALIntrTranslateSysIntr(sysIntr, &count, &pIrqs)) {
 81         // Indicate invalid SysIntr
 82         OALMSG(OAL_ERROR, (
 83             L"ERROR: OEMInterruptEnable: IRQs are undefined for SysIntr %d/r/n", 
 84             sysIntr 
 85         ));
 86         goto cleanUp;
 87     }
 88 
 89     // Disable the interrupt
 90     OALIntrDisableIrqs(count, pIrqs);
 91 
 92 cleanUp:
 93     // Indicate exit
 94     OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-OEMInterruptDisable/r/n"));
 95 }
 96 
 97 
 98 //------------------------------------------------------------------------------
 99 //
100 //  Function: OEMInterruptDone
101 //
102 //  OEMInterruptDone is called by the kernel when a device driver
103 //  calls InterruptDone(). The system is not preemtible when this
104 //  function is called.
105 //
106 VOID OEMInterruptDone(DWORD sysIntr)
107 {
108     const UINT32 *pIrqs;
109     UINT32 count;
110 
111     OALMSG(OAL_INTR&&OAL_VERBOSE, (L"+OEMInterruptDone(%d)/r/n", sysIntr));
112     if (OALIntrTranslateSysIntr(sysIntr, &count, &pIrqs)) {
113         OALIntrDoneIrqs(count, pIrqs);
114     }
115     OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-OEMInterruptDone/r/n"));
116 }
117 
118 //------------------------------------------------------------------------------
119 

 

      

     看OALIntrTranslateSysIntr,

 

OALIntrTranslateSysIntr

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-- 1 //------------------------------------------------------------------------------
 2 //
 3 //  Function:  OALIntrTranslateSysIntr
 4 //
 5 //  This function maps a SYSINTR to its corresponding IRQ. It is typically used
 6 //  in OEMInterruptXXX to obtain IRQs for given SYSINTR.
 7 //
 8 BOOL OALIntrTranslateSysIntr(
 9     UINT32 sysIntr, UINT32 *pCount, const UINT32 **ppIrqs
10 ) {
11     BOOL rc;
12 
13     OALMSG(OAL_INTR&&OAL_VERBOSE, (L"+OALTranslateSysIntr(%d)/r/n", sysIntr));
14     
15     // Valid SYSINTR?
16     if (sysIntr >= SYSINTR_MAXIMUM) {
17         rc = FALSE;
18         goto cleanUp;
19     }
20     *pCount = 1;
21     *ppIrqs = &g_oalSysIntr2Irq[sysIntr];
22     rc = TRUE;
23 
24 cleanUp:
25     OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-OALTranslateSysIntr(rc = %d)/r/n", rc));
26     return rc;
27 }
28 

 

     从上面的代码可以知道,以前说这个系统中断数目限制是从哪里来的SYSINTR_MAXIMUM是系统限定了。

不知道系统为什么要做这个限制,我想如果想改动,也是可行的。不过我觉得有点奇怪,这个中断相关的g_oalIrq2SysIntr是怎么回事呢

static UINT32 g_oalSysIntr2Irq[SYSINTR_MAXIMUM];
static UINT32 g_oalIrq2SysIntr[OAL_INTR_IRQ_MAXIMUM];

我原以为是个全局数组,现在看来,还是另有玄机。现在看看g_oalIrq2SysIntr这些到底在哪里被修改过了,就知道这是怎么来的了

 

Code

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--  1 //------------------------------------------------------------------------------
  2 //  刚开始的时候,g_oalSysIntr2Irq和g_oalIrq2SysIntr都是初始化为未定义的
  3 //  Function:  OALIntrMapInit
  4 //
  5 //  This function must be called from OALInterruptInit to initialize mapping
  6 //  between IRQ and SYSINTR. It simply initialize mapping arrays.
  7 //
  8 VOID OALIntrMapInit()
  9 {
 10     UINT32 i;
 11     
 12     OALMSG(OAL_FUNC&&OAL_INTR, (L"+OALIntrMapInit/r/n"));
 13 
 14     // Initialize interrupt maps
 15     for (i = 0; i < SYSINTR_MAXIMUM; i++) {
 16         g_oalSysIntr2Irq[i] = OAL_INTR_IRQ_UNDEFINED;
 17     }
 18     for (i = 0; i < OAL_INTR_IRQ_MAXIMUM; i++) {
 19         g_oalIrq2SysIntr[i] = SYSINTR_UNDEFINED;
 20     }
 21 
 22     OALMSG(OAL_FUNC&&OAL_INTR, (L"-OALIntrMapInit/r/n"));
 23 }
 24 
 25 //------------------------------------------------------------------------------
 26 //  静态映射中断 在2440 5.0BSP没有使用到
 27 //  Function:   OALIntrStaticTranslate
 28 //
 29 //  This function sets static translation between IRQ and SYSINTR. In most
 30 //  cases it should not be used. Only exception is mapping for 
 31 //  SYSINTR_RTC_ALARM and obsolete device drivers.
 32 //
 33 VOID OALIntrStaticTranslate(UINT32 sysIntr, UINT32 irq)
 34 {
 35     OALMSG(OAL_FUNC&&OAL_INTR, (
 36         L"+OALIntrStaticTranslate(%d, %d)/r/n", sysIntr, irq
 37     ));
 38     if (irq < OAL_INTR_IRQ_MAXIMUM && sysIntr < SYSINTR_MAXIMUM) {
 39         g_oalSysIntr2Irq[sysIntr] = irq;
 40         g_oalIrq2SysIntr[irq] = sysIntr;
 41     }        
 42     OALMSG(OAL_FUNC&&OAL_INTR, (L"-OALIntrStaticTranslate/r/n"));
 43 }
 44 
 45 //------------------------------------------------------------------------------
 46 //  这个函数作用很大,把物理中断转换成系统中断
 47 //  Function:  OALIntrRequestSysIntr
 48 //
 49 //  This function allocate new SYSINTR for given IRQ and it there isn't
 50 //  static mapping for this IRQ it will create it.
 51 //
 52 UINT32 OALIntrRequestSysIntr(UINT32 count, const UINT32 *pIrqs, UINT32 flags)
 53 {
 54     UINT32 irq, sysIntr;
 55 
 56     OALMSG(OAL_INTR&&OAL_FUNC, (
 57         L"+OALIntrRequestSysIntr(%d, 0x%08x, 0x%08x)/r/n", count, pIrqs, flags
 58     ));
 59     
 60     // Valid IRQ?
 61     if (count != 1 || pIrqs[0] >= OAL_INTR_IRQ_MAXIMUM) {
 62         sysIntr = SYSINTR_UNDEFINED;            
 63         goto cleanUp;
 64     }
 65     irq = pIrqs[0];
 66 
 67     // If there is mapping for given irq check for special cases
 68     if (g_oalIrq2SysIntr[irq] != SYSINTR_UNDEFINED) {
 69         // If static mapping is requested we fail
 70         if ((flags & OAL_INTR_STATIC) != 0) {
 71             OALMSG(OAL_ERROR, (L"ERROR: OALIntrRequestSysIntr: "
 72                L"Static mapping for IRQ %d already assigned/r/n", irq
 73             ));
 74             sysIntr = SYSINTR_UNDEFINED;            
 75             goto cleanUp;
 76         }
 77         // If we should translate, return existing SYSINTR
 78         if ((flags & OAL_INTR_TRANSLATE) != 0) {
 79             sysIntr = g_oalIrq2SysIntr[irq];
 80             goto cleanUp;
 81         }
 82     }
 83 
 84     // Find next available SYSINTR value
 85     for (sysIntr = SYSINTR_FIRMWARE; sysIntr < SYSINTR_MAXIMUM; sysIntr++) {
 86         if (g_oalSysIntr2Irq[sysIntr] == OAL_INTR_IRQ_UNDEFINED) break;
 87     }
 88     
 89     // Any available SYSINTRs left?
 90     if (sysIntr >= SYSINTR_MAXIMUM) {
 91         OALMSG(OAL_ERROR, (L"ERROR: OALIntrRequestSysIntr: "
 92             L"No avaiable SYSINTR found/r/n"
 93         ));            
 94         sysIntr = SYSINTR_UNDEFINED;
 95         goto cleanUp;
 96     }
 97     
 98     // Make SYSINTR -> IRQ association.
 99     g_oalSysIntr2Irq[sysIntr] = irq;
100     
101     // Make IRQ -> SYSINTR association if required
102     if ((flags & OAL_INTR_DYNAMIC) != 0) goto cleanUp;
103     if (
104         g_oalIrq2SysIntr[irq] == SYSINTR_UNDEFINED ||
105         (flags & OAL_INTR_FORCE_STATIC) != 0
106     ) {
107         g_oalIrq2SysIntr[irq] = sysIntr;
108     }
109 
110 cleanUp:
111     OALMSG(OAL_INTR&&OAL_FUNC, (
112         L"-OALIntrRequestSysIntr(sysIntr = %d)/r/n", sysIntr
113     ));
114     return sysIntr;
115 }
116 
117 //------------------------------------------------------------------------------
118 //  释放系统中断
119 //  Function:  OALIntrReleaseSysIntr
120 //
121 //  This function release given SYSINTR and remove static mapping if exists.
122 //
123 BOOL OALIntrReleaseSysIntr(UINT32 sysIntr)
124 {
125     BOOL rc = FALSE;
126     UINT32 irq;
127 
128     OALMSG(OAL_INTR&&OAL_FUNC, (L"+OALIntrReleaseSysIntr(%d)/r/n", sysIntr));
129 
130     // Is the SYSINTR already released?
131     if (g_oalSysIntr2Irq[sysIntr] == OAL_INTR_IRQ_UNDEFINED) goto cleanUp;
132 
133     // Remove the SYSINTR -> IRQ mapping
134     irq = g_oalSysIntr2Irq[sysIntr];
135     g_oalSysIntr2Irq[sysIntr] = OAL_INTR_IRQ_UNDEFINED;
136 
137     // If we're releasing the SYSINTR directly mapped in the IRQ mapping, 
138     // remove the IRQ mapping also
139     if (g_oalIrq2SysIntr[irq] == sysIntr) {
140         g_oalIrq2SysIntr[irq] = SYSINTR_UNDEFINED;
141     }
142 
143 cleanUp:
144     OALMSG(OAL_INTR&&OAL_FUNC, (L"-OALIntrReleaseSysIntr(rc = %d)/r/n", rc));
145     return rc;
146 }
147 以上代码均来自C:/WINCE500/PLATFORM/COMMON/SRC/COMMON/INTR/BASE/map.c
148 
149 //------------------------------------------------------------------------------

 

     再来看OALIntrEnableIrqs这个函数是怎么实现的

 

 

OALIntrEnableIrqs

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-- 1 //------------------------------------------------------------------------------
 2 //
 3 //  Function:  OALIntrEnableIrqs
 4 //
 5 BOOL OALIntrEnableIrqs(UINT32 count, const UINT32 *pIrqs)
 6 {
 7     BOOL rc = TRUE;
 8     UINT32 i, mask, irq;
 9 
10     OALMSG(OAL_INTR&&OAL_FUNC, (
11         L"+OALIntrEnableIrqs(%d, 0x%08x)/r/n", count, pIrqs
12     ));
13 
14     for (i = 0; i < count; i++) {
15 #ifndef OAL_BSP_CALLBACKS
16         irq = pIrqs[i];
17 #else
18         // Give BSP chance to enable irq on subordinate interrupt controller
19         irq = BSPIntrEnableIrq(pIrqs[i]);
20 #endif
21         if (irq == OAL_INTR_IRQ_UNDEFINED) continue;
22         // Depending on IRQ number use internal or external mask register
23         if (irq <= IRQ_ADC) {
24             // Use interrupt mask register
25             CLRREG32(&g_pIntrRegs->INTMSK, 1 << irq);
26         } else if (irq <= IRQ_EINT7) {
27             // Use external mask register
28             CLRREG32(&g_pIntrRegs->INTMSK, 1 << IRQ_EINT4_7);
29             CLRREG32(&g_pPortRegs->EINTMASK, 1 << (irq - IRQ_EINT4 + 4));
30         } else if (irq <= IRQ_EINT23) {
31             // Use external mask register
32             mask = 1 << (irq - IRQ_EINT4 + 4);
33             OUTREG32(&g_pPortRegs->EINTPEND, mask);
34             CLRREG32(&g_pPortRegs->EINTMASK, mask);
35             mask = 1 << IRQ_EINT8_23;
36             if ((INREG32(&g_pIntrRegs->INTPND) & mask) != 0) {
37                 OUTREG32(&g_pIntrRegs->INTPND, mask);
38             }
39             CLRREG32( &g_pIntrRegs->INTMSK, 1 << IRQ_EINT8_23);
40         } else {
41             rc = FALSE;
42         }
43     }        
44 
45     OALMSG(OAL_INTR&&OAL_FUNC, (L"-OALIntrEnableIrqs(rc = %d)/r/n", rc));
46     return rc;    
47 }

 

     通过以上的分析,这个代码是比较明朗,但是我们还是不明白这个中断到底是如何申请的,现在找一些驱动的代码来看看,以简单的重启按键驱动为例子,发现这个InterruptInitialize函数起到初始化中断和绑定线程的作用,现在看看PB帮助。

 

This function initializes a hardware interrupt with the kernel. This initialization allows the device driver to register an event and enable the interrupt.

BOOL InterruptInitialize( 
DWORD idInt,
HANDLE hEvent,
LPVOID pvData,
DWORD cbData 
);

Parameters idInt [in] Interrupt identifier to be associated with this interrupt service thread (IST). hEvent [in] Event to be signaled when the interrupt is triggered. pvData [in] This parameter can be used as a pointer to a block of data that is passed to OEMInterruptEnable. The block of data can be initialization data, scratch space, and so on. cbData [in] Size of data pointed to by pvData. Return Values

TRUE indicates success; FALSE indicates failure.

Remarks

This function must be called before using the hEvent parameter, which provides a link between the idInt parameter and the SYSINTR value returned by an ISR.

The hEvent parameter can only be used in a WaitForSingleObject call to wait for the event to be triggered by the kernel.

A WaitForMultipleObjects call with hEvent will fail.

If you use hEvent in a call to WaitForSingleObject before you call InterruptInitialize, InterruptInitialize will fail.

Requirements

OS Versions: Windows CE 2.10 and later.
Header: Pkfuncs.h.
Link Library: Coredll.lib.——郁闷,不开源的。

     从PB帮助可以知道,这个

This function initializes a hardware interrupt with the kernel. This initialization allows the device driver to register an event and enable the interrupt.

BOOL InterruptInitialize( 
DWORD idInt,
HANDLE hEvent,
LPVOID pvData,
DWORD cbData 
);

Parameters idInt [in] Interrupt identifier to be associated with this interrupt service thread (IST). hEvent [in] Event to be signaled when the interrupt is triggered. pvData [in] This parameter can be used as a pointer to a block of data that is passed to OEMInterruptEnable. The block of data can be initialization data, scratch space, and so on. cbData [in] Size of data pointed to by pvData. Return Values

TRUE indicates success; FALSE indicates failure.

Remarks

This function must be called before using the hEvent parameter, which provides a link between the idInt parameter and the SYSINTR value returned by an ISR.

The hEvent parameter can only be used in a WaitForSingleObject call to wait for the event to be triggered by the kernel.

A WaitForMultipleObjects call with hEvent will fail.

If you use hEvent in a call to WaitForSingleObject before you call InterruptInitialize, InterruptInitialize will fail.

Requirements

OS Versions: Windows CE 2.10 and later.
Header: Pkfuncs.h.
Link Library: Coredll.lib.——郁闷,不开源的。

     从PB帮助可以知道InterruptInitialize函数的功能是绑定线程和系统中断,并且调用OEMInterruptEnable使能中断

(When a device driver calls the InterruptInitialize kernel routine, the kernel then calls OEMInterruptEnable)

            InterruptInitialize 函数使用的是系统中断来绑定线程的,那么这个物理中断是如何转换成系统中断的呢?这个5.0和4.2BSP是不同的。——答案是伟大的KernelIoControl函数,这个函数的具体用法请参照PB帮助吧。

 

This function provides the kernel with a generic I/O control for carrying out I/O operations.

BOOL KernelIoControl( 
DWORD dwIoControlCode,
LPVOID lpInBuf,
DWORD nInBufSize,
LPVOID lpOutBuf,
DWORD nOutBufSize,
LPDWORD lpBytesReturned 
);

Parameters dwIoControlCode [in] I/O control code, which should support the OAL I/O controls. For a list of these I/O controls, see OAL IOCTLs. lpInBuf [out] Pointer to a buffer that contains the data required to perform the operation.

Set to NULL if the dwIoControlCode parameter specifies an operation that does not require input data.

nInBufSize [in] Size, in bytes, of the buffer pointed to by lpInBuf. lpOutBuf [out] Pointer to a buffer that receives the output data for the operation.

Set to NULL if the dwIoControlCode parameter specifies an operation that does not produce output data.

nOutBufSize [in] Size, in bytes, of the buffer pointed to by lpOutBuf. lpBytesReturned [in] Long pointer to a variable that receives the size, in bytes, of the data stored in the buffer pointed to by lpOutBuf. Even when an operation produces no output data, and lpOutBuf is NULL, the KernelIoControl function uses the variable pointed to by lpBytesReturned. After such an operation, the value of the variable has no meaning. Return Values

TRUE indicates success; FALSE indicates failure.

Remarks

The kernel calls the OEMIoControl function when a device driver or application calls the kernel function KernelIoControl and passes an I/O control code. ——这个很关键,关于OEMIoControl 函数我在优快云博客有介绍。这是实现中断转换的关键函数

This function is also called when the SystemParametersInfo function is called with SPI_GETOEMINFO or SPI_GETPLATFORMINFO.

The system is fully preemptible when this function is called. The kernel does no processing, but it passes all parameters directly to the function supplied by you.

This function is provided solely to allow your device driver or application to communicate with an OAL and its specific functionality.

     现在就拿2440 5.0BSP串口驱动来具体分析一下 

2440串口驱动

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-- 1     virtual BOOL Init() {
 2         PHYSICAL_ADDRESS    ioPhysicalBase = { S3C2440A_BASE_REG_PA_IOPORT, 0};
 3         ULONG               inIoSpace = 0;
 4         if (TranslateBusAddr(m_hParent,Internal,0, ioPhysicalBase,&inIoSpace,&ioPhysicalBase)) {
 5             // Map it if it is Memeory Mapped IO.
 6             m_pIOPregs = (S3C2440A_IOPORT_REG *)MmMapIoSpace(ioPhysicalBase, sizeof(S3C2440A_IOPORT_REG),FALSE);
 7         }
 8         if (m_pIOPregs) {
 9             DDKISRINFO ddi;
10 //读取注册表的IRQ的键值(这个键值还是物理中断的值,是中断偏移寄存器(INTOFFSET指定IRQ中断源)的值,4.2BSP就利用了这个东西)
11             if (GetIsrInfo(&ddi)== ERROR_SUCCESS && 
12                     KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &ddi.dwIrq, sizeof(UINT32), &ddi.dwSysintr, sizeof(UINT32), NULL))
13             {   //使用KernelIoControl完成物理中断和系统中断转换之后,又把这个系统中断写入到注册表中,下次读出的中断
14                   //就是系统中断了 这样就完成了物理中断和系统中断之间的转换,比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 

 

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

{ IOCTL_HAL_REQUEST_SYSINTR,                0,  OALIoCtlHalRequestSysIntr   }, 

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

     OK,大功告成了!

参考资料:http://www.cnblogs.com/wogoyixikexie/archive/2009/02/04/1384012.html(OEMIoControl)

              何宗健——《windows CE嵌入式系统》

为什么RingMo能成为遥感领域的首个生成式自监督基础模型? RingMo作为遥感领域首个生成式自监督基础模型,通过创新的图像掩码建模技术解决了传统方法在遥感图像处理中的挑战。该模型利用两百万张多元数据集进行预训练,在小目标检测、场景分类等任务上表现卓越,显著提升了性能指标。RingMo的技术突破为遥感图像解译提供了高效解决方案,降低了标注成本并增强了模型泛化能力。 阅读详情

相关推荐

Redhawk-SC输入件配置中的5个常见错误及解决方法

本文针对Redhawk-SC功耗与可靠性签核工具,深入剖析了输入件配置中工艺文件错配、DEF文件路径、时序文件格式、电源网络模型及宏模型处理这5个最常见且棘手的错误。文章提供了资深工程师验证过的实战解决方案与检查清单,旨在帮助用户规避风险,提升配置效率与分析准确性,确保芯片签核流程的顺利进行。

earth的博客 233

Linux设备驱动编程之中断处理

与Linux设备驱动中中断处理相关的首先是申请与释放IRQ的API request_irq()和free_irq(),request_irq()的原型为: int request_irq(unsigned int irq,void (*handler)(int irq, void *dev_id, struct pt_regs *reg

menuconfig的专栏 961

STM32驱动2.8寸TFTLCD屏幕实战:从看懂原理图到点亮第一个像素(基于ILI9341)

本文详细介绍了如何使用STM32驱动2.8寸TFTLCD屏幕(基于ILI9341驱动芯片),从硬件连接到软件配置,包括FSMC接口设置、ILI9341初始化序列、坐标设置及基础绘图函数实现。文章还提供了常见问题排查指南和性能优化技巧,帮助开发者快速解决屏幕不亮等问题,并提升显示性能。

weixin_42665255的博客 268

wince 5.0 .2440 5.0BSP的中断过程(作者:wogoyixikexie@gliet)

wince 5.0 .2440 5.0BSP的中断过程(作者:wogoyixikexie@gliet)      以前在优快云写过一些wince5.0中断的文章,现在重新看看,发现以前的有些理解是错误的,想翻开来改改,可是郁闷的优快云在前台没有返回后台的编辑功能,所以现在重新写一篇纠正一下。      首先描述wince5.0 (2440BSP)的中断流程     注册表等——

gooogleman#foxmail.com 2876

STM32F407实现LwIP的MQTT客户端并连接到服务器

这个是用LwIP协议栈中自带的MQTT客户端API写成的,代码注释很详细,附带有服务端的展示。LwIP版本是2.1.2.

wait_for_STM32的博客 6398

别再乱选保护板了!手把手教你用ABLIC S-8254A为3/4串锂电池组DIY安全保护电路

本文详细介绍了如何使用ABLIC S-8254A保护集成电路为3/4串锂电池组DIY安全保护电路。从选型策略、电路搭建到功能验证,手把手教你实现可靠的充放电保护系统,适用于无人机、电动工具等场景,确保锂电池组的安全使用。

weixin_42525264的博客 189

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

wince 5.0 .2440 5.0BSP的中断过程(转) 以前在优快云写过一些wince5.0中断的文章,现在重新看看,发现以前的有些理解是错误的,想翻开来改改,可是郁闷的优快云在前台没有返回后台的编辑功能,所以现在重新写一篇纠正一下。       首先描述wince5.0 (2440BSP)的中断流程      注册表等——》KernelIoControl(——》OEM

wuan584974722的专栏 856

SRv6第二弹:SRv6基本概念

在SRv6网络编程中,不同的转发行为由不同的Function来标识,例如在RFC中定义了公认的End、End.X、End.DX4、End.DX6等。例如:R3使用报文的IPv6目的地址FC03::3查找Local SID表,命中到End SID,随后R3将报文SL减1,同时将SL=1的SID做为报文目标IPv6地址,并查路由表转发出去。SID支持静态配置或者动态分配,end-op、end、end.x、end-dt4、end-dt6、end-dx2推荐静态配置 ,便于网络运维,其他的SID可以动态分配。

wbyyy的博客 4251

转:wince 5.0 .2440 5.0BSP的中断过程(作者:wogoyixikexie@gliet)

 以前在优快云写过一些wince5.0中断的文章,现在重新看看,发现以前的有些理解是错误的,想翻开来改改,可是郁闷的优快云在前台没有返回后台的编辑功能,所以现在重新写一篇纠正一下。      首先描述wince5.0 (2440BSP)的中断流程     注册表等——》KernelIoControl(——》OEMIoControl——》OALIntrRequestIrqs )把物理中断

luixing67的专栏 651

thinkphp5.0.24反序列化漏洞分析

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!因此收集整理了一份《Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

m0_67392182的博客 1871

YOLOv11改进策略【模型轻量化】| 替换骨干网络 CVPR-2024 RepViT 轻量级的Vision Transformers架构

本文记录的是基于RepVit的YOLOv11轻量化改进方法研究。RepVit的网络结构借鉴ViT的设计理念,通过分离的token mixe和减少推理时的计算和内存成本,同时减少扩展比率并增加宽度,降低延迟,并通过来弥补参数大幅减少的问题,提高了准确性。本文在替换骨干网络中配置了原论文中的和五种模型,以满足不同的需求。

Limiiiing的博客 2976

【下载】关于Samsung2440原厂WINCE500/600 BSP下载

昨天晚上收集了一下最新的SAMSUNG的BSP。这里共享给大家,也算是给原厂和友善做个分流了。主要是原厂的2440 wince5.0的BSP最新版本以及友善2440 wince6.0的BSP。友善的6.0 BSP是最近才relesase出来,值得移植下看看。这里建议大家可以用500的BSP来移植到600上。参考文档如下:2440 wince6.0移植文档 by Goooglem

这个世界乱纷纷,先把自己锻炼成器 1667

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

2440从WINCE5.0升到WINCE6.0

2440从WINCE5.0升到WINCE6.02443的BSP有6.0的,不过我们不用2443,现在想把2440从WINCE5.0升到WINCE6.0,有想做的朋友我们一起来吧这两天有点时间,我总结一下。我的平台条件:UBOOT+WINCE50BSP+800×480(7寸屏),因为用UBOOT,所以我没有升级BOOTLOADER请大家参考一下本贴的一些问题,链接等等,基本就OK了,伧促记之,错误在所难免,望高手指正。如果大家有什么高招,请一定分享,饮水思源,来了论坛总得有点贡献嘛!总结:一:OAL.H修改1

1201

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

移植wince 5.0到2440

从网上下载的smdk2440 bsp,自己修改在platform builder 5.0下编译,历经千辛万苦,编译出了nk.nb0,nk.bin,自己写的boot程序先启动硬件,再用j-link的loadbin命令下载nk.nb0到0x80200000地址,运行后桌面显示出几个排列在一起的图标,图质粗糙,比例看起来也不对,没有任务栏,都不太像wince桌面。运行时串口输出的内容很多(因为我打开了多

联华众科的专栏 2140

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

WinCE5.0 BSP BOOTLOADER开发详解-郁闷的前三步

在书市和网上溜达一圈,只发现两本关于Bootloader的开发资料。一个是电子工业出版社出版的《Windows CE.NET实用开发技术》;另一个是PB的HELP文件。其他大多为介绍Bootloader相关知识的,最多也就是修改一下官方的Bootloader源码。 觉得没什么意思!如果官方不给源码呢?咱还是要从零开始。也算是发扬自力更生、艰苦奋斗的革命精神。由于本人的英文太差,在金山词霸的帮助

笑向天的专栏 1995

wince 5.0 移植到 utu2440 开发板记录

wince 5.0 移植到 utu2440 开发板记录   1、修改时钟频率需要修改为  FCLK = 400M  HCLK = 100M  PCLK = 50M跟据以上关系,则需要设置  HDIVN = 2  PDIVN = 1  HCLK3_HALF = 0  HCLK4_HALF = 0计算出  CLKDIVN = 0x05 需要修改的文件有src/Bootloader/Eboot/startup.s    ;Apollo +    ;PLLVAL EQU (((0x6e     PLLVAL EQU

702

2440 6.0BSP 移植过程之OAL

2440 6.0BSP 移植过程之OAL  //----------------------------------------------------------------------------------------------------------- // 作者:wogoyixikexie@gliet //论坛账号:gooogleman (经常在优快云出没)

gooogleman#foxmail.com 2277

SMDK2440A 5.0BSP之eboot流程(作者:wogoyixikexie@gliet)

SMDK2440A 5.0BSP之eboot流程(作者:wogoyixikexie@gliet)      这两天为了搞明白bootloader的binfs分区功能,看了大量代码,觉得有必要把整个eboot流程疏理一下。至于binfs分区以及MBR等相关信息,请看http://topic.csdn.net/u/20081203/11/6d0f940c-03e1-487b-a922-e08cc9

gooogleman#foxmail.com 5124

SMDK2440A 5 0BSP之eboot流程(作者 wogoyixikexie gliet)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SMDK2440A 5.0BSP之eboot流程(作者:wogoyixikexie@gliet)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这两天为了搞

hfdghjh的博客 249

s3c2440 smdk2440 BSP(linux,wince) download 板级支持包下载

http://just4you.springnote.com/pages/1052612?print=1 S3C2440A 관련자료SamsungCPU 관련자료S3C2440A Brochure : S3C2440_200311.pdfRevision Points : 2440x_to_2440a_revision_points-040203.pdf

samantha_sun的专栏 3982
上一篇: PS2键盘编程详细资料
下一篇: Windows CE 电源管理
menuconfig
博客等级 码龄19年 713粉丝 6原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值