Introduction | - | - | The Core/ARM directory contains the modules which provide support for the
ARM processor. It comprises of all the non-board-specific ARM-related code within NedHAL. To be specific, this includes:
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Overview | This is effectively the ARM 'port' of NedHAL and it resides within
Core/ARM. It should come as part of the NedHAL distribution. For the ARM-specific documentation, there are a number of extra fields added to the standard API description as given in the manual introduction to extend it for real-time and embedded use on the ARM processor. Here is a complete API field explanation, but with the new fields in white:
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Staticity of API's | NedHAL on the ARM is based on the use of a zero page of DRAM to
store volatile information prior to the availability of the main DRAM banks (see the Board Definintion modules manual for further
information). Most of the ARM support modules use zero page space, and many of them use it
exclusively (ones with "uses zero page only"). On this port of NedHAL to the ARM, there are short periods of time during boot up when main memory is not available as it has not yet been configured for use and hence the C run-time system is not prepared. Hence, any C code which uses static data (ie; is not fully static in the staticity field) will not run correctly. You must only call fully static API's or ones which only use the zero page as this is guaranteed to be available at all times. This will usually only be of relevence to people porting NedHAL to a new board (ie; rewriting the board definition files) - some API's cannot be used in some macros. Examine the Board Definition modules manual to see which macros this applies to. |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Documentation | Most of the NedHAL required functionality is encapsulated within modules,
and hence is not documented here but in their own files:
However, there are two items which do not easily fit into the modular design framework of NedHAL - that of multiprocessor support and system halting. |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Multiprocessor support | Nominally, the only multiprocessor support required of any processor is an interlocked memory load and store instruction. This allows the processor to load the contents of a memory location and set the contents of that same location atomically ie; no part of the system may access that memory location in between the load and store. This is the minimum required to implement semaphores to synchronise between multiple processors in a system. NedHAL abstracts the detail of performing this action so that code may be more easily through the CPU_LOADANDSET call, which will usually be implemented as a macro but may be an inlined C function if the compiler requires it. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Halting the system | It is often useful within any system to have an end-of-line call suitable for when everything else has gone wrong - much like the infamous Windows' "blue screen of death". Such a call is especially useful for debugging code, and NedHAL provides it as the only call which is not part of a module as it doesn't really have anywhere to fit well. The call, in line with most ports of NedHAL, is NedHAL_EmergencyStop which takes a HALError structure, prints suitable information from it and then halts the system by entering a supervisor mode, disabling interrupts and entering an infinite loop. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Using NedHAL on the ARM | These ARM support files were written to be compiled using the ARM
Software Development Toolkit (SDT) v2.0 or later. The GNU make utility is also required
(supplied for Win32) to use the provided Makefiles as the ARM SDT make utility cannot
handle them. You may get a lot of compiler warnings when you use later versions of the SDT
as some ARM assembler notation used by NedHAL has become deprecated. The initial build target as supplied is for the ARM SDT ARMulator utility which soft-emulates an ARM environment on a host machine. We suggest getting this configuration running first before attempting to board-specific ports. To install NedHAL for the ARM, copy the files off the source disc onto your hard drive. There are two copies of the makefile for NedHAL, NedHAL/MakefileR and NedHAL/MakefileD which are the release and debug builds of NedHAL - rename whichever one you want to build to Makefile (debug is easier initially). You will then need to alter the makefile to suit the locations of your copy of the ARM SDT. If you are using Win32, you will also need to copy the provided GNU make utility into somewhere referenced by your PATH variable. Now open a command prompt/line if necessary, and run make. NedHAL should compile all its parts into an ARM library file called nedhal.alf in the NedHAL/<build> directory. |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
NedHAL_Entry | You must now link the nedhal library against the standard C library as
provided by ARM and against some of your code which must contain an exported function
prototyped void NedHAL_Entry(void). This is the point which NedHAL calls when the
system has been initialised and the C run-time system is ready. In a minimal system, this could be the entry point to your application - you have the minimal functionality provided by NedHAL. However, most will want to provide some form of operating system on top of NedHAL. |
Purpose | - | - | Performs an interlocked load and store operation | |
Prototype | int CPU_LOADANDSET(int *address, int value) | |||
Exit | If implemented as a macro, value as on entry, but changed to former
contents of address If implemented an an inlined function, then returns former contents of address |
|||
Interrupts | IRQ is unchanged FIQ is unchanged |
|||
Processor Mode | Unchanged | |||
Staticity | Fully static | |||
Use | This call performs an atomic load and store operation, storing value
at address and setting value to the former contents of address. It
returns value to allow use in if() statements eg; retest: if(CPU_LOADANDSET(lockaddr, (temp=0))==0) /* Lock being examined by other processor */ goto retest; else /* Lock not being looked at right now, we have gained exclusive access */ ... /* Reset lock to previous value for others to use */ *lockaddr=temp; |
|||
Notes | May be implemented as a macro for lower overhead on ARM compilers which support embedded assembler |
Purpose | - | - | Halts the system with the specified error | |
Entry | R0 = pointer to HALError | |||
Exit | Never returns | |||
Interrupts | IRQ is disabled FIQ is disabled |
|||
Processor Mode | SVC32 if User32 on entry, otherwise unchanged | |||
Staticity | Not static | |||
Use | This call writes a suitable message to DebugIO and then halts the system.
If you are running under a debugger, control will return to the debugger. If not, the
system enters an infinite loop. Needless to say, don't use this call unless it's something very critical. It is expected that debug code will make the most use of this call. |
|||
Notes | This call does not return |