Detailed description of Wince external interrupt control LED-Dynamic Application

Source: Internet
Author: User

This instance is based on S3C2440, wince5.0

1. There are two types of interruptions: Internal interruption and external interruption.

External interruption: the interruption caused by external devices. These external interruptions are generated through the interrupt pin in gpio. The S3C2440 has 24 External interruptions. The related registers are as follows:

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

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

Eintpend: interrupt pending register

Eintmask: Interrupt Mask register

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

Subsrcpnd: the Register for secondary interrupt suspension.

Intsubmsk: the secondary interrupt shielding register.

Intmod: interrupt mode register

Priority: Priority register

Srcpnd: interrupt pending register

Intmsk: the interrupt shielding register.

Intpnd: after an interruption occurs, srcpnd has a location of 1, which may be several. These interruptions will be selected by the priority arbitration server with the highest priority, and then the corresponding position of intpnd is 1, only one digit at a time is 1.

Pay attention to the difference between the level-1 interruption and the level-1 interruption. The configuration of level-1 interruption is more complex than that of level-1 interruption.
2. wince interrupt mechanism: ISR and ist

The wince interrupt is divided into two major parts: ISR and ist. The specific ISR and ist are not detailed here. Simply put, ISR is responsible for converting IRQ into logical interruptions and returning it to the kernel. Ist is responsible for the logical processing of interruptions.

3. wince interrupt instance: LED lamp with external button interrupt control

(1) create a simple flow driver template, which can be created manually, you can also use the "Windows CE developer samples"-> "Windows CE 5.0 embedded development labs"-> "drvwiz.exe" framework. We recommend that you use the latter, which is simple, fast, and error-free. Here the project is named led, that is, the produced DLL is led_dll.

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

DWORD led_init (lpctstr pcontext) // driver initialization function, mainly used to allocate memory and call the interrupt initialization function.

DWORD winapi led_ist (lpvoid lpvparam) // Interrupt Processing thread, that is, ist, where interrupt processing is performed.

DWORD initinterrupt (void) // interrupt initialization function, including interrupt register settings, event and thread creation, initialization, etc.

First, we will introduce DWORD initinterrupt (void). The Code is as follows:

DWORD initinterrupt (void)
{
Handle g_htist; // handle returned by the thread
Bool fretval;
DWORD dwthreadid;
Printfmsg (text ("*************** come into the setup interrupt !!! * ******************* \ R \ n ")));

// Initialize External Interrupt 8
S2440io-> rgpgcon & = ~ (0x3 );
S2440io-> rgpgcon | = 0x2; // you can specify the interrupt mode.
S2440io-> rextint1 & = ~ (0x0f );
S2440io-> rextint1 | = 0xa; // The Descent edge is triggered to enable the filter.
S2440io-> reintmask & = ~ (1 <8); // open interrupt 8
S2440io-> reintpend | = (1 <8); // clear the interrupt
// Gpio settings-led
S2440io-> rgpbcon = (s2440io-> rgpbcon &~ (3 <14) | (1 <14); // gpb7 = output.
S2440io-> rgpbcon = (s2440io-> rgpbcon &~ (3 <16) | (1 <16); // gpb8 = output.

S2440intr-> rintmsk & = ~ (0x20); // cancel shielding of External Interrupt 8
S2440intr-> rsrcpnd | = (0x20); // clear external interrupt 8
S2440intr-> rintpnd | = 0x20; // clear the external interrupt, that is, initialize
// Create an event
// 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 physical interrupt IRQ to 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
// Create an interrupt service thread ist
G_htist = createthread (null, // ce has no security
0, // No stack size
Threadist, // interrupt thread
Null, // No Parameters
Create_suincluded, // create susponded until we are done
& Dwthreadid // thread ID
);
If (! G_htist)
{Return-1}
// Set the thread priority to real time
// Set the thread priority
Int m_nistpriority = 7;
If (! Cesetthreadpriority (g_htist, m_nistpriority ))
{Return-1}
// Initialize the interrupt
// Initialize the interrupt and associate the logical interrupt number with the event, that is, the event is triggered when the interrupt is generated.
// Wait for the event to occur in the interrupted service thread ist, that is, waitforsingleobject (g_hevinterrupt, infinite );
// This causes the IST to run and process the interrupted 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's briefly describe the process of Initializing an interrupt. The first step is to initialize the relevant interrupt register. Here I use the External Interrupt 8. Next, create an event to associate the External Interrupt 8 and ist threads. In ist, dwstatus = waitforsingleobject (g_hevinterrupt, infinite) is used to wait for the interruption. Then use kerneliocontrol (ioctl_hal_translate_irq,

& Dwirq, sizeof (dwirq), & g_dwsysint, sizeof (g_dwsysint), null); converts physical interrupt IRQ to logical interrupt. This is for the kernel. Then we need to create the service interruption thread: g_htist = createthread (null, // ce has no security

0, // No stack size
Threadist, // interrupt thread
Null, // No Parameters
Create_suincluded, // create susponded until we are done
& Dwthreadid // thread ID
);

After completing these steps, 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 is generated.
// Wait for the event to occur in the interrupted service thread ist, that is, waitforsingleobject (g_hevinterrupt, infinite );
// This causes the IST to run and process the interrupted task.
Interruptinitialize (g_dwsysint, g_hevinterrupt, null, 0) This function associates the logical interrupt number corresponding to the physical interrupt with the event.

The entire Initialization is done here. The function call sequence is not unique, but you only need to clarify the call sequence 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 inregulatory *) virtualalloc (0, sizeof (inregulatory), 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 (inregulatory), 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 we need to put the initialization task here.

There are so many parts related to the interruption, which is a complicated method for dynamically applying for interruption. In fact, you do not need to apply dynamically, and this method is not recommended. Static application is a good method and is relatively simple. The following articles will be further explained.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.