79

帖子

0

TA的资源

一粒金砂(初级)

21
 
引用 17 楼 xqhrs232 的回复:
我的BSP有一个对照表,物理号跟虚拟号是对应的,其实只要知道一个就可以的.知道其中一个用数组访问一个就可以知道另外的一个.


1>static const UINT32 g_VirIrq2PhyIrq[IRQ_MAX_S3C6410]
2>static const UINT32 g_PhyIrq2VirIrq[PHYIRQ_MAX_S3C6410]


哦...那就是说你在注册表中传进去物理中断号或者虚拟中断号都无所谓了??

回复

73

帖子

0

TA的资源

一粒金砂(初级)

22
 
“我没弄什么16550,我只是在弄虚拟串口驱动程序顺带把串口驱动看了看.你弄过虚拟串口没?”

没,不过你可以参照
http://blog.chinaunix.net/u1/49088/showart_1933553.html

试试
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

23
 
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\Serial]
    "SysIntr"=dword:13
    "Irq"=dword:3
    "IoBase"=dword:02F8
    "IoLen"=dword:8
    "DeviceArrayIndex"=dword:0
    "Prefix"="COM"
    "Dll"="Com16550.Dll"
    "Order"=dword:0
    "Priority"=dword:0
    "IsrDll"="isr16550.dll"
    "IsrHandler"="ISRHandler"


这个是MS给的例子注册表
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

24
 
引用 18 楼 wangxin_801115 的回复:
pSerObj->dwIntID = DeviceArrayIndex
不知道后面为什么很多地方用到这个ID作为一个中断号用

昨天有位高手给我解释了一下,大概是说从MDD起的时候需要用真正的外部中断
从PDD起的时候就用这个ID(也就是DeviceArrayIndex )来判断用的哪个串口

不知道记没记反,具体没理解上去!

想先把中断这个问题搞定

昨天编译了一个内核进去,到com16550的驱动后就死机了
今天换个驱动试试!


估计跟这个是一个意思,线程在那里就表示从那里起!!!
pSerialHead->pHWObj->BindFlags有三种模式!!!

1>THREAD_AT_INIT
2>THREAD_IN_PDD
3>THREAD_AT_MDD


 
 
 

回复

79

帖子

0

TA的资源

一粒金砂(初级)

25
 


  1. PVOID
  2. SerInit(
  3.        ULONG   Identifier, // @parm Device identifier.
  4.        PVOID   pMddHead,   // @parm First argument to mdd callbacks.
  5.        PHWOBJ  pHWObj      // @parm Pointer to our own HW OBJ for this device
  6.        )
  7. {
  8.     DEBUGMSG (ZONE_CLOSE,(TEXT("+SerInit, 0x%X\r\n"), Identifier));
  9.     CSerialPDD * pSerialPDD = NULL;
  10.     if (pHWObj) {
  11.         DWORD dwIndex= pHWObj->dwIntID;
  12.         pHWObj->dwIntID = 0;
  13.         pSerialPDD = CreateSerialObject((LPTSTR)Identifier,pMddHead, pHWObj,dwIndex);
  14.     }
  15.     if (pSerialPDD==NULL) {
  16.         ASSERT(FALSE);
  17.         LocalFree(pHWObj);
  18.     }
  19.     DEBUGMSG (ZONE_CLOSE,(TEXT("-SerInit, 0x%X\r\n"), pSerialPDD));
  20.     return pSerialPDD;
  21. }
  22. //=====================================================================================================


  23. CSerialPDD * CreateSerialObject(LPTSTR lpActivePath, PVOID pMdd,PHWOBJ pHwObj, DWORD DeviceArrayIndex)
  24. {
  25.     CSerialPDD * pSerialPDD = NULL;
  26.     RETAILMSG( TRUE, (TEXT("DEBUG: CreateSerialObject %d\r\n"), DeviceArrayIndex));
  27.     switch (DeviceArrayIndex)
  28.     {
  29.     case 0:        ///< UART0
  30.         pSerialPDD = new CPdd6410Serial0(lpActivePath,pMdd, pHwObj);
  31.         break;
  32.     case 1:        ///< UART1
  33.         pSerialPDD = new CPdd6410Serial1(lpActivePath,pMdd, pHwObj);
  34.         break;
  35.     case 2:        ///< UART2(IrDA)
  36.         pSerialPDD = new CPdd6410Serial2(lpActivePath, pMdd, pHwObj);
  37.         break;
  38.     case 3:        ///< UART3(IrDA)
  39.         pSerialPDD = new CPdd6410Serial3(lpActivePath, pMdd, pHwObj);
  40.         break;
  41.     }
  42.     if (pSerialPDD && !pSerialPDD->Init())
  43.     {
  44.         delete pSerialPDD;
  45.         pSerialPDD = NULL;
  46.     }   
  47.     return pSerialPDD;
  48. }
  49. //===========================================================================================================

  50. virtual BOOL Init()
  51.     {
  52.         PHYSICAL_ADDRESS    ioPhysicalBase = { S3C6410_BASE_REG_PA_GPIO, 0};
  53.         ULONG                inIoSpace = 0;
  54.         if (TranslateBusAddr(m_hParent,Internal,0, ioPhysicalBase,&inIoSpace,&ioPhysicalBase))
  55.         {
  56.             // Map it if it is Memeory Mapped IO.
  57.             m_pIOPregs = (S3C6410_GPIO_REG *)DrvLib_MapIoSpace(ioPhysicalBase.LowPart , sizeof(S3C6410_GPIO_REG),FALSE);
  58.         }
  59.         ioPhysicalBase.LowPart = S3C6410_BASE_REG_PA_SYSCON;
  60.         ioPhysicalBase.HighPart = 0;
  61.         if (TranslateBusAddr(m_hParent,Internal,0, ioPhysicalBase,&inIoSpace,&ioPhysicalBase))
  62.         {
  63.             m_pSysconRegs = (S3C6410_SYSCON_REG *) DrvLib_MapIoSpace(ioPhysicalBase.LowPart ,sizeof(S3C6410_SYSCON_REG),FALSE);
  64.         }
  65.         if(m_pSysconRegs)
  66.         {
  67.             m_pSysconRegs->PCLK_GATE  |= (1<<1);        // UART0
  68.             m_pSysconRegs->SCLK_GATE  |= (1<<5);        // UART0~3   
  69.         }
  70.         if (m_pIOPregs)
  71.         {
  72.             DDKISRINFO ddi;
  73.             if (GetIsrInfo(&ddi)== ERROR_SUCCESS &&
  74.                  KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &ddi.dwIrq, sizeof(UINT32), &ddi.dwSysintr, sizeof(UINT32), NULL))
  75.             {   
  76.                 //RETAILMSG( TRUE, (TEXT("DEBUG: Serial0 SYSINTR : %d\r\n"), (PBYTE)&ddi.dwSysintr));
  77.                 RegSetValueEx(DEVLOAD_SYSINTR_VALNAME,REG_DWORD,(PBYTE)&ddi.dwSysintr, sizeof(UINT32));
  78.             }
  79.             else
  80.             {
  81.                 return FALSE;
  82.             }
  83.             //gao0129
  84.             /*
  85.             m_pDTRPort = (volatile ULONG *)&(m_pIOPregs->GPNDAT);
  86.             m_pDSRPort = (volatile ULONG *)&(m_pIOPregs->GPNDAT);
  87.             m_dwDTRPortNum = 6;
  88.             m_dwDSRPortNum = 7;
  89.             */
  90.             // CTS0(GPA2), RTS0(GPA3), TXD0(GPA1), RXD0(GPA0)
  91.             m_pIOPregs->GPACON &= ~(0xf<<0 | 0xf<<4 | 0xf<<8 | 0xf<<12 );    ///< Clear Bit
  92.             m_pIOPregs->GPACON |=  (0x2<<0 | 0x2<<4 | 0x2<<8 | 0x2<<12 );     ///< Select UART IP               
  93.             m_pIOPregs->GPAPUD &= ~(0x3<<0 | 0x3<<2 | 0x3<<4 | 0x3<<6 );    ///< Pull-Up/Down Disable  

  94.             // DTR0(GPN6), DSR0(GPN7)
  95.             // If you want to use COM1 port for ActiveSync, use these statements.   
  96.             //gao0129
  97.             /*  
  98.             m_pIOPregs->GPNCON &= ~(0x3<<12);    ///< DTR0 Clear Bit
  99.             m_pIOPregs->GPNCON |= (0x1<<12);    ///< Output
  100.             m_pIOPregs->GPNPUD &= ~(0x3<<12);    ///< Pull-Up/Down Disable
  101.             m_pIOPregs->GPNCON &= ~(0x3<<14);    ///< DSR0 Clear Bit
  102.             m_pIOPregs->GPNCON |= (0x0<<14);    ///< Input
  103.             m_pIOPregs->GPNPUD &= ~(0x3<<14);    ///< Pull-Up/Down Disable
  104.             */
  105.             return CPdd6410Uart::Init();
  106.         }
  107.         return FALSE;
  108.     }
  109. //===================================================================================================================
  110. BOOL CPdd6410Uart::Init()
  111. {
  112.     if ( CSerialPDD::Init() && IsKeyOpened() && m_XmitFlushDone!=NULL)
  113.     {
  114.         // IST Setup .
  115.         DDKISRINFO ddi;
  116.         if (GetIsrInfo(&ddi)!=ERROR_SUCCESS)
  117.         {
  118.             return FALSE;
  119.         }
  120.         m_dwSysIntr = ddi.dwSysintr;
  121.         if (m_dwSysIntr !=  MAXDWORD && m_dwSysIntr!=0 )
  122.         {
  123.             m_hISTEvent= CreateEvent(0,FALSE,FALSE,NULL);
  124.         }

  125.         if (m_hISTEvent!=NULL)
  126.         {
  127.             InterruptInitialize(m_dwSysIntr,m_hISTEvent,0,0);
  128.         }
  129.         else
  130.         {
  131.             return FALSE;
  132.         }

  133.         // Get Device Index.
  134.         if (!GetRegValue(PC_REG_DEVINDEX_VAL_NAME, (PBYTE)&m_dwDevIndex, PC_REG_DEVINDEX_VAL_LEN))
  135.         {
  136.             m_dwDevIndex = 0;
  137.         }
  138.         if (!GetRegValue(PC_REG_SERIALWATERMARK_VAL_NAME,(PBYTE)&m_dwWaterMark,PC_REG_SERIALWATERMARKER_VAL_LEN))
  139.         {
  140.             m_dwWaterMark = 8;
  141.         }
  142.         if (!GetRegValue(PC_REG_6410UART_IST_TIMEOUTS_VAL_NAME,(PBYTE)&m_dwISTTimeout, PC_REG_6410UART_IST_TIMEOUTS_VAL_LEN))
  143.         {
  144.             m_dwISTTimeout = INFINITE;
  145.         }
  146.         if (!GetRegValue(PC_REG_6410UART_MEM_LENGTH_VAL_NAME, (PBYTE)&m_dwMemLen, PC_REG_6410UART_MEM_LENGTH_VAL_LEN))
  147.         {
  148.             m_dwMemLen = 0x40;
  149.         }
  150.         if (!MapHardware()  || !CreateHardwareAccess())
  151.         {
  152.             return FALSE;
  153.         }

  154.         return TRUE;        
  155.     }
  156.     return FALSE;
  157. }



复制代码



下面的代码是通过物理中断号去向系统请求系统中断(也就是虚拟中断),并用ddi.dwSysintr去改变注册表.
下次GetIsrInfo读到的就是改变后的值了.

DDKISRINFO ddi;
            if (GetIsrInfo(&ddi)== ERROR_SUCCESS &&
                 KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &ddi.dwIrq, sizeof(UINT32), &ddi.dwSysintr, sizeof(UINT32), NULL))
            {   
                //RETAILMSG( TRUE, (TEXT("DEBUG: Serial0 SYSINTR : %d\r\n"), (PBYTE)&ddi.dwSysintr));
                RegSetValueEx(DEVLOAD_SYSINTR_VALNAME,REG_DWORD,(PBYTE)&ddi.dwSysintr, sizeof(UINT32));
            }
            else
            {
                return FALSE;
            }

 
 
 

回复

80

帖子

0

TA的资源

一粒金砂(初级)

26
 
自己顶一下!!!
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

27
 
仔细看了一下.应该是开线程有两种方式,一种是在MDD里面开,一种是在PDD层里面去开.


在COM_Init( )里面
{

//2009--10--10  xqh  我在怀疑会不会进入这个分支!!!
    if ( pSerialHead->pHWObj->BindFlags & THREAD_AT_INIT )
    {
        // Hook the interrupt and start the associated thread.
        if ( ! StartDispatchThread( pSerialHead ) )
        {
            // Failed on InterruptInitialize or CreateThread.  Bail.
            COM_Deinit(pSerialHead);
            return(NULL);
        }

    }

}
这个限制开关应该就是开不开MDD层的线程,看了应该是不开的,因为设置有pSerObj->BindFlags = THREAD_IN_PDD;  
所以SerialDispatchThread线程(这个线程是MDD层的)不会被启动起来.
 
 
 

回复

79

帖子

0

TA的资源

一粒金砂(初级)

28
 
再看PDD层的一个线程

DWORD CPdd6410Uart::ThreadRun()
{
    while ( m_hISTEvent!=NULL && !IsTerminated() )
    {
        if ( WaitForSingleObject( m_hISTEvent, m_dwISTTimeout) == WAIT_OBJECT_0)
        {
            m_HardwareLock.Lock();   
        
            while ( !IsTerminated() )
            {
                DWORD dwData = ( GetInterruptStatus() & (S6410UART_INT_RXD | S6410UART_INT_TXD | S6410UART_INT_ERR | S6410UART_INT_MODEM) );
                if (dwData)
                {
                    DEBUGMSG(ZONE_THREAD, (TEXT(" CPdd6410Uart::ThreadRun Active INT=%x\r\n"), dwData));

                    DWORD interrupts=NULL;

                    if ((dwData & S6410UART_INT_RXD)!=0)
                    {
                        interrupts |= INTR_RX;
                    }
                    if ((dwData & S6410UART_INT_TXD)!=0)
                    {
                        interrupts |= INTR_TX;
                    }
                    if ((dwData & S6410UART_INT_ERR)!=0)
                    {
                        interrupts |= INTR_LINE | INTR_RX;
                    }
                    if ((dwData & S6410UART_INT_MODEM)!=0)
                    {
                        interrupts |=INTR_MODEM;
                    }
                    
                    NotifyPDDInterrupt( (INTERRUPT_TYPE)interrupts );
                    
                    ClearInterrupt(dwData);
                }
                else
                {
                    break;
                }
            }

            m_HardwareLock.Unlock();   

            InterruptDone(m_dwSysIntr);
        }
        else
        {
            DEBUGMSG(ZONE_THREAD,(TEXT(" CPdd6410Uart::ThreadRun timeout INT=%x,MASK=%d\r\n"),m_pReg6410Uart->Read_UINTP()/*m_pReg6410Uart->Read_UINTSP()*/, m_pReg6410Uart->Read_UINTM()) );
            ASSERT(FALSE);
        }
    }

    return 1;
}

这个应该是真正的等待硬件中断的线程,等待到了,通过NotifyPDDInterrupt( (INTERRUPT_TYPE)interrupts );通知MDD的处理程序SerialEventHandler







  1. extern "C" VOID SerialEventHandler(PVOID pMddHead);

  2. BOOL CSerialPDD::NotifyPDDInterrupt(INTERRUPT_TYPE interruptType)
  3. {
  4.     m_InterruptLock.Lock();
  5.     // The interrupt is define as Bit event.
  6.     m_dwInterruptFlag |= (DWORD)interruptType;
  7.     m_InterruptLock.Unlock();
  8.    
  9.    
  10.     if (IsPowerResumed ( ))
  11.     {
  12.         if (m_lOpenCount)
  13.         { // If application is opened.
  14.             EventCallback( EV_POWER );
  15.         }
  16.         else
  17.         {
  18.             if (GetModemStatus() & MS_RLSD_ON)
  19.                 CeEventHasOccurred (NOTIFICATION_EVENT_RS232_DETECTED, NULL);
  20.         }
  21.     }
  22.    
  23.    
  24.     m_InterruptLock.Lock();
  25.    
  26.    
  27.    
  28.     SerialEventHandler(m_pMdd);
  29.    
  30.    
  31.    
  32.    
  33.     m_InterruptLock.Unlock();
  34.     return TRUE;
  35. }

复制代码


//==================================
MDD层的SerialDispatchThread线程(这个线程被限制没被启动起来)也会调MDD的处理函数SerialEventHandler



  1. static DWORD WINAPI
  2. SerialDispatchThread(
  3.                     PVOID   pContext    /* @parm [IN] Pointer to main data structure. */
  4.                     )
  5. {
  6.     PHW_INDEP_INFO      pSerialHead    = (PHW_INDEP_INFO)pContext;
  7.     ULONG               WaitReturn;

  8.     DEBUGMSG (ZONE_THREAD, (TEXT("Entered SerialDispatchThread %X\r\n"),
  9.                             pSerialHead));

  10.     // It is possible for a PDD to use this routine in its private thread, so
  11.     // don't just assume that the MDD synchronization mechanism is in place.
  12.     if ( pSerialHead->pHWObj->BindFlags & THREAD_IN_MDD ) {
  13.         DEBUGMSG(ZONE_INIT,
  14.                  (TEXT("Spinning in dispatch thread %X %X\n\r"), pSerialHead, pSerialHead->pHWObj));
  15.         while ( !pSerialHead->pDispatchThread ) {
  16.             Sleep(20);
  17.         }
  18.     }

  19.     /* Wait for the event that any serial port action creates.
  20.      */
  21.     while ( !pSerialHead->KillRxThread ) {
  22.         DEBUGMSG (ZONE_THREAD, (TEXT("Event %X, %d\r\n"),
  23.                                 pSerialHead->hSerialEvent,
  24.                                 pSerialHead->pHWObj->dwIntID ));
  25.         WaitReturn = WaitForSingleObject(pSerialHead->hSerialEvent, INFINITE);


  26.         SerialEventHandler(pSerialHead);
  27.         
  28.         
  29.         
  30.         
  31.         
  32.         InterruptDone(pSerialHead->pHWObj->dwIntID);
  33.     }

  34.     DEBUGMSG (ZONE_THREAD, (TEXT("SerialDispatchThread %x exiting\r\n"),
  35.                             pSerialHead));
  36.     return(0);
  37. }


复制代码





 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

29
 
不知道我这样理解对不对,手上没实际的环境还真拿不准.希望高手解惑!!!
 
 
 

回复

78

帖子

0

TA的资源

一粒金砂(初级)

30
 
HANDLE
COM_Init(
        ULONG   Identifier
        )
{



// OK, now that everything is ready on our end, give the PDD
    // one last chance to init interrupts, etc.
    (void) pSerialHead->pHWObj->pFuncTbl->HWPostInit( pHWHead );

    DEBUGMSG (ZONE_INIT | ZONE_FUNCTION, (TEXT("-COM_Init\r\n")));
    return(pSerialHead);
}

//=====================================================================


  1. //
  2. BOOL
  3. SerPostInit(
  4.            PVOID   pHead // @parm PVOID returned by HWinit.
  5.            )
  6. {
  7.     CSerialPDD * pSerialPDD    = (CSerialPDD *)pHead;

  8.     DEBUGMSG (ZONE_INIT,(TEXT("+SL_PostInit, 0x%X\r\n"),  pSerialPDD ));
  9.     if ( pSerialPDD ) {
  10.          pSerialPDD->PostInit();
  11.     }
  12.     DEBUGMSG (ZONE_INIT,(TEXT("-SL_PostInit, 0x%X\r\n"),  pSerialPDD ));
  13.     return(TRUE);
  14. }

复制代码

//=========================================================================



  1. #define MAX_RETRY 0x1000
  2. void CPdd6410Uart::PostInit()
  3. {
  4.     DWORD dwCount=0;
  5.     m_HardwareLock.Lock();
  6.     m_pReg6410Uart->Write_UCON(0); // Set to Default;
  7.     DisableInterrupt(S6410UART_INT_RXD | S6410UART_INT_TXD | S6410UART_INT_ERR | S6410UART_INT_MODEM);
  8.     // Mask all interrupt.
  9.     while ((GetInterruptStatus() & (S6410UART_INT_RXD | S6410UART_INT_TXD | S6410UART_INT_ERR | S6410UART_INT_MODEM))!=0 && dwCount
  10.     { // Interrupt.
  11.         InitReceive(TRUE);
  12.         InitLine(TRUE);
  13.         ClearInterrupt(S6410UART_INT_RXD | S6410UART_INT_TXD | S6410UART_INT_ERR | S6410UART_INT_MODEM);
  14.         dwCount++;
  15.     }
  16.     ASSERT((GetInterruptStatus() & (S6410UART_INT_RXD | S6410UART_INT_TXD | S6410UART_INT_ERR | S6410UART_INT_MODEM))==0);
  17.     // IST Start to Run.
  18.     m_HardwareLock.Unlock();
  19.     CSerialPDD::PostInit();
  20.     CeSetPriority(m_dwPriority256);
  21.    
  22.    
  23.    
  24.    
  25. #ifdef DEBUG
  26.     if ( ZONE_INIT )
  27.     {
  28.         m_pReg6410Uart->DumpRegister();
  29.     }
  30. #endif





  31.     ThreadStart();  // Start IST.  //2009--10--10  XQH  不知道开的是那个线程!!!MDD?PDD?
  32.    
  33.    
  34.    
  35.    
  36. }


复制代码


 
 
 

回复

78

帖子

0

TA的资源

一粒金砂(初级)

31
 
pSerObj->BindFlags = THREAD_IN_PDD;     // PDD create thread when device is first attached.

    pSerObj->dwIntID = DeviceArrayIndex;   // Only it is useful when set set THREAD_AT_MDD. We use this to transfer DeviceArrayIndex


    pSerObj->pFuncTbl = (HW_VTBL *) &IoVTbl; // Return pointer to appropriate functions
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

32
 
define in  public/common/oak/inc/serhw.h

// Define for BindFlags.  Note we only have two mutually exclusive values,
// but this is a bitfield so we may add others later
#define     THREAD_IN_PDD   0   /* PDD is responsible for Intr Thread */
#define     THREAD_AT_INIT  1   /* MDD Spins Intr Thread at init time */
#define     THREAD_AT_OPEN  2   /* MDD Spins Intr Thread at open time */

// The next define is only for compares.  NEVER set both OPEN and INIT for thread
#define     THREAD_IN_MDD (THREAD_AT_INIT | THREAD_AT_OPEN)

#ifdef USE_NEW_SERIAL_MODEL
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

33
 
好帖 顶
 
 
 

回复

86

帖子

0

TA的资源

一粒金砂(初级)

34
 


if ( !InterruptInitialize(pSerialHead->pHWObj->dwIntID,
                              pSerialHead->hSerialEvent,
                              NULL,
                              0) )
{
        DEBUGMSG(ZONE_INIT | ZONE_ERROR,
                 (TEXT("Error initializing interrupt\n\r")));
        return(FALSE);
    }

    InterruptDone(pSerialHead->pHWObj->dwIntID);



觉得上面这段代码的绑定应该也是毫无意义的.pSerialHead->pHWObj->dwIntID又不是个允许的系统中断号,再说就算这个是个合法的系统中断号,它跟硬件中断号对应起来没?就没见用KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &ddi.dwIrq, sizeof(UINT32), &ddi.dwSysintr, sizeof(UINT32), NULL))这样的函数去通过硬件中断号请求合法的系统中断号.
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

35
 
在串口驱动中,HWOBJ结构中的函数实现了对串口硬件的操作,并在MDD层被调用。可以说,该结构描述了串口设备的所有特性,先来介绍一下该结构,具体定义如下:
typedef struct __HWOBJ
{  
    ULONG BindFlags;  
    DWORD dwIntID;  
    PHW_VTBL pFuncTbl;
} HWOBJ, *PHWOBJ;
BindFlags:用于控制MDD层如何来处理IST,具体值如下:           

                       THREAD_IN_PDD:MDD层不处理,中断在PDD层处理。            

                       THREAD_AT_INIT:在驱动初始化的时候,MDD层启动IST。            

                       THREAD_AT_OPEN:在驱动被Open的时候,MDD层启动IST。

dwInitID: 系统的中断号 pFuncTbl: 指向一个PHW_VTBL结构,该结构中包含一个函数指针列表,这些函数指针指向串口硬件操作函数,用于操作串口。


[url=http://www.j2medev.com/windowsmobile/ShowArticle.asp?ArticleID=5382][/url]
 
 
 

回复

62

帖子

0

TA的资源

一粒金砂(初级)

36
 
googleman的一篇相关文章

[url=http://topic.eeworld.net/u/20090206/11/547cd990-f62e-4edf-81dd-581827dd50ff.html?seed=1984790033&r=60334044#r_60334044][/url]
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

37
 
需要仔细理解
慢慢消化!
 
 
 

回复

44

帖子

0

TA的资源

一粒金砂(初级)

38
 
望高手解释解释是不是我理解的这样!
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

39
 
今天把PUBLIC的代码修改了一下,真的不RUN--StartDispatchThread( ).
 
 
 

回复

82

帖子

0

TA的资源

一粒金砂(初级)

40
 
今天在PUBLIC里面加了调试消息,看执行的过程,应该是没有启动StartDispatchThread( )的,COM_INIT( )和COM_OPEN( )都不会去执行StartDispatchThread( )函数的.因为pSerObj->BindFlags = THREAD_IN_PDD;开关限制住了.
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表