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.
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
- Naxin Micro and Xinxian jointly launched the NS800RT series of real-time control MCUs
- How to learn embedded systems based on ARM platform
- Summary of jffs2_scan_eraseblock issues
- Application of SPCOMM Control in Serial Communication of Delphi7.0
- Using TComm component to realize serial communication in Delphi environment
- Bar chart code for embedded development practices
- Embedded Development Learning (10)
- Embedded Development Learning (8)
- Embedded Development Learning (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Intel promotes AI with multi-dimensional efforts in technology, application, and ecology
- ChinaJoy Qualcomm Snapdragon Theme Pavilion takes you to experience the new changes in digital entertainment in the 5G era
- Infineon's latest generation IGBT technology platform enables precise control of speed and position
- Two test methods for LED lighting life
- Don't Let Lightning Induced Surges Scare You
- Application of brushless motor controller ML4425/4426
- Easy identification of LED power supply quality
- World's first integrated photovoltaic solar system completed in Israel
- Sliding window mean filter for avr microcontroller AD conversion
- What does call mean in the detailed explanation of ABB robot programming instructions?
- STMicroelectronics discloses its 2027-2028 financial model and path to achieve its 2030 goals
- 2024 China Automotive Charging and Battery Swapping Ecosystem Conference held in Taiyuan
- State-owned enterprises team up to invest in solid-state battery giant
- The evolution of electronic and electrical architecture is accelerating
- The first! National Automotive Chip Quality Inspection Center established
- BYD releases self-developed automotive chip using 4nm process, with a running score of up to 1.15 million
- GEODNET launches GEO-PULSE, a car GPS navigation device
- Should Chinese car companies develop their own high-computing chips?
- Infineon and Siemens combine embedded automotive software platform with microcontrollers to provide the necessary functions for next-generation SDVs
- Continental launches invisible biometric sensor display to monitor passengers' vital signs
- RF circuit PCB design
- 10 FAQs on Green Electronics
- Development and application of AC variable frequency speed regulation
- How to judge whether the operational amplifier of this circuit is in the amplification state
- Xunwei iTOP3399 development board QT system PCIE 4G transplantation-compilation program
- Live Review: Typical Applications of ADI Switch/Multiplexer Series Products on July 21
- Anxinke NB-IoT module evaluation - sleep power test
- RF ATZB-900-B0R 1000 yuan
- MicroPython official English forum will be moved to github
- EEWORLD University Hall----RF Analog Circuits Yang Yumei, University of Electronic Science and Technology of China