OAL bit by bit (ii)

Source: Internet
Author: User

As the CE help document says, creating OAL is a very complex task, and the usual approach is to replicate the original OAL code of the same platform and modify it to accommodate the special requirements of the platform. That is to say, for a platform without special requirements, it is sufficient to copy the OAL code of the original same platform. Because of the complexity of OAL in this article, I only explain the common parts.

First, the implementation of ISR

The concept of 1.ISR

The ISR (Interrupt service routine) is a program that handles IRQs (interrupt request line). Windows CE uses an ISR to process all IRQ requests. When an interrupt occurs, the kernel's exception handler invokes the kernel ISR, the kernel ISR disables all interrupts with the same priority and lower priority, and then invokes the registered OAL ISR program, which has the following characteristics:

Perform minimal interrupt processing, which means that the hardware that is capable of testing and replying to interrupts can be inspected and responded to, and more processing is left to IST (Interrupt service thread).

Returns the interrupt ID (most of the interrupt ID is predefined) when the ISR completes.

2. ISR structure of the X86 platform

The ISR for the X86 platform is stored in%_WINCEROOT%\PUBLIC\COMMON\OAK\CSP\I486\OAL\FWPC.C and the function is named PERPISR. Here's an analysis of the main code for this function:

ULONG perpisr (void)
{
ULONG ulret = Sysintr_nop;///return value, both interrupt ID (prefixed by sysintr_)
Uchar Uccurrentinterrupt; The current interrupt number,
if (fintrtime)//////fintrtime, is used to test the delay time of the SR and IST, and the test tool is ILTiming.exe.
.....
Uccurrentinterrupt = Picgetcurrentinterrupt ();////returns the current interrupt IRQ
///irq0,irq0 interrupts the system clock (systems tick), see "Second, implement system clock"
if (uccurrentinterrupt = = Intr_timer0)
...
if (dwrebootaddress)////requires a reboot
Reboothandler (),
...
if (uccurrentinterrupt = = INTR_RTC)////irq8,real-time clock interrupts
...
Else if (uccurrentinterrupt <= intr_maximum)///If the interrupt is less than intr_maximum
{
Ulret = Nkcallintchain (uccurrentint Errupt); Call the interrupt chain
if (Ulret = sysintr_chain)///If the break chain does not contain interrupts
////convert between IRQ and SYSINTR, this function returns the SysIntr
Ulret of the IRQ corresponding to OEMTRANSLATEIRQ (Uccurrentinterrupt);
.....
Picenableinterrupt (Uccurrentinterrupt, FALSE);///enable all interrupts except the current interrupt
}///else if
Oemindicateintsource (ulret ); Notifies the kernel that a sysintr interrupt has occurred
}

It is not difficult to see from the above code that the task of the ISR is to return the interrupt ID prefixed with "sysintr_" and return SYSINTR_NOP if no further ist is required.

3. Interrupt Registration Step

Refer to the code for the X86 platform and interrupt the registration steps as follows:

Associate SysIntr and IRQ with Setup_interrupt_map macros. Constants prefixed with "Sysintr_" are used by the kernel to uniquely identify the hardware in which the interrupt occurred. Some sysintr,oem are predefined in the Nkintr.h file to customize SysIntr in Oalintr.h files.

The hardware interrupt number and ISR are associated with the Hookinterrupt function. The hardware interrupt number here is the physical interrupt number, not the logical interrupt number IRQ. The Hookinterrupt function was called at the end of the Initpics function (which is located in the same file as the ISR), as follows:

for (i = 64; i < 80; i++)
HookInterrupt(i, (void *)PeRPISR); ///用ISR关联16个中断号

4. Interrupt processing steps

Call the InterruptInitialize function to associate SysIntr and IST, specifically the event that the associated IST waits on. Typically written in the driver as follows:

hEvent = CreateEvent(...) ///创建一个事件对象
InterruptInitialize(SYSINTR_SERIAL, hEvent, ...) ///关联一个串口中断ID和这个事件
hThd = CreateThread(..., MyISTRoutine, hEvent, ...) ///创建一个线程(IST)
CeSetThreadPriority(hThd, 152); ///提高此线程的优先级

IST performs I/O operations, the general IST is written as follows:for(;;) ///驱动程序一直处于服务状态
{
WaitForSingleObject(hEvent, INFINITE); ////无限等待事件
...... //// I/O操作
InterruptDone(InterruptId); ///结束当前中断处理
}

Data transfer between ISR and IST

If we want to read data from a device frequently and have very little per read, then calling ist on every read will degrade performance. As a solution, the ISR can do the read work (stored to the buffer) and read from the IST to the buffer after the buffer is full. Because the ISR runs in kernel mode and the IST runs in user mode, IST cannot easily access the ISR buffer, providing a solution for this CE (see the help document titled "Passing Data between an ISR and ist"), You can also ask for the Tenkine Embedded Development Forum.

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.