Wince external interrupt control LED detailed explanation dynamic application

Publisher:AmpouleLatest update time:2016-05-12 Source: eefocusKeywords:Wince Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
This example is based on S3C2440, WINCE5.0

1. Interrupts are divided into two categories: internal interrupts and external interrupts.

          External interrupt: An interrupt caused by an external device. These external interrupts are generated through the interrupt pins in GPIO. S3C2440 has 24 external interrupts, and the related registers are as follows:

               EXTINT0-EXTINT2: Three registers set the trigger mode of EINT0-EINT23.

                EINTFLT0-EINTFLT3: Control the filter clock and filter width.

                EINTPEND: Interrupt Pending Register

                 EINTMASK: Interrupt mask register

         Internal interrupt: Internal interrupt is an interrupt generated by the internal device of CPU, such as timer interrupt, USB interrupt, UART interrupt, etc. The related registers are as follows:

                 SUBSRCPND: Secondary interrupt pending register.

                 INTSUBMSK: Secondary interrupt mask register.

                  INTMOD: Interrupt mode register

                 PRIORITY : Priority register

                  SRCPND: Interrupt Pending Register

                 INTMSK: Interrupt mask register.

               INTPND: After an interrupt occurs, there may be several positions set to 1 in SRCPND. The priority arbiter will select the highest priority interrupt and then set the corresponding position in INTPND to 1. Only one position is set to 1 at the same time.

                 Here we should pay attention to the difference between primary interrupt and secondary interrupt. The setting of secondary interrupt is more complicated than primary interrupt.
2. WINCE interrupt mechanism: ISR and IST

                WinCE interrupts are generally divided into two parts: ISR and IST. I won't go into detail here about what ISR and IST are, but you can find a lot of them online. Simply put, ISR is responsible for converting IRQ into a logical interrupt and returning it to the kernel; IST is responsible for the logical processing of the interrupt.

3. WINCE interrupt example: external button interrupt control LED light

              (1) Create a simple stream driver template. This step can be created manually or through the "Windows CE Developer Samples" -> "Windows CE 5.0 Embedded Development Labs" -> "DrvWiz.exe" framework. It is recommended to use the latter, which is simple, fast and less prone to errors. Here the project is named LED, that is, the generated DLL is LED_DLL.

               (2) Fill in the function body. Here we mainly introduce two functions related to interrupts:

                               DWORD LED_Init( LPCTSTR pContext) //Driver initialization function, mainly for memory allocation and interrupt initialization function call.

                               DWORD WINAPI LED_IST( LPVOID lpvParam ) //Interrupt processing thread, i.e. IST, performs interrupt processing here.

                               DWORD InitInterrupt( void ) //Interrupt initialization function, including setting of interrupt registers, creation and initialization of events and threads, etc.

                    First, let's introduce DWORD InitInterrupt( void ), the code is as follows:

DWORD InitInterrupt( void ) 

HANDLE g_htIST; //Thread return handle
BOOL fRetVal; 
DWORD dwThreadID; 
printfmsg((TEXT("come into the setup interrupt!!!\r\n")));

//Initialize external interrupt 8
      s2440IO->rGPGCON &= ~(0X3);
      s2440IO->rGPGCON |= 0X2; //Set to interrupt mode
      s2440IO->rEXTINT1 &= ~(0X0f);
      s2440IO->rEXTINT1 |= 0XA; //Falling edge trigger, enable filter
      s2440IO->rEINTMASK &= ~(1<<8); //Turn on interrupt 8
      s2440IO->rEINTPEND |= (1<<8); //Clear interrupt
      //GPIO set-LED
      s2440IO->rGPBCON = (s2440IO->rGPBCON &~(3 << 14)) | (1<< 14); // GPB7 == OUTPUT.
      s2440IO->rGPBCON = (s2440IO->rGPBCON &~(3 << 16)) | (1<< 16); // GPB8 == OUTPUT.


   s2440INTR->rINTMSK &= ~(0x20); //Unmask external interrupt 8
   s2440INTR->rSRCPND |= (0x20); //Clear external interrupt 8
   s2440INTR->rINTPND |=0X20; //Clear external interrupt, i.e. initialize
// Create an event 
g_hevInterrupt
= CreateEvent(NULL, FALSE, FALSE, NULL); 
if(!g_hevInterrupt) return -10;

// Have the OAL Translate the IRQ to a system irq 
//Convert the physical interrupt IRQ to a logical interrupt
fRetVal = KernelIoControl( IOCTL_HAL_TRANSLATE_IRQ, 
         &dwIrq, 
         sizeof( dwIrq ), 
         &g_dwSysInt, 
         sizeof( g_dwSysInt ), 
         NULL );

  
if( !fRetVal )
{ return -1 } // Create a thread
  
that waits for signaling  g_htIST = CreateThread(NULL,// CE Has No Security          0, // No Stack Size          ThreadIST,// Interrupt Thread          NULL,// No Parameters          CREATE_SUSPENDED,// Create Suspended until we are done  & dwThreadID         // Thread Id          );  if( !g_htIST ) {return -1 } // Set the thread priority to real time  int m_nISTPriority = 7;  if(!CeSetThreadPriority( g_htIST, m_nISTPriority))  { return -1 } // Initialize the interrupt  INFINITE);  //The interruption will cause IST to run and handle the interruption task if ( !InterruptInitialize(g_dwSysInt, g_hevInterrupt, NULL, 0) ) {return -1; } ResumeThread( g_htIST );        printfmsg((TEXT("*leave the setup interrupt!!!\r\n")));






















return 1; 

      Let me briefly talk about the process of initializing interrupts. First, initialize the relevant interrupt registers. Here I use external interrupt 8. The next step is to create an event to associate external interrupt 8 with the IST thread. In IST, dwStatus = WaitForSingleObject(g_hevInterrupt, INFINITE) is used to wait for the interrupt to occur. Then use KernelIoControl( IOCTL_HAL_TRANSLATE_IRQ, 
         &dwIrq, sizeof( dwIrq ), &g_dwSysInt, sizeof( g_dwSysInt ), NULL ); to convert the physical interrupt IRQ into a logical interrupt. This is for the kernel. Next, create an interrupt service thread: g_htIST = CreateThread(NULL,// CE Has No Security 
        0, // No Stack Size 
        ThreadIST,// Interrupt Thread 
        NULL,// No Parameters 
        CREATE_SUSPENDED,// Create Suspended until we are done 
        &dwThreadID // Thread Id 
        );

      After all these are done, you can initialize the interrupt.

     // Initialize the interrupt 
      // Initialize the interrupt and associate the logical interrupt number with the event, that is, the event is
      triggered when the interrupt occurs. // In the interrupt service thread IST, it will wait for the event to occur, that is, WaitForSingleObject(g_hevInterrupt, INFINITE); 
     // Thus, the interruption will cause IST to run and process the interrupt task
   InterruptInitialize(g_dwSysInt, g_hevInterrupt, NULL, 0) This function associates the logical interrupt number corresponding to the physical interrupt with the event.

    At this point, the entire initialization is done. The function calling order is not unique, but it is enough to just clarify the calling order of each function.

    DWORD TST_Init( LPCTSTR pContext)
{
printfmsg((TEXT("come into the init!!!\r\n")));


          // GPIO Virtual alloc
s2440IO = (volatile IOPreg *) VirtualAlloc(0,sizeof(IOPreg),MEM_RESERVE, PAGE_NOACCESS);
if(s2440IO == NULL) {
   printfmsg((TEXT("For s2440IO: VirtualAlloc faiLED!\r\n ")));
}
else {
   if(!VirtualCopy((PVOID)s2440IO,(PVOID)(IOP_BASE),sizeof(IOPreg),PAGE_READWRITE | PAGE_NOCACHE )) {
    printfmsg((TEXT("For s2440IO: Virtualcopy faiLED!\r \n")));
   }
}

   s2440INTR = (volatile INTreg *) VirtualAlloc(0,sizeof(INTreg ),MEM_RESERVE, PAGE_NOACCESS);
if(s2440INTR == NULL) {
   printfmsg((TEXT("For s2440INTR: VirtualAlloc faiLED!\r\n!\r\n ")));
}
else {
   if(!VirtualCopy((PVOID)s2440INTR,(PVOID)(INT_BASE),sizeof(INTreg),PAGE_READWRITE | PAGE_NOCACHE )) {
    printfmsg((TEXT("For s2440INTR: Virtualcopy faiLED!\r \n!\r\n")));
   }

   InitInterrupt();
   return 0x1234;

}
    This function is called when the driver is loaded, so the initialization tasks should be placed here.

     That's all about interrupts. This is a method of dynamically applying for interrupts, which is relatively complicated. In fact, you don't need to use the dynamic application method at all, and it is not recommended. Static application is a good method and is relatively simple. I will explain it in more detail in the following article.

Keywords:Wince Reference address:Wince external interrupt control LED detailed explanation dynamic application

Previous article:Problems encountered when mini2440 key interrupt control LED lights
Next article:STM32 external interrupt control

Recommended ReadingLatest update time:2024-11-23 08:34

Design of Intelligent Vehicle Instrument Based on WinCE
  introduction   With the development of high-performance electronic display technology, the degree of electronicization of automobile instruments is getting higher and higher. High-tech products such as multifunctional all-electronic display instruments, head-up display instruments, car navigation systems, and drivi
[Microcontroller]
Design of Intelligent Vehicle Instrument Based on WinCE
A low-level S3c2416 wince SD eboot assembly error
C:WINCE500PLATFORMSMDK2416srcbootloaderEboot.Whimorystartup.s(332) : error A0034: undefined symbol: _undef_loc_label_ You really don’t know what it is unless you look carefully, but you should know it later if you look at the logic. There is a problem with the 20 in %B20. The code does not have a 20 label at all.
[Microcontroller]
Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号