Readme for ARM U/COS II port v1.04 (last updated: 20th January 2001)
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
by Niall Douglas
CHANGES 20/Jan/01: OSRunning, OSPrioRdy & OSPrioCur are byte values
and I was using word ops hence breaking code compiled for Thumb.
Apologies to anyone inconvenienced and thanks to Arjan Oskam for
pointing it out
Herein contained are the files to port U/COS II to a *generic* ARM.
There is no code specific to any particular ARM other than it must
run in a 32 bit mode (ie; ARM2 and ARM3 processors won't run this).
Quick start:
-=-=-=-=-=-=
ALL YOU MUST DO TO USE THIS PORT: Go to the file os_cpu_a.s. Go to
the function OSIntCtxSw. Change the registers unwound appropriately
(they WILL ALTER across versions of ARM SDT used - I've put in
entries for v2.5 and v2.0 of the SDT). If your run-time system
supports OS_EnterOS (SWI 0x16), you're ready.
More detail:
-=-=-=-=-=-=
However, there are a number of assumptions made. The first is that
there are both SWI and IRQ handlers provided. The IRQ handler must
call OSIntEnter(), OSTimeTick() and OSIntExit() for timer interrupts
as the U/COS II book says. The SWI handler must at least provide
SWI OS_EnterOS (0x16) and optionally SWI's OS_IntOn (0x13) and
OS_IntOff (0x14). These work as the *RISC-OS* ones used to, not as
some RTOS's broken implementations do. Demon I believe implements
these fine, Angel does not.
To be specific here:
* OS_EnterOS: Must exit with processor mode now SVC32, interrupt &
flag state *unchanged*. Also, and it's here where many RTOS's are
broken, SPSR_svc on exit must contain the *correct* prior PSR before
the call to OS_EnterOS.
* OS_IntOff: Must exit with merely interrupts disabled, nothing
else changed. If you change OS_CRITICAL_METHOD to 2, you don't
need this call.
* OS_IntOn: Must exit with merely interrupts enabled, nothing else
changed. If you change OS_CRITICAL_METHOD to 2, you don't need this
call.
Potential stack corruption:
-=-=-=-=-=-=-=-=-=-=-=-=-=-
Other notes: If you are using OS_CRITICAL_METHOD 2, you must be
careful in writing code protected by OS_ENTER_CRITICAL and
OS_EXIT_CRITICAL. The problem is that the current interrupt state
is saved on the SVC stack. This poses no problems to C code
running in USR mode, but C code running in SVC mode may have
stack problems as the calls OSStackAndDisableInts() (called by
OS_ENTER_CRITICAL) and OSRestoreStackedIntState() (called by
OS_EXIT_CRITICAL) are not APCS compliant as they don't leave the
stack in the same state as they received it. This normally isn't
a problem unless the compiler is using the stack for temporary
workspace whose allocation and deallocation isn't nested within
the calls.
There are two work-arounds for this problem. First is to change
OSStackAndDisableInts() and OSRestoreStackedIntState() to stack
the saved interrupt state on the FIQ stack instead of the SVC
one. This causes increased overhead.
The second option is to *always* encapsulate code between the
OS_ENTER_CRITICAL and OS_EXIT_CRITICAL in a scope declaration eg;
OS_ENTER_CRITICAL();
{
char temp[256];
// Do stuff
}
OS_EXIT_CRITICAL();
This forces the compiler to deallocate temporary stack usage
before calling OS_EXIT_CRITICAL. Remember this problem ONLY
affects C code which may run in SVC mode. If it's IRQ mode (eg;
IRQ handlers written in C) or any other mode then it is NOT a
problem.
Other small notes: If you enable OS_TASK_DEL_EN, tasks will
auto-call OSTaskDel(OS_PRIO_SELF) if they ever try returning. If
not, the reset vector is called. This behaviour can be changed
in os_cpu_c.c.
The C code correctly handles OS_STK_GROWTH although it assumes
a full descending stack for 1 and an empty ascending stack for
2. The assembler code always assumes a full descending stack as
the relevent ARM instructions embody how stacks move and hence
lots of conditional code would be needed to use a different
stack type. Processor stacks on the ARM haven't been anything
other than full descending for at least a decade now, so I'd
imagine this limitation won't be a problem.
What is "NedHAL"? (I keep seeing references to it)
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
As the NedHAL manual says ...
NedHAL is a modular architecture-independent multiprocessing
capable Hardware Abstraction Layer for everything from tiny
embedded systems upwards. It was designed to remedy many of
the shortcomings of traditional embedded HAL's and RTOS's
NedHAL was the project I undertook as part of reading the final
year of my Software Engineering degree at Hull University in the
United Kingdom. It is roughly equivalent in function to ARM's
uHAL but is improved.
As part of my project, I ported U/COS II to NedHAL. My port of
U/COS II is generic, but all the gubbins required to make it work
(setting up the environment and etc) would be performed by
something like NedHAL.
NedHAL can be downloaded from http://www.nedprod.com/NedHAL/. It
is supplied "as is" and may be used for any non-commercial
application. See the licence.txt file for more info.
All the best,
Niall Douglas
8th July 2000
(Email: NedHAL@nedprod.com)