Windows Embedded Compact 7 is a popular OS being used in low power embedded systems. Embien, working from its early iterations from 4.2 to latest 2013, has ported the same on to NXP’s iMx 6UL based development platforms. This blog demonstrates the Windows Embedded Compact 7 on iMx6 UltraLite with the video, show-casing our capability in porting such Operating systems to various processors and architectures.

Windows Embedded Compact 7

Windows Embedded Compact 7 more commonly known as WinCE 7 or WEC7 is the successor to the WinCE 6.0. Released on 2011, it is still one of the most popular versions of the Microsoft offerings for the embedded devices.

Some of the features of the OS include

  • Rich User Interface
  • Silverlight support
  • Support for Symmetric Multi processing (SMP)
  • Rich Media play back support
  • Complete Win95 based shell

In a WEC7, is still more sought after than its successor WEC2013 because of better licensing options and more importantly the availability of the Shell. From WEC2013, Microsoft removed the support for Windows 95 like Shell that forces the developer to offer an equivalent shell which involves a lot of effort. Further WEC 7 can be ported on the non-Thumb2 only devices too.

WinCE on NXP iMx6UL

Embien offers its expertise in Windows CE for porting the RTOS on to various platforms. One of the most popular low cost SoC of recent times from NXP stables is the iMx6UL. This processor has gained a good market share at low power low cost computing. Some of the features include

  • ARM® Cortex®-A7 @ 696 MHz, 128 KB L2 cache
  • Parallel LCD Display up to WXGA (1366×768)
  • 8/10/16/24-bit Parallel Camera Sensor Interface
  • 16-bit LP-DDR2, DDR3/DDR3L
  • 8/16-bit Parallel NOR FLASH / PSRAM
  • Dual-channel Quad-SPI NOR FLASH
  • 8-bit Raw NAND FLASH with 40-bit ECC
  • 2x MMC 4.5/SD 3.0/SDIO Port
  • 2x USB 2.0 OTG, HS/FS, Device or Host with PHY
  • Audio Interfaces include 3x I2S/SAI, S/PDIF Tx/Rx
  • 2x 10/100 Ethernet with IEEE 1588
  • 2x 12-bit ADC, up to 10 input channel total, with resistive touch controller (4-wire/5-wire)
  • Advanced Power Management
  • Partial PMU Integration

Many vendors offers different development boards for the same. Some of the popular platforms are

  • NXP – iMX 6 UltraLite EVK
  • Variscite – DART-6UL
  • Compu lab – SOM-iMX6UL
  • TechNexion’s PICO-IMX6 COM
  • iWave Systems – iW-RainboW-G18M-SM
  • Embedded Artists – iMX6 UltraLite COM Board

Embien has ported Windows Embedded Compact 7 (WEC7) on to the NXP iMx6UL supporting all the major peripherals. Below is a video demonstration of the port running on the Variscite DART-6UL platform.

 

A video of WEC7 running on NXP iMx6UL Platform.

About Embien: Embien Technologies is a leading service provider in the Embedded software domain. Our team has rich experience in working with various OS like Linux, Android, Windows CE, FreeRTOS, uC-OS, QNX etc. We have created various applications on top the WinCE systems such as HMI, Medical instrumentation displays, Smart Home control system etc. We have also enabled running legacy Windows Applications on top of latest hardware and software including emulation over Linux using technologies such as Mono, OpenNETCF etc.

 

Saravana Pandian Annamalai
27. October 2016 · Write a comment · Categories: ARM, Embedded Software, Technology · Tags: ,

With an understanding of ARM registers and Exception model, now we are ready to explore the ARM interrupt controllers. These are the modules that sit in between the interrupt sources (peripherals) and ARM cores deciding how to route the interrupts to.

The ARM core accepts only two input signals handling unscheduled interrupts from the external systems – nIRQ and nFIQ. If IRQ is asserted, the system enters IRQ mode as discussed earlier or if FIQ is asserted, FIQ mode is entered.

It is up to the ARM licences i.e SoC manufacturer to decide the mechanism to route the interpret signals to the core. There are many ways to implement the interrupt controllers each of which are discussed in detail in this blog.

Vendor Specific Model

In the early ARM implementations where there used to be only one core in general, the logic for this routing of interrupts to the core is done by the SoC manufacturer mostly based on their design philosophy. More likely there will be a set of following registers

  • RAW Interrupt Status register
  • Interrupt Enable Register
  • Interrupt Status Register
  • IRQ Priority Encoding
  • FIQ/IRQ Selection

Up on assertion of any interrupt line, the interrupt source is checked if it is configured as FIQ. If so, the signal is routed to the core immediately. If it is an IRQ interrupt, ARM interrupt status is updated. If multiple interrupts occur simultaneously, the priority is resolved between other pending interrupts and finally the core is given the interrupt signal.

The below diagram gives a model implementation for the Interrupt Controller by Freescale called the Interrupt Collector (ICOLL) used in Freescale/NXP iMx233/iMx28 series of MCUs.

Freescale Interrupt Collector

Vendor specific Interrupt Controller

Vectored Interrupt Controller – VIC

ARM itself came up with a model called Vectored Interrupt Controller (VIC). Sitting directly on the AMBA High Speed bus, the latency is significantly reduced. Being an early generation controller it supports 32 interrupt sources each of which can be routed to either FIQ or IRQ signals. A unique feature of VIC is that, as it name suggests, it supports 16 vectored interrupts. In this there are 16 registers where the address of the corresponding interrupt service routines (ISR) can be saved. Based on the priority, the VIC identifies the high priority interrupt and loads its ISR address to a register called VICVectAddr. The firmware can simply use a LDR PC instruction to jump to this ISR. This saves a lot of software effort in branching to the ISR there by reducing latency.

Interrupt Controller from ARM

Vectored Interrupt Controller (VIC)

But VIC supports only level sensitive interrupts that must remain active HIGH till the ISR services it. Thus for these reasons, many SoC designers preferred their own implementation rather than the VIC.

Generic Interrupt Controller – GIC

As processors evolved, soon the number of interrupts became quiet large and also it was not uncommon to have more than 1 core (either symmetric or asymmetric), there was a need for a more standardized way of handling interrupts.

ARM defines Generic Interrupt Controller that suits this need. Though vendors are still free to choose their own mechanism, GIC has become very popular and is almost present in all modern SoCs. It consists of primarily two components – Distributor and CPU interfaces. The primary functionalities of the same include

Distributor:

This is the peripheral facing component that is available as only one implementation (instance). It is responsible for managing interrupts in the whole system and decides priorities between them and routing mechanism of the same.

CPU Interfaces:

For each CPU core available, there is a corresponding CPU Interface present bridging the Distributor interface with the core. It implements the priority masking for the processor.

The below diagram explains the same.

 

ARM's Interrupt Controller for Multi-core SoCs

ARM Generic Interrupt Controller (GIC)

The interrupts are identified by unique ID and could be in any one of the following 4 states (as explained by the GIC Architecture Specification):

  • Inactive: An interrupt that is not active or pending.
  • Pending: An interrupt from a source to the GIC that is recognized as asserted in hardware or generated by software and is waiting to be serviced by a target processor.
  • Active: An interrupt from a source to the GIC that has been acknowledged by a processor, and is being serviced but has not completed.
  • Active and pending: A processor is servicing the interrupt and the GIC has a pending interrupt from the same source.

Based on the source, there are three major types of interrupts defined.

Shared Peripheral Interrupts – SPI: These interrupts sources are typically from different peripherals in the system. They can be routed to (i.e shared with) any one or more of the cores as per the requirement and will be handled suitably. For example, UART0 and UART1 interrupts could be SPI and configured in the Distributor to be routed to two available cores. Up on UART0 interrupt, the signal is routed to first available processor. If at that instance, UART1 interrupt is received, the distributor routes it to the other core for handling.

These are assigned Interrupt ID from 32 to 1019.

Private Peripheral Interrupts – PPI: There could be interrupts that are only specific to one processor. In such cases, they are routed to PPI of only that processor. For example in an asymmetric system with a Cortex A5 and Cortex M4, a Watchdog interrupt corresponding to A5 will be routed only to the A5 core. There might be no need to share it with the M4. Hence it will be routed as a PPI.

The interrupt ID is defined from 16 to 31.

Software Generated Interrupts – SGI: ARM defines interrupt IDs 0 through 15 specifically for Inter processor communication. It is possible a SGI can be routed to one or more processors through the Distributor.

The Interrupts 0 to 31 are banked by the distributor for each CPU Interface i.e. each processor sees them different and are identified by the CPUID. For example, PPI 16 could be pending in CPU0 but not in CPU1. Whereas, in case of the SPI, it will be same across the CPU’s as they are not banked.

Irrespective of all these, each core is provided signal through either nIRQ or nFIQ lines for interrupting program execution.

Nested Vectored Interrupt Controller – NVIC

While the above implementations are suitable for powerful processors, there is a need for specialized handling in microcontroller profiles that typically run in sub-100MHz speed and with few tens of kilobytes of RAM and flash. It is important to reduce the interrupt latency and to leverage the fact that the number of peripherals is less and hence fewer interrupt sources. For that, ARM defines a NVIC model for the Cortex-M implementations.

In Cortex-M implementation, the interrupt service routine addresses are to be provided in a set of consecutive addresses at offsets corresponding to the vector number. As soon as the interrupt signals are received, the NVIC finds the ISR corresponding to the highest priority interrupt and jumps to it.

The Cortex-M core accepts only nIRQ interrupt and there is no option for a FIQ.

With our understanding of hardware implementation, in the upcoming blogs, we will discuss software mechanism in handling interrupts in ARM architectures.

Saravana Pandian Annamalai
27. August 2015 · Write a comment · Categories: ARM, Embedded Software, Technology · Tags: ,

Continuing our series on interrupts, this blog will capture the ARM interrupt architecture along with the evolution of the same from the early ARMv4 to the latest ARMv8 models. A fair outline of overall flow, including the exception/ registers model, is given to aid the reader understand the principles behind the ARM interrupt architecture design.

ARM Instruction Set

ARM architecture has continuously evolved since its introduction. Beginning with ARMv4, architecture evolution is labeled with incremental values like ARMv5, ARMv6 till the latest ARMv8. There are additions and extensions that are labeled with a suffix like ARMv5TE or ARMv6K.

As with any RISC core, ARM supports very few instructions and is capable of executing them fast at a rate of 1 instruction per clock using techniques such as pipelining, branch prediction, caching etc.

Many RISC architectures define a set of instructions and encoding that will be executed by the processor. But ARM Architecture is an advanced design that supports different instruction sets that can be changed dynamically. Each of these instruction execution modes offer unique advantage like higher code density, support for Java execution etc. Few of the instruction sets supported are

ARM: The default mode that operates with fixed width (32-bit) instructions. Automatically changed to this mode when an interrupt/exception occurs.

Thumb: It is a 16-bit instruction set that can be used for higher code density. It is has limited set of instructions and registers compared to ARM mode, but can be advantageous if limited register manipulations are done.

Thumb2: Introduced in ARMv6T2, this brings the best of both worlds, by supporting mixed 16 bit and 32 bit instructions able to achieve very higher code density and performance. This has become popular that modern OS like Windows Embedded Compact has made this the default execution mode. Even Linux kernel supports compilation to Thumb2 mode.

Jazelle: Optimized for Java code execution.

SIMD: Single Instruction Multiple Data instruction set for better data manipulation.

There are other sets like VFP, Security extension etc that are not explained in this blog. It is interesting to note that these instructions sets can be interchangeably used as switching from one to another is as simple as setting one or more bits is a register, that can be accomplished by a single instruction.

With ARMv8, two higher level Execution States are introduced – AArch32 and AArch64. While the AArch32 is mostly similar to the instructions sets in the earlier architectures, AArch64 supports a single 64 bit instructions set and registers. It is possible to transition between these during exceptions by a process called Interprocessing.

ARM Processor Modes and Exception Levels

While the instruction sets define the type of instructions supported, ARM core supports multiple modes that defines how the access privilege, current exception taken etc. The processor modes supported are

Mode Description
User Mode with minimal access privilege. It is not possible to change to other modes from this mode. In an OS, generally the applications are executed in this mode
FIQ Entered up on an Fast Interrupt being received
IRQ Entered up on an Interrupt being received
Supervisor Same set of register visibility as in User mode but with higher privileges
Monitor Part of security extension that can be used during transition from a Secure Mode to Non-secure mode.
Abort Entered when there is an error accessing data memory(Data Abort) or instruction area (Prefetch abort)
Undefined Entered when a wrong instructions is executed
System Mode that has full privileges that can be used to configure the system. Usually the kernel operates in this mode in an OS.

Of these modes, except User mode, all others are said to be privileged modes. Usually the transition between these modes is done primarily with exceptions and in limited case, with instructions.

AArch64, introduces four Exception levels, represented by ELn, that is used to determine the level of privilege. EL0 is the least privileged while EL3 is the most. The recommended usage model for the same are:

ARMv8 Exception Model

Recommended usage of ARMv8 Exception Levels

 

It is key to remember that the AArch32 mode processor states are still usable when executing in that.

ARM Register Model

It is generally known that there are 16 general purpose registers (R0 through R12, R13 (Stack Pointer), LR (Link Register) and PC) and two Program Status Registers (CPSR and SPSR). But few of these registers are actually banked and different registers are available for different processor modes. The register bank in AArch32 state as given in ARMv8 TRM is given below:

Registers in ARM

Arm Register Banking

Based on the current processor mode, the registers are visible to software access. i.e. if the processor is in Supervisor mode, reading R13 will return SP_svc where as access to R13 will return SP_irq in IRQ mode. For FIQ mode, lot more registers are banked enabling fewer stack push/pops for faster interrupt processing. Also, since the FIQ vector is at the end of the vector table, the handler (ISR) can be directly placed at the FIQ vector address rather than having a branch to ISR instruction as in case of other exceptions.

In AArch64 mode, there are 31 64-bit general purpose registers labeled XL0 to XL30. XL30 is generally used as Procedure Link Register. None of these are banked. But there are few registers that are banked for each Execution level – Stack Pointer (SP), the Exception Link Register (ELR) and the Saved Process State Register (SPSR). To enable access of AArch32 registers from AArch64 state, the AArch32 registers are mapped to lease significant 32-bits of the AArch64 registers. The mapping of the same as given by ARM is as follows

  X0-X7 X8-X15 X16-X23 X24-X30
0 R0 R8_usr R14_irq R8_fiq
1 R1 R9_usr R13_irq R9_fiq
2 R2 R10_usr R14_svc R10_fiq
3 R3 R11_usr R13_svc R11_fiq
4 R4 R12_usr R14_abt R12_fiq
5 R5 R13_usr R13_abt R13_fiq
6 R6 R14_usr R14_und R14_fiq
7 R7 R13_hyp R13_und No Register

ARM Exceptions Model

In ARM architecture, anything that affects sequential flow of instructions is called an exception. For example, it could be an occurrence of an interrupt, access of wrong memory or even power-cycling the system. These exceptions are clearly defined along with the specific steps taken on an exception – typically involving change in processor mode and jumping to a vector address. Some of the defined exceptions are

 

Exception Description Entered Mode Vector Offset
Reset Entered on power on reset Supervisor mode 0x00
Undefined Instruction Invalid/Unimplemented instruction Undefined 0x04
Supervisor Call Usually by SWI/SVC instruction. Used for system call implementation Supervisor 0x08
Secure Monitor Call Usually by SMC/SMI instruction. Monitor 0x08
Prefetch Abort Invalid instruction memory access Abort 0x0C
Data Abort Invalid Data memory access Abort 0x10
IRQ Interrupt request to the core IRQ 0x18
FIQ FIQ request to core FIQ 0x1C

 

When any of these exceptions occurs in an ARM core, following set of sequences happens:

  • CPSR is copied to the SPSR of the mode being entered.
  • Processor mode is set to the new state
  • Whatever the existing instruction set being executed, it is changed to ARM state
  • Return address (of mode being left) is stored to the link register of the mode being entered
  • PC is set to the vector address corresponding to the entered exception

Now that the processor is in the new exception mode, the corresponding registers are banked. The software can choose to handle the exception as desired. Care should be taken that no registers are corrupted or lost, due to multiple or nested exceptions. Registers can be backed up in the stack.

To return back to the interrupted code, following operations can be done:

  • Restore the registers back to the original values (by popping from stack)
  • The above process can be done using a single instruction LDMFD^ if possible.

For AArch64, numerous exception classes are defined that are source of the exceptions like WFI, Illegal execution state, Misaligned PC Exception etc. The cause of exception can be obtained from the Exception Syndrome Register (ESR). The major happenings on an exception entry, as given by ARMv8 TRM,

  • The PE state is saved in the SPSR_ELx at the Exception level the exception is taken to.
  • The preferred return address is saved in the ELR_ELx at the Exception level the exception is taken to.
  • Execution moves to the target Exception level, and starts at the address defined by the exception vector.
  • The stack pointer register selected is the dedicated stack pointer register for the target Exception level.

To return from exception, an ERET instruction can be used. On executing the same:

  • PC is restored with the value held in the ELR_EL of level returning from.
  • PSTATE is restored by using the contents of the SPSR_EL of level returning from.

It is possible to switch from AArch64 to AArch32 states using exceptions.

Thus ARM Architecture is evolving fast to accommodate the growing requirements in computing. Now with basic idea about, the instruction set, register sets and exception model in ARM architecture, we will see about the Interrupt Architecture in specific in the upcoming blog.