Usually one solution of debugging is to run compiled code on PC simulator. You can download a limited version of instruction set simulator from Hitex for free. Of course better simulators aren’t for free. More advanced simulators you can purchase at Keil. More advanced I mean that there is ability to simulate peripherals by additional scripting and so on. But again, simulators re virtual tools and usually it is hard to simulate real world events. Once you face this problem, you are going to switch to real world simulation using JTAG.
Thumb instructions Thumb instructions shrinks ARM instructions from 32 bit to 16 bit length. This allows saving up to 40% of program memory comparing to ARM instruction set. Maybe this is main reason of Thumb instructions being used. Thumb instructions loose many properties of ARM instructions and become similar to traditional RISC instructions. Thumb instructions cant be conditional, data processing have a two-address format where destination register is one of source registers. ARM instruction: ADD R0, R0, R1 Thumb instruction: ADD R0, R1 As Thumb instruction set takes less of program space it allows to upload bigger applications but with lower speed as using ARM instructions performance is up to 40% faster. But in non critical applications or functions speed isn’t significant factor. Also Thumb instructions doesn’t have full access to all registers. Thumb instructions can only access “low registers”(R0-R7). And only few instructions can access “high registers”(R8-R12).
ARM7 architecture has normal 32bit ARM7 instruction set and compressed 16 bit instruction set so called “Thumb”. ARM7 instructions has a complex behaviour. As ARM processor programming is usually written in C there is no need to be ARM expert, but understanding of basics may help in developing efficient programs. ARM7 datatypes ARM7 processor can support following datatypes: 8 bit signed and unsigned bytes; 16 bit signed and unsigned half-words; 32 bit signed and unsigned words But shorter then 32 bit datatypes are supported only by data transfer functions but when internally processed they are extended to 32 bit size. ARM7 core doesn’t support floating point datatypes – they can only be interpreted by software.
This is an important part of understanding ARM operation modes and handling them. ARM7 supports seven types (0x00000014 address is reserved) of exceptions: As you can see in the table each exception has its own name and fixed address so called exception vectors. When exception occurs, execution is forced from fixed memory address corresponding to the type of exception. When exception occurs R14 and SPSR registers acts like this: R14_<mode>=return link(PC+4); SPSR_<mode>=CPSR; CPSR[4:0]=exception mode number; //execute in ARM state CPSR=0; //disable fast interrupts if (<mode>==reset or FIQ) CPSR=1; //disable normal interrupts CPSR=1 PC=mode vector address Each exception has priorities. Table bellow shows how priorities are assigned to exceptions: Note. All chip peripherals are served as FIQ and IRQ. More deeply about exceptions and priorities will be in practical examples later.
ARM has 31 general purpose 32 bit register where 16 of these are visible at any time. Other registers are used to speed up processing of exceptions. There also is 6 32bit wide status registers. Lets see how it looks like. Registers are arranged in partially overlapping banks with a different register ban of each MCU mode. As I mentioned at any time 15 general purpose registers(R0 to R14) and one or two status registers and PC are visible. Basically R0-R12 registers are user register, that doesn’t have special purpose. Registers R13 – R15 has special functions. R13 is used as stack pointer (SP), R14 is used as link register (LR) and R15 is as program counter (PC):
One of the key features of the fast performance of ARM microcontrollers is Pipelining. ARM7 Core has three-stage pipeline that increase instruction flow through processor up to three times. So each instruction is executed in three stages: Fetch – instruction is fetched from memory and placed in pipeline; Decode – instruction is decoded and data-path signals prepared for next cycle; Execute – instruction from prepared data-path reads from registry bank, shifts operand to ALU and writes generated result to dominant register. Pipelining is implemented in hardware level. Pipeline is linear, what means that in simple data processing processor executes one instruction in single clock cycle while individual instruction takes three clock cycles. But when program structure has branches then pipeline faces difficulties, because it cannot predict which command will be next. In this case pipeline flushes and has to be refilled what means execution speed drops to 1 instruction per 3 clock cycles. But it isn’t true actually. ARM instructions has nice feature that allow to smooth performance of small branches in code that assures optimal performance. This is achieved in hardware level where PC (Program Counter) is calculated 8 bytes ahead of current instruction.
WinARM is a collection of GNU tools for ARM MCU family packed by Martin Thomas that works on MS Windows. WinARM is developed by inspiration on WinAVR project and it is really simple to start working with it if you had a chance to try WinAVR. WinARM doesn’t depend on cygwin or mingw-environment like GNUARM tools does. WinARM toolset is compilled to work with most ARM microcontrollers including LPC2000 series, Atmel’s ARM microcontrollers and Analog devices ARM microcontrollers as well. Basically tools should work with any microcontroller with ARM architecture.