mirror of
https://github.com/kelvinlawson/atomthreads.git
synced 2026-01-10 17:56:37 +01:00
Merge pull request #24 from spth/master
Make STM8 port compile with SDCC
This commit is contained in:
@@ -42,15 +42,6 @@ extern "C" {
|
||||
/* Forward declaration */
|
||||
struct atom_tcb;
|
||||
|
||||
/*
|
||||
* Define THREAD_PORT_PRIV to be empty if the used atomport.h does not define
|
||||
* a port specific entry for the atom_tcb struct. This way we do not have an
|
||||
* unused element.
|
||||
*/
|
||||
#if !defined(THREAD_PORT_PRIV)
|
||||
#define THREAD_PORT_PRIV
|
||||
#endif
|
||||
|
||||
typedef struct atom_tcb
|
||||
{
|
||||
/*
|
||||
@@ -60,7 +51,9 @@ typedef struct atom_tcb
|
||||
POINTER sp_save_ptr;
|
||||
|
||||
/* Thread's port specific private data */
|
||||
#if defined(THREAD_PORT_PRIV)
|
||||
THREAD_PORT_PRIV;
|
||||
#endif
|
||||
|
||||
/* Thread priority (0-255) */
|
||||
uint8_t priority;
|
||||
|
||||
199
ports/stm8/README
Normal file
199
ports/stm8/README
Normal file
@@ -0,0 +1,199 @@
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Library: Atomthreads
|
||||
Author: Kelvin Lawson <info@atomthreads.com>
|
||||
Website: http://atomthreads.com
|
||||
License: BSD Revised
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
STM8 PORT
|
||||
|
||||
This folder contains a port of the Atomthreads real time kernel for the
|
||||
STM8 processor architecture. These instructions cover compiler-agnostic
|
||||
aspects of usage of Atomthreads.
|
||||
|
||||
All of the cross-platform kernel code is contained in the top-level
|
||||
'kernel' folder, while ports to specific CPU architectures are contained in
|
||||
the 'ports' folder tree. A port to a CPU architecture can comprise just one
|
||||
or two modules which provide the architecture-specific functionality, such
|
||||
as the context-switch routine which saves and restores processor registers
|
||||
on a thread switch. In this case, the kernel port is split into two files:
|
||||
|
||||
* atomport.c: Those functions which can be written in C
|
||||
* atomport-asm-raisonance.s: Main register save/restore assembler routines
|
||||
|
||||
Each Atomthreads port requires also a header file which describes various
|
||||
architecture-specific details such as appropriate types for 8-bit, 16-bit
|
||||
etc variables, the port's system tick frequency, and macros for performing
|
||||
interrupt lockouts / critical sections:
|
||||
|
||||
* atomport.h: Port-specific header required by the kernel for each port
|
||||
|
||||
A few additional source files are also included here:
|
||||
|
||||
* tests-main.c: Main application file (used for launching automated tests)
|
||||
* uart.c: UART wrapper to allow use of stdio/printf()
|
||||
* stm8s-periphs/*.*: Peripheral drivers as delivered by ST (no changes
|
||||
to distributed code).
|
||||
|
||||
Atomthreads includes a suite of automated tests which prove the key OS
|
||||
functionality, and can be used with any architecture ports. This port
|
||||
provides an easy mechanism for building, downloading and running the test
|
||||
suite to prove the OS on your target.
|
||||
|
||||
The port was carried out and tested on an STM8S105C6 running within an
|
||||
STM8S-Discovery board, and supports the SDCC, Cosmic, Raisonance and IAR compiler
|
||||
tools. It is possible to use it with other processors in the STM8 range, as
|
||||
well as other hardware platforms and compilers, with minimal changes.
|
||||
Platform and compiler specific code has been kept to an absolute minimum.
|
||||
|
||||
This README covers th ecompiler-agnostic aspects of usage of Atomthreads.
|
||||
|
||||
Instructions for users of particular compilers are available in README-SDCC,
|
||||
README-IAR, README-COSMIC and README-RASONANCE.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
STM8S-DISCOVERY SPECIFICS
|
||||
|
||||
There are very minimal board-specific aspects to the STM8 port so it is
|
||||
trivial to run Atomthreads on other STM8 platforms.
|
||||
|
||||
The test applications make use of a LED to indicate test pass/fail status.
|
||||
This is currently configured to use a bit in GPIOD, which on the Discovery
|
||||
board maps to the board's only LED. You may change the port and register
|
||||
bit in tests-main.c to utilise a different pin on other hardware platforms.
|
||||
You may also completely omit the LED flashing in the test application if
|
||||
you prefer to use the UART for monitoring test status.
|
||||
|
||||
The test applications also make use of the UART to print out pass/fail
|
||||
indications and other information. For this you should connect a serial
|
||||
cable to the Discovery board via the external pin connectors. Use of
|
||||
a UART is not required if you prefer to use the LED or some other method
|
||||
of notifying test pass/fail status.
|
||||
|
||||
To connect a serial cable to the Discovery you will need to connect to
|
||||
the following pins on the external connectors:
|
||||
Vcc: CN2 pin 8
|
||||
GND: CN2 pin 7
|
||||
UART RX: CN4 pin 11 (connect to TX at the PC end)
|
||||
UART TX: CN4 pin 10 (connect to RX at the PC end)
|
||||
Note that the board uses TTL levels so you may need to use a level
|
||||
converter. External level converters may need to be powered using
|
||||
a Vdd of 5v, which can be achieved by positioning JP1 on the Discovery.
|
||||
|
||||
The STM8 device on the Discovery only offers UART2. If you are using a
|
||||
different device or wish to use an alternative UART then you must change
|
||||
the stm8s_conf.h file.
|
||||
|
||||
If you are using a CPU other than the STM8S105C6 you should change the
|
||||
PART macro from "STM8S105" to your target CPU. This can be changed in the
|
||||
raisonance.mak Makefile. If you are using the STVD project it should be
|
||||
changed in the project preprocessor settings for both Debug and Release
|
||||
builds. You may also wish to enable any CPU peripherals which you wish to
|
||||
use in the stm8s_conf.h file.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
RAM FOOTPRINT & STACK USAGE
|
||||
|
||||
The Atomthreads kernel is written in well-structured pure C which is highly
|
||||
portable and not targeted at any particular compiler or CPU architecture.
|
||||
For this reason it is not highly optimised for the STM8 architecture, and
|
||||
by its nature will likely have a higher text and data footprint than an
|
||||
RTOS targeted at the STM8 architecture only. The emphasis here is on
|
||||
C-based portable, readable and maintainable code which can run on any CPU
|
||||
architecture, from the 8-bitters up.
|
||||
|
||||
A good rule of thumb when using Atomthreads on the STM8 architecture is
|
||||
that a minimum of 1KB RAM is required in order to support an application
|
||||
with 4 or 5 threads and the idle thread. If a minimum of approximately
|
||||
128 bytes per thread stack is acceptable then you will benefit from the
|
||||
easy-to-read, portable implementation of an RTOS herein.
|
||||
|
||||
The major consumer of RAM when using Atomthreads is your thread stacks.
|
||||
Functionality that is shared between several kernel modules is farmed out
|
||||
to separate functions, resulting in readable and maintainable code but
|
||||
with some associated stack cost of calling out to subroutines. Further,
|
||||
each thread stack is used for saving its own registers on a context
|
||||
switch, and there is no separate interrupt stack which means that each
|
||||
thread stack has to be able to cope with the maximum stack usage of the
|
||||
kernel (and application) interrupt handlers.
|
||||
|
||||
Clearly the stack requirement for each thread depends on what your
|
||||
application code does, and what memory model is used etc, but generally
|
||||
you should find that 128 bytes is enough to allow for the thread to be
|
||||
switched out (and thus save its registers) while deep within a kernel
|
||||
or application call stack, and similarly enough to provide stack for
|
||||
interrupt handlers interrupting while the thread is deep within a kernel
|
||||
or application call stack. You will need to increase this depending on
|
||||
what level of stack the application code in question requires.
|
||||
|
||||
At this time the maximum stack consumed by the test threads within the
|
||||
automated test modules is 95 bytes of stack, and the main test thread has
|
||||
been seen to consume 163 bytes of stack. At this time the queue9 test is
|
||||
the largest consumer of test thread stack (95 bytes) and the sem1 test
|
||||
consumes the largest main thread stack (137 bytes). If your applications
|
||||
have large amounts of local data or call several subroutines then you may
|
||||
find that you need larger than 128 bytes.
|
||||
|
||||
You may monitor the stack usage of your application threads during runtime
|
||||
by defining the macro ATOM_STACK_CHECKING and calling
|
||||
atomThreadStackCheck(). This macro is defined by default in the Makefile
|
||||
so that the automated test modules can check for stack overflows, but you
|
||||
may wish to undefine this in your application Makefiles when you are happy
|
||||
that the stack usage is acceptable. Enabling ATOM_STACK_CHECKING will
|
||||
increase the size of your threads' TCBs slightly, and will incur a minor
|
||||
CPU cycles overhead whenever threads are created due to prefilling the
|
||||
thread stack with a known value.
|
||||
|
||||
With careful consideration and few threads it would be possible to use
|
||||
a platform with 512 bytes RAM, but not all of the automated test suite
|
||||
would run on such a platform (some of the test modules use 6 threads: a
|
||||
main thread together with 4 test threads and the idle thread).
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
INTERRUPT HANDLING
|
||||
|
||||
Interrupt handlers use the stack of the thread which was running when the
|
||||
interrupt occurred. If no thread rescheduling occurs during the ISR then
|
||||
on exit from the ISR any data stacked by the ISR on the thread's stack is
|
||||
popped off the stack and execution of the thread resumes. If a reschedule
|
||||
during the ISR causes a context switch to a new thread, then the ISR's
|
||||
data will remain on the thread's stack until the thread is scheduled back
|
||||
in.
|
||||
|
||||
Interrupt priorities (via the ITC_SPRx registers) are left in their
|
||||
default power-on state, which disables interrupt nesting. Kernel changes
|
||||
may be required to support interrupt nesting.
|
||||
|
||||
Note that the STM8 programming manual currently describes the following
|
||||
feature:
|
||||
|
||||
"Fast interrupt handling through alternate register files (up to 4
|
||||
contexts) with standard stack compatible mode (for real time OS
|
||||
kernels)"
|
||||
|
||||
This feature was implemented by ST in the core but has to date never been
|
||||
included in any STM8 products. If it is included in future products then
|
||||
you will need to put the device in the stack compatible mode described.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
WRITING NEW INTERRUPT HANDLERS
|
||||
|
||||
All interrupt handlers which will call out to the OS kernel and potentially
|
||||
cause a thread switch must call atomIntEnter() and atomIntExit(). An
|
||||
example of this can be seen in the timer tick ISR in atomport.c.
|
||||
|
||||
You may also implement fast interrupt handlers in the system which do not
|
||||
call atomIntEnter()/atomIntExit(), however these ISRs cannot perform OS
|
||||
functions such as posting semaphores or effecting a thread switch.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
@@ -13,44 +13,10 @@ This folder contains a port of the Atomthreads real time kernel for the
|
||||
STM8 processor architecture. These instructions cover usage of Atomthreads
|
||||
with the Cosmic compiler (CXSTM8).
|
||||
|
||||
All of the cross-platform kernel code is contained in the top-level
|
||||
'kernel' folder, while ports to specific CPU architectures are contained in
|
||||
the 'ports' folder tree. A port to a CPU architecture can comprise just one
|
||||
or two modules which provide the architecture-specific functionality, such
|
||||
as the context-switch routine which saves and restores processor registers
|
||||
on a thread switch. In this case, the kernel port is split into two files:
|
||||
Compiler-agnostic aspects of the usage of Atomthreads can be found in README.
|
||||
|
||||
* atomport.c: Those functions which can be written in C
|
||||
* atomport-asm-cosmic.s: The main register save/restore assembler routines
|
||||
|
||||
Each Atomthreads port requires also a header file which describes various
|
||||
architecture-specific details such as appropriate types for 8-bit, 16-bit
|
||||
etc variables, the port's system tick frequency, and macros for performing
|
||||
interrupt lockouts / critical sections:
|
||||
|
||||
* atomport.h: Port-specific header required by the kernel for each port
|
||||
|
||||
A few additional source files are also included here:
|
||||
|
||||
* tests-main.c: Main application file (used for launching automated tests)
|
||||
* stm8_interrupt_vector.c: List of interrupt handlers for vector table
|
||||
* uart.c: UART wrapper to allow use of stdio/printf()
|
||||
* stm8s-periphs/*.*: Peripheral drivers as delivered by ST (no changes
|
||||
to distributed code).
|
||||
|
||||
Atomthreads includes a suite of automated tests which prove the key OS
|
||||
functionality, and can be used with any architecture ports. This port
|
||||
provides an easy mechanism for building, downloading and running the test
|
||||
suite to prove the OS on your target.
|
||||
|
||||
The port was carried out and tested on an STM8S105C6 running within an
|
||||
STM8S-Discovery board, and supports the Cosmic, Raisonance and IAR compiler
|
||||
tools. It is possible to use it with other processors in the STM8 range, as
|
||||
well as other hardware platforms and compilers, with minimal changes.
|
||||
Platform and compiler specific code has been kept to an absolute minimum.
|
||||
This README covers usage of Atomthreads with the Cosmic compiler.
|
||||
Instructions for users of the other compilers are available in README-IAR
|
||||
and README-RAISONANCE.
|
||||
Instructions for users of the other compilers are available in README-SDCC,
|
||||
README-IAR and README-RAISONANCE.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
@@ -212,49 +178,6 @@ device and start it running.
|
||||
Other programming tools may exist but are not apparent in the toolset
|
||||
delivered for use the STM8S Discovery platform.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
STM8S-DISCOVERY SPECIFICS
|
||||
|
||||
There are very minimal board-specific aspects to the STM8 port so it is
|
||||
trivial to run Atomthreads on other STM8 platforms.
|
||||
|
||||
The test applications make use of a LED to indicate test pass/fail status.
|
||||
This is currently configured to use a bit in GPIOD, which on the Discovery
|
||||
board maps to the board's only LED. You may change the port and register
|
||||
bit in tests-main.c to utilise a different pin on other hardware platforms.
|
||||
You may also completely omit the LED flashing in the test application if
|
||||
you prefer to use the UART for monitoring test status.
|
||||
|
||||
The test applications also make use of the UART to print out pass/fail
|
||||
indications and other information. For this you should connect a serial
|
||||
cable to the Discovery board via the external pin connectors. Use of
|
||||
a UART is not required if you prefer to use the LED or some other method
|
||||
of notifying test pass/fail status.
|
||||
|
||||
To connect a serial cable to the Discovery you will need to connect to
|
||||
the following pins on the external connectors:
|
||||
Vcc: CN2 pin 8
|
||||
GND: CN2 pin 7
|
||||
UART RX: CN4 pin 11 (connect to TX at the PC end)
|
||||
UART TX: CN4 pin 10 (connect to RX at the PC end)
|
||||
Note that the board uses TTL levels so you may need to use a level
|
||||
converter. External level converters may need to be powered using
|
||||
a Vdd of 5v, which can be achieved by positioning JP1 on the Discovery.
|
||||
|
||||
The STM8 device on the Discovery only offers UART2. If you are using a
|
||||
different device or wish to use an alternative UART then you must change
|
||||
the stm8s_conf.h file.
|
||||
|
||||
If you are using a CPU other than the STM8S105C6 you should change the
|
||||
PART macro from "STM8S105" to your target CPU. This can be changed in the
|
||||
cosmic.mak Makefile. If you are using the STVD project it should be
|
||||
changed in the project preprocessor settings for both Debug and Release
|
||||
builds. You may also wish to enable any CPU peripherals which you wish to
|
||||
use in the stm8s_conf.h file.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
RUNNING THE AUTOMATED TESTS
|
||||
@@ -322,155 +245,6 @@ both Debug and Release builds as follows:
|
||||
0x7BF for application usage, and 0x7C0 to 0x7FF for startup stack.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
RAM FOOTPRINT & STACK USAGE
|
||||
|
||||
The Atomthreads kernel is written in well-structured pure C which is highly
|
||||
portable and not targeted at any particular compiler or CPU architecture.
|
||||
For this reason it is not highly optimised for the STM8 architecture, and
|
||||
by its nature will likely have a higher text and data footprint than an
|
||||
RTOS targeted at the STM8 architecture only. The emphasis here is on
|
||||
C-based portable, readable and maintainable code which can run on any CPU
|
||||
architecture, from the 8-bitters up.
|
||||
|
||||
A good rule of thumb when using Atomthreads on the STM8 architecture is
|
||||
that a minimum of 1KB RAM is required in order to support an application
|
||||
with 4 or 5 threads and the idle thread. If a minimum of approximately
|
||||
128 bytes per thread stack is acceptable then you will benefit from the
|
||||
easy-to-read, portable implementation of an RTOS herein.
|
||||
|
||||
The major consumer of RAM when using Atomthreads is your thread stacks.
|
||||
Functionality that is shared between several kernel modules is farmed out
|
||||
to separate functions, resulting in readable and maintainable code but
|
||||
with some associated stack cost of calling out to subroutines. Further,
|
||||
each thread stack is used for saving its own registers on a context
|
||||
switch, and there is no separate interrupt stack which means that each
|
||||
thread stack has to be able to cope with the maximum stack usage of the
|
||||
kernel (and application) interrupt handlers.
|
||||
|
||||
Clearly the stack requirement for each thread depends on what your
|
||||
application code does, and what memory model is used etc, but generally
|
||||
you should find that 128 bytes is enough to allow for the thread to be
|
||||
switched out (and thus save its registers) while deep within a kernel
|
||||
or application call stack, and similarly enough to provide stack for
|
||||
interrupt handlers interrupting while the thread is deep within a kernel
|
||||
or application call stack. You will need to increase this depending on
|
||||
what level of stack the application code in question requires.
|
||||
|
||||
At this time the maximum stack consumed by the test threads within the
|
||||
automated test modules is 95 bytes of stack, and the main test thread has
|
||||
been seen to consume 163 bytes of stack. At this time the timer2 test is
|
||||
the largest consumer of test thread stack (95 bytes) and the sem3 test
|
||||
consumes the largest main thread stack (163 bytes). If your applications
|
||||
have large amounts of local data or call several subroutines then you may
|
||||
find that you need larger than 128 bytes.
|
||||
|
||||
You may monitor the stack usage of your application threads during runtime
|
||||
by defining the macro ATOM_STACK_CHECKING and calling
|
||||
atomThreadStackCheck(). This macro is defined by default in the Makefile
|
||||
so that the automated test modules can check for stack overflows, but you
|
||||
may wish to undefine this in your application Makefiles when you are happy
|
||||
that the stack usage is acceptable. Enabling ATOM_STACK_CHECKING will
|
||||
increase the size of your threads' TCBs slightly, and will incur a minor
|
||||
CPU cycles overhead whenever threads are created due to prefilling the
|
||||
thread stack with a known value.
|
||||
|
||||
With careful consideration and few threads it would be possible to use
|
||||
a platform with 512 bytes RAM, but not all of the automated test suite
|
||||
would run on such a platform (some of the test modules use 6 threads: a
|
||||
main thread together with 4 test threads and the idle thread).
|
||||
|
||||
The RAM layout used for the automated test applications is as follows:
|
||||
|
||||
RAM Top:
|
||||
* Startup Stack (64 bytes)
|
||||
* Data & BSS area (thread stacks, other application data)
|
||||
RAM Bottom.
|
||||
|
||||
This is not prescribed, you may use whichever layout you wish for your
|
||||
applications.
|
||||
|
||||
The startup stack area starts at the top of RAM and is only used for first
|
||||
initialisation of the OS and main thread. This uses 64 bytes and could be
|
||||
reused once the OS is started, but for the purposes of the automated test
|
||||
applications it is not reused. Generally you would ensure that this is
|
||||
reused in your own application code.
|
||||
|
||||
The application's data starts at the bottom of RAM, and this includes all
|
||||
of the thread stacks which are statically allocated arrays. The idle
|
||||
thread, main thread, and automated test thread stacks are allocated here.
|
||||
|
||||
The default layout provided with Atomthreads matches the STM8S-Discovery
|
||||
with 2KB RAM. The linker file reserves the first 0x7C0 bytes for data
|
||||
areas. The region from here up to the end of RAM (0x800) is used for the
|
||||
the 64 byte startup stack.
|
||||
|
||||
As mentioned previously, this RAM layout is only the one utilised by the
|
||||
test applications. You may choose whatever layout you like.
|
||||
|
||||
Note that on this platform data can be placed at address 0x0, but the
|
||||
Atomthreads kernel performs validity checks on pointers to ensure they
|
||||
are not NULL pointers (point to address 0x0). For this reason the
|
||||
example projects (STVD and Makefile) force the linker to not use address
|
||||
0x0 and instead start the page0 space at 0x2. This ensures that the
|
||||
linker does not place any data at address 0x0, and hence all NULL-ptr
|
||||
checks are still suitable checks for valid pointers. This does, however,
|
||||
waste 2 bytes. For your own projects you can force this within STVD by
|
||||
editing the project linker settings (Input -> Zero Page start at 0x2)
|
||||
or by editing the linker .LKF file as can be seen in atomthreads.lkf.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
INTERRUPT HANDLING
|
||||
|
||||
Interrupt handlers use the stack of the thread which was running when the
|
||||
interrupt occurred. If no thread rescheduling occurs during the ISR then
|
||||
on exit from the ISR any data stacked by the ISR on the thread's stack is
|
||||
popped off the stack and execution of the thread resumes. If a reschedule
|
||||
during the ISR causes a context switch to a new thread, then the ISR's
|
||||
data will remain on the thread's stack until the thread is scheduled back
|
||||
in.
|
||||
|
||||
Interrupt priorities (via the ITC_SPRx registers) are left in their
|
||||
default power-on state, which disables interrupt nesting. Kernel changes
|
||||
may be required to support interrupt nesting.
|
||||
|
||||
Note that the STM8 programming manual currently describes the following
|
||||
feature:
|
||||
|
||||
"Fast interrupt handling through alternate register files (up to 4
|
||||
contexts) with standard stack compatible mode (for real time OS
|
||||
kernels)"
|
||||
|
||||
This feature was implemented by ST in the core but has to date never been
|
||||
included in any STM8 products. If it is included in future products then
|
||||
you will need to put the device in the stack compatible mode described.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
WRITING NEW INTERRUPT HANDLERS
|
||||
|
||||
All interrupt handlers which will call out to the OS kernel and potentially
|
||||
cause a thread switch must call atomIntEnter() and atomIntExit(). An
|
||||
example of this can be seen in the timer tick ISR in atomport.c.
|
||||
|
||||
With the Cosmic compiler port it is also necessary to add the @svlreg
|
||||
modifier to any interrupt handlers which call out to the OS kernel.
|
||||
Alternatively you may use the INTERRUPT macro from atomport-private.h which
|
||||
always adds the @svlreg modifier. This modifier ensures that the c_lreg
|
||||
virtual register is saved on the interrupted thread's stack for any
|
||||
preemptive context switches. It also ensures that longs are available for
|
||||
use within any OS kernel code called as part of the interrupt handling.
|
||||
|
||||
You may also implement fast interrupt handlers in the system which do not
|
||||
call atomIntEnter()/atomIntExit() and which do not need the @svlreg
|
||||
modifier, however these ISRs cannot perform OS functions such as posting
|
||||
semaphores or effecting a thread switch.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
COSMIC COMPILER VIRTUAL REGISTERS
|
||||
|
||||
@@ -13,43 +13,10 @@ This folder contains a port of the Atomthreads real time kernel for the
|
||||
STM8 processor architecture. These instructions cover usage of Atomthreads
|
||||
with the IAR Embedded Workbench compiler (EWSTM8).
|
||||
|
||||
All of the cross-platform kernel code is contained in the top-level
|
||||
'kernel' folder, while ports to specific CPU architectures are contained in
|
||||
the 'ports' folder tree. A port to a CPU architecture can comprise just one
|
||||
or two modules which provide the architecture-specific functionality, such
|
||||
as the context-switch routine which saves and restores processor registers
|
||||
on a thread switch. In this case, the kernel port is split into two files:
|
||||
Compiler-agnostic aspects of the usage of Atomthreads can be found in README.
|
||||
|
||||
* atomport.c: Those functions which can be written in C
|
||||
* atomport-asm-iar.s: The main register save/restore assembler routines
|
||||
|
||||
Each Atomthreads port requires also a header file which describes various
|
||||
architecture-specific details such as appropriate types for 8-bit, 16-bit
|
||||
etc variables, the port's system tick frequency, and macros for performing
|
||||
interrupt lockouts / critical sections:
|
||||
|
||||
* atomport.h: Port-specific header required by the kernel for each port
|
||||
|
||||
A few additional source files are also included here:
|
||||
|
||||
* tests-main.c: Main application file (used for launching automated tests)
|
||||
* uart.c: UART wrapper to allow use of stdio/printf()
|
||||
* stm8s-periphs/*.*: Peripheral drivers as delivered by ST (no changes
|
||||
to distributed code).
|
||||
|
||||
Atomthreads includes a suite of automated tests which prove the key OS
|
||||
functionality, and can be used with any architecture ports. This port
|
||||
provides an easy mechanism for building, downloading and running the test
|
||||
suite to prove the OS on your target.
|
||||
|
||||
The port was carried out and tested on an STM8S105C6 running within an
|
||||
STM8S-Discovery board, and supports the Cosmic, Raisonance and IAR compiler
|
||||
tools. It is possible to use it with other processors in the STM8 range, as
|
||||
well as other hardware platforms and compilers, with minimal changes.
|
||||
Platform and compiler specific code has been kept to an absolute minimum.
|
||||
This README covers usage of Atomthreads with the IAR compiler. Instructions
|
||||
for users of the other compilers are available in README-COSMIC and
|
||||
README-RAISONANCE.
|
||||
Instructions for users of the other compilers are available in README-SDCC,
|
||||
README-COSMIC and README-RAISONANCE.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
@@ -188,50 +155,6 @@ device and start it running.
|
||||
Other programming tools may exist but are not apparent in the toolset
|
||||
delivered for use the STM8S Discovery platform.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
STM8S-DISCOVERY SPECIFICS
|
||||
|
||||
There are very minimal board-specific aspects to the STM8 port so it is
|
||||
trivial to run Atomthreads on other STM8 platforms.
|
||||
|
||||
The test applications make use of a LED to indicate test pass/fail status.
|
||||
This is currently configured to use a bit in GPIOD, which on the Discovery
|
||||
board maps to the board's only LED. You may change the port and register
|
||||
bit in tests-main.c to utilise a different pin on other hardware platforms.
|
||||
You may also completely omit the LED flashing in the test application if
|
||||
you prefer to use the UART for monitoring test status.
|
||||
|
||||
The test applications also make use of the UART to print out pass/fail
|
||||
indications and other information. For this you should connect a serial
|
||||
cable to the Discovery board via the external pin connectors. Use of
|
||||
a UART is not required if you prefer to use the LED or some other method
|
||||
of notifying test pass/fail status.
|
||||
|
||||
To connect a serial cable to the Discovery you will need to connect to
|
||||
the following pins on the external connectors:
|
||||
Vcc: CN2 pin 8
|
||||
GND: CN2 pin 7
|
||||
UART RX: CN4 pin 11 (connect to TX at the PC end)
|
||||
UART TX: CN4 pin 10 (connect to RX at the PC end)
|
||||
Note that the board uses TTL levels so you may need to use a level
|
||||
converter. External level converters may need to be powered using
|
||||
a Vdd of 5v, which can be achieved by positioning JP1 on the Discovery.
|
||||
|
||||
The STM8 device on the Discovery only offers UART2. If you are using a
|
||||
different device or wish to use an alternative UART then you must change
|
||||
the stm8s_conf.h file.
|
||||
|
||||
If you are using a CPU other than the STM8S105C6 you should change the
|
||||
PART macro from "STM8S105" to your target CPU. This can be changed in the
|
||||
iar.mak Makefile. If you are using the EWSTM8 project it should be
|
||||
changed in the project C/C++ Compiler Preprocessor settings for both Debug
|
||||
and Release builds, and you must also change the target device in the
|
||||
project's "General Options". You may also wish to enable any CPU
|
||||
peripherals which you wish to use in the stm8s_conf.h file.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
RUNNING THE AUTOMATED TESTS
|
||||
@@ -311,107 +234,6 @@ Add the .C and .S modules from the following folders:
|
||||
Set include paths as appropriate.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
RAM FOOTPRINT & STACK USAGE
|
||||
|
||||
The Atomthreads kernel is written in well-structured pure C which is highly
|
||||
portable and not targeted at any particular compiler or CPU architecture.
|
||||
For this reason it is not highly optimised for the STM8 architecture, and
|
||||
by its nature will likely have a higher text and data footprint than an
|
||||
RTOS targeted at the STM8 architecture only. The emphasis here is on
|
||||
C-based portable, readable and maintainable code which can run on any CPU
|
||||
architecture, from the 8-bitters up.
|
||||
|
||||
A good rule of thumb when using Atomthreads on the STM8 architecture is
|
||||
that a minimum of 1KB RAM is required in order to support an application
|
||||
with 4 or 5 threads and the idle thread. If a minimum of approximately
|
||||
128 bytes per thread stack is acceptable then you will benefit from the
|
||||
easy-to-read, portable implementation of an RTOS herein.
|
||||
|
||||
The major consumer of RAM when using Atomthreads is your thread stacks.
|
||||
Functionality that is shared between several kernel modules is farmed out
|
||||
to separate functions, resulting in readable and maintainable code but
|
||||
with some associated stack cost of calling out to subroutines. Further,
|
||||
each thread stack is used for saving its own registers on a context
|
||||
switch, and there is no separate interrupt stack which means that each
|
||||
thread stack has to be able to cope with the maximum stack usage of the
|
||||
kernel (and application) interrupt handlers.
|
||||
|
||||
Clearly the stack requirement for each thread depends on what your
|
||||
application code does, and what memory model is used etc, but generally
|
||||
you should find that 128 bytes is enough to allow for the thread to be
|
||||
switched out (and thus save its registers) while deep within a kernel
|
||||
or application call stack, and similarly enough to provide stack for
|
||||
interrupt handlers interrupting while the thread is deep within a kernel
|
||||
or application call stack. You will need to increase this depending on
|
||||
what level of stack the application code in question requires.
|
||||
|
||||
At this time the maximum stack consumed by the test threads within the
|
||||
automated test modules is 85 bytes of stack, and the main test thread has
|
||||
been seen to consume 193 bytes of stack. At this time the queue9 test is
|
||||
the largest consumer of test thread stack (85 bytes) and the sem8 test
|
||||
consumes the largest main thread stack (193 bytes). If your applications
|
||||
have large amounts of local data or call several subroutines then you may
|
||||
find that you need larger than 128 bytes.
|
||||
|
||||
You may monitor the stack usage of your application threads during runtime
|
||||
by defining the macro ATOM_STACK_CHECKING and calling
|
||||
atomThreadStackCheck(). This macro is defined by default in the EWSTM8
|
||||
Debug project so that the automated test modules can check for stack
|
||||
overflows, but you may wish to undefine this in your application
|
||||
when you are happy that the stack usage is acceptable. Enabling
|
||||
ATOM_STACK_CHECKING will increase the size of your threads' TCBs
|
||||
slightly, and will incur a minor CPU cycles overhead whenever threads are
|
||||
created due to prefilling the thread stack with a known value.
|
||||
|
||||
With careful consideration and few threads it would be possible to use
|
||||
a platform with 512 bytes RAM, but not all of the automated test suite
|
||||
would run on such a platform (some of the test modules use 6 threads: a
|
||||
main thread together with 4 test threads and the idle thread).
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
INTERRUPT HANDLING
|
||||
|
||||
Interrupt handlers use the stack of the thread which was running when the
|
||||
interrupt occurred. If no thread rescheduling occurs during the ISR then
|
||||
on exit from the ISR any data stacked by the ISR on the thread's stack is
|
||||
popped off the stack and execution of the thread resumes. If a reschedule
|
||||
during the ISR causes a context switch to a new thread, then the ISR's
|
||||
data will remain on the thread's stack until the thread is scheduled back
|
||||
in.
|
||||
|
||||
Interrupt priorities (via the ITC_SPRx registers) are left in their
|
||||
default power-on state, which disables interrupt nesting. Kernel changes
|
||||
may be required to support interrupt nesting.
|
||||
|
||||
Note that the STM8 programming manual currently describes the following
|
||||
feature:
|
||||
|
||||
"Fast interrupt handling through alternate register files (up to 4
|
||||
contexts) with standard stack compatible mode (for real time OS
|
||||
kernels)"
|
||||
|
||||
This feature was implemented by ST in the core but has to date never been
|
||||
included in any STM8 products. If it is included in future products then
|
||||
you will need to put the device in the stack compatible mode described.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
WRITING NEW INTERRUPT HANDLERS
|
||||
|
||||
All interrupt handlers which will call out to the OS kernel and potentially
|
||||
cause a thread switch must call atomIntEnter() and atomIntExit(). An
|
||||
example of this can be seen in the timer tick ISR in atomport.c.
|
||||
|
||||
You may also implement fast interrupt handlers in the system which do not
|
||||
call atomIntEnter()/atomIntExit(), however these ISRs cannot perform OS
|
||||
functions such as posting semaphores or effecting a thread switch.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
IAR COMPILER VIRTUAL REGISTERS
|
||||
|
||||
@@ -13,43 +13,10 @@ This folder contains a port of the Atomthreads real time kernel for the
|
||||
STM8 processor architecture. These instructions cover usage of Atomthreads
|
||||
with the Raisonance compiler (RCSTM8).
|
||||
|
||||
All of the cross-platform kernel code is contained in the top-level
|
||||
'kernel' folder, while ports to specific CPU architectures are contained in
|
||||
the 'ports' folder tree. A port to a CPU architecture can comprise just one
|
||||
or two modules which provide the architecture-specific functionality, such
|
||||
as the context-switch routine which saves and restores processor registers
|
||||
on a thread switch. In this case, the kernel port is split into two files:
|
||||
Compiler-agnostic aspects of the usage of Atomthreads can be found in README.
|
||||
|
||||
* atomport.c: Those functions which can be written in C
|
||||
* atomport-asm-raisonance.s: Main register save/restore assembler routines
|
||||
|
||||
Each Atomthreads port requires also a header file which describes various
|
||||
architecture-specific details such as appropriate types for 8-bit, 16-bit
|
||||
etc variables, the port's system tick frequency, and macros for performing
|
||||
interrupt lockouts / critical sections:
|
||||
|
||||
* atomport.h: Port-specific header required by the kernel for each port
|
||||
|
||||
A few additional source files are also included here:
|
||||
|
||||
* tests-main.c: Main application file (used for launching automated tests)
|
||||
* uart.c: UART wrapper to allow use of stdio/printf()
|
||||
* stm8s-periphs/*.*: Peripheral drivers as delivered by ST (no changes
|
||||
to distributed code).
|
||||
|
||||
Atomthreads includes a suite of automated tests which prove the key OS
|
||||
functionality, and can be used with any architecture ports. This port
|
||||
provides an easy mechanism for building, downloading and running the test
|
||||
suite to prove the OS on your target.
|
||||
|
||||
The port was carried out and tested on an STM8S105C6 running within an
|
||||
STM8S-Discovery board, and supports the Cosmic, Raisonance and IAR compiler
|
||||
tools. It is possible to use it with other processors in the STM8 range, as
|
||||
well as other hardware platforms and compilers, with minimal changes.
|
||||
Platform and compiler specific code has been kept to an absolute minimum.
|
||||
This README covers usage of Atomthreads with the Raisonance compiler.
|
||||
Instructions for users of the other compilers are available in README-IAR
|
||||
and README-COSMIC.
|
||||
Instructions for users of the other compilers are available in README-SDCC,
|
||||
README-IAR and README-COSMIC.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
@@ -204,49 +171,6 @@ device and start it running.
|
||||
Other programming tools may exist but are not apparent in the toolset
|
||||
delivered for use the STM8S Discovery platform.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
STM8S-DISCOVERY SPECIFICS
|
||||
|
||||
There are very minimal board-specific aspects to the STM8 port so it is
|
||||
trivial to run Atomthreads on other STM8 platforms.
|
||||
|
||||
The test applications make use of a LED to indicate test pass/fail status.
|
||||
This is currently configured to use a bit in GPIOD, which on the Discovery
|
||||
board maps to the board's only LED. You may change the port and register
|
||||
bit in tests-main.c to utilise a different pin on other hardware platforms.
|
||||
You may also completely omit the LED flashing in the test application if
|
||||
you prefer to use the UART for monitoring test status.
|
||||
|
||||
The test applications also make use of the UART to print out pass/fail
|
||||
indications and other information. For this you should connect a serial
|
||||
cable to the Discovery board via the external pin connectors. Use of
|
||||
a UART is not required if you prefer to use the LED or some other method
|
||||
of notifying test pass/fail status.
|
||||
|
||||
To connect a serial cable to the Discovery you will need to connect to
|
||||
the following pins on the external connectors:
|
||||
Vcc: CN2 pin 8
|
||||
GND: CN2 pin 7
|
||||
UART RX: CN4 pin 11 (connect to TX at the PC end)
|
||||
UART TX: CN4 pin 10 (connect to RX at the PC end)
|
||||
Note that the board uses TTL levels so you may need to use a level
|
||||
converter. External level converters may need to be powered using
|
||||
a Vdd of 5v, which can be achieved by positioning JP1 on the Discovery.
|
||||
|
||||
The STM8 device on the Discovery only offers UART2. If you are using a
|
||||
different device or wish to use an alternative UART then you must change
|
||||
the stm8s_conf.h file.
|
||||
|
||||
If you are using a CPU other than the STM8S105C6 you should change the
|
||||
PART macro from "STM8S105" to your target CPU. This can be changed in the
|
||||
raisonance.mak Makefile. If you are using the STVD project it should be
|
||||
changed in the project preprocessor settings for both Debug and Release
|
||||
builds. You may also wish to enable any CPU peripherals which you wish to
|
||||
use in the stm8s_conf.h file.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
RUNNING THE AUTOMATED TESTS
|
||||
@@ -318,106 +242,6 @@ functions in reentrant mode, however it does this by default on the STM8
|
||||
platform so no user action is required (unlike when targeting the STM7
|
||||
platform with Raisonance).
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
RAM FOOTPRINT & STACK USAGE
|
||||
|
||||
The Atomthreads kernel is written in well-structured pure C which is highly
|
||||
portable and not targeted at any particular compiler or CPU architecture.
|
||||
For this reason it is not highly optimised for the STM8 architecture, and
|
||||
by its nature will likely have a higher text and data footprint than an
|
||||
RTOS targeted at the STM8 architecture only. The emphasis here is on
|
||||
C-based portable, readable and maintainable code which can run on any CPU
|
||||
architecture, from the 8-bitters up.
|
||||
|
||||
A good rule of thumb when using Atomthreads on the STM8 architecture is
|
||||
that a minimum of 1KB RAM is required in order to support an application
|
||||
with 4 or 5 threads and the idle thread. If a minimum of approximately
|
||||
128 bytes per thread stack is acceptable then you will benefit from the
|
||||
easy-to-read, portable implementation of an RTOS herein.
|
||||
|
||||
The major consumer of RAM when using Atomthreads is your thread stacks.
|
||||
Functionality that is shared between several kernel modules is farmed out
|
||||
to separate functions, resulting in readable and maintainable code but
|
||||
with some associated stack cost of calling out to subroutines. Further,
|
||||
each thread stack is used for saving its own registers on a context
|
||||
switch, and there is no separate interrupt stack which means that each
|
||||
thread stack has to be able to cope with the maximum stack usage of the
|
||||
kernel (and application) interrupt handlers.
|
||||
|
||||
Clearly the stack requirement for each thread depends on what your
|
||||
application code does, and what memory model is used etc, but generally
|
||||
you should find that 128 bytes is enough to allow for the thread to be
|
||||
switched out (and thus save its registers) while deep within a kernel
|
||||
or application call stack, and similarly enough to provide stack for
|
||||
interrupt handlers interrupting while the thread is deep within a kernel
|
||||
or application call stack. You will need to increase this depending on
|
||||
what level of stack the application code in question requires.
|
||||
|
||||
At this time the maximum stack consumed by the test threads within the
|
||||
automated test modules is 95 bytes of stack, and the main test thread has
|
||||
been seen to consume 163 bytes of stack. At this time the queue9 test is
|
||||
the largest consumer of test thread stack (95 bytes) and the sem1 test
|
||||
consumes the largest main thread stack (137 bytes). If your applications
|
||||
have large amounts of local data or call several subroutines then you may
|
||||
find that you need larger than 128 bytes.
|
||||
|
||||
You may monitor the stack usage of your application threads during runtime
|
||||
by defining the macro ATOM_STACK_CHECKING and calling
|
||||
atomThreadStackCheck(). This macro is defined by default in the Makefile
|
||||
so that the automated test modules can check for stack overflows, but you
|
||||
may wish to undefine this in your application Makefiles when you are happy
|
||||
that the stack usage is acceptable. Enabling ATOM_STACK_CHECKING will
|
||||
increase the size of your threads' TCBs slightly, and will incur a minor
|
||||
CPU cycles overhead whenever threads are created due to prefilling the
|
||||
thread stack with a known value.
|
||||
|
||||
With careful consideration and few threads it would be possible to use
|
||||
a platform with 512 bytes RAM, but not all of the automated test suite
|
||||
would run on such a platform (some of the test modules use 6 threads: a
|
||||
main thread together with 4 test threads and the idle thread).
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
INTERRUPT HANDLING
|
||||
|
||||
Interrupt handlers use the stack of the thread which was running when the
|
||||
interrupt occurred. If no thread rescheduling occurs during the ISR then
|
||||
on exit from the ISR any data stacked by the ISR on the thread's stack is
|
||||
popped off the stack and execution of the thread resumes. If a reschedule
|
||||
during the ISR causes a context switch to a new thread, then the ISR's
|
||||
data will remain on the thread's stack until the thread is scheduled back
|
||||
in.
|
||||
|
||||
Interrupt priorities (via the ITC_SPRx registers) are left in their
|
||||
default power-on state, which disables interrupt nesting. Kernel changes
|
||||
may be required to support interrupt nesting.
|
||||
|
||||
Note that the STM8 programming manual currently describes the following
|
||||
feature:
|
||||
|
||||
"Fast interrupt handling through alternate register files (up to 4
|
||||
contexts) with standard stack compatible mode (for real time OS
|
||||
kernels)"
|
||||
|
||||
This feature was implemented by ST in the core but has to date never been
|
||||
included in any STM8 products. If it is included in future products then
|
||||
you will need to put the device in the stack compatible mode described.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
WRITING NEW INTERRUPT HANDLERS
|
||||
|
||||
All interrupt handlers which will call out to the OS kernel and potentially
|
||||
cause a thread switch must call atomIntEnter() and atomIntExit(). An
|
||||
example of this can be seen in the timer tick ISR in atomport.c.
|
||||
|
||||
You may also implement fast interrupt handlers in the system which do not
|
||||
call atomIntEnter()/atomIntExit(), however these ISRs cannot perform OS
|
||||
functions such as posting semaphores or effecting a thread switch.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
|
||||
61
ports/stm8/README-SDCC
Normal file
61
ports/stm8/README-SDCC
Normal file
@@ -0,0 +1,61 @@
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Author: Dr. Philipp Klaus Krause
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
STM8 PORT - SMALL DEVICE C COMPILER
|
||||
|
||||
This folder contains a port of the Atomthreads real time kernel for the
|
||||
STM8 processor architecture. These instructions cover usage of Atomthreads
|
||||
with the Small Device C Compiler (SDCC).
|
||||
|
||||
This README covers usage of Atomthreads with SDCC.
|
||||
Instructions for users of the other compilers are available in README-COSMIC,
|
||||
README-IAR and README-RAISONANCE.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
PREREQUISITES
|
||||
|
||||
The port works out-of-the-box with SDCC and GNU make for
|
||||
building.
|
||||
|
||||
* SDCC 3.6.0 or later
|
||||
* Programming software (e.g. stm8flash)
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
BUILD VIA MAKEFILE
|
||||
|
||||
* make -f sdcc.mak
|
||||
|
||||
All objects are built into the 'build-sdcc' folder under ports/stm8.
|
||||
The build process builds separate target applications for each automated
|
||||
test, and appropriate .ihx files can be found in the build folder
|
||||
ready for downloading to and running on the target. Because of the limited
|
||||
resources on the STM8, and the large amount of automated tests, each test
|
||||
is built and run as a separate application.
|
||||
|
||||
All built objects etc can be cleaned using:
|
||||
|
||||
* make -f sdcc.mak clean
|
||||
|
||||
The Atomthreads sources are documented using Doxygen markup. You can build
|
||||
both the kernel and STM8 port documentation from this folder using:
|
||||
|
||||
* make -f raisonance.mak doxygen
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
PROGRAMMING MAKEFILE-BUILT APPLICATIONS TO THE TARGET DEVICE
|
||||
|
||||
Applications can be written onto the STM8S-Discovery board using:
|
||||
|
||||
* stm8flash -c stlink -p stm8s105c6 -w <filename>
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
48
ports/stm8/atomport-asm-sdcc.s
Normal file
48
ports/stm8/atomport-asm-sdcc.s
Normal file
@@ -0,0 +1,48 @@
|
||||
; Copyright (c) 2016 Dr. Philipp Klaus Krause
|
||||
|
||||
; Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
; The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
.area CODE
|
||||
|
||||
; uint8_t get_cc(void);
|
||||
_get_cc::
|
||||
push cc
|
||||
pop a
|
||||
ret
|
||||
|
||||
; void set_cc(uint8_t);
|
||||
_set_cc::
|
||||
ld a, (3, sp)
|
||||
push a
|
||||
pop cc
|
||||
ret
|
||||
|
||||
; void archContextSwitch (ATOM_TCB *old_tcb_ptr, ATOM_TCB *new_tcb_ptr)
|
||||
_archContextSwitch::
|
||||
|
||||
; save context
|
||||
ldw x, (3, sp)
|
||||
ldw y, sp
|
||||
ldw (x), y
|
||||
|
||||
; restore context
|
||||
ldw x, (5, sp)
|
||||
ldw x, (x)
|
||||
ldw sp, x
|
||||
|
||||
ret
|
||||
|
||||
; void archFirstThreadRestore (ATOM_TCB *new_tcb_ptr)
|
||||
_archFirstThreadRestore::
|
||||
|
||||
; restore context
|
||||
ldw x, (3, sp)
|
||||
ldw x, (x)
|
||||
ldw sp, x
|
||||
|
||||
ret
|
||||
|
||||
@@ -64,13 +64,18 @@
|
||||
#define INTERRUPT @far @interrupt @svlreg
|
||||
#elif defined (__IAR_SYSTEMS_ICC__)
|
||||
#define INTERRUPT __interrupt
|
||||
#elif defined(__RCSTM8__)
|
||||
#elif defined(__RCSTM8__) || defined(__SDCC_stm8)
|
||||
#define INTERRUPT
|
||||
#endif
|
||||
|
||||
|
||||
/* Function prototypes */
|
||||
void archInitSystemTickTimer (void);
|
||||
#ifndef __SDCC_stm8
|
||||
INTERRUPT void TIM1_SystemTickISR (void);
|
||||
#else
|
||||
void TIM1_SystemTickISR (void) __interrupt(11);
|
||||
#endif
|
||||
|
||||
#endif /* __ATOM_PORT_PRIVATE_H */
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
#define _STR
|
||||
|
||||
/* Default thread stack size (in bytes) */
|
||||
#define TEST_THREAD_STACK_SIZE 128
|
||||
#define TEST_THREAD_STACK_SIZE 192
|
||||
|
||||
/* Uncomment to enable logging of stack usage to UART */
|
||||
#define TESTS_LOG_STACK_USAGE
|
||||
|
||||
@@ -95,6 +95,8 @@ static NO_REG_SAVE void thread_shell (void)
|
||||
rim();
|
||||
#elif defined(__RCSTM8__)
|
||||
_rim_();
|
||||
#elif defined(__SDCC_stm8)
|
||||
__asm__("rim");
|
||||
#endif
|
||||
|
||||
/* Call the thread entry point */
|
||||
@@ -293,6 +295,9 @@ void archInitSystemTickTimer ( void )
|
||||
INTERRUPT void TIM1_SystemTickISR (void)
|
||||
#if defined(__RCSTM8__)
|
||||
interrupt 11
|
||||
|
||||
#elif defined(__SDCC_stm8)
|
||||
__interrupt(11)
|
||||
#endif
|
||||
{
|
||||
/* Call the interrupt entry routine */
|
||||
@@ -307,3 +312,4 @@ interrupt 11
|
||||
/* Call the interrupt exit routine */
|
||||
atomIntExit(TRUE);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Kelvin Lawson. All rights reserved.
|
||||
* Copyright (c) 2016, Dr. Philipp Klaus Krause.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -45,20 +46,23 @@
|
||||
/* Required number of system ticks per second (normally 100 for 10ms tick) */
|
||||
#define SYSTEM_TICKS_PER_SEC 100
|
||||
|
||||
/* Size of each stack entry / stack alignment size (8 bits on STM8) */
|
||||
#define STACK_ALIGN_SIZE sizeof(u8)
|
||||
|
||||
/**
|
||||
* Architecture-specific types.
|
||||
*/
|
||||
#if defined(__CSMC__) || defined (__RCSTM8__) /* Cosmic and Raisonance do not have the C99 stdint.h header*/
|
||||
#define int8_t s8
|
||||
#define int16_t s16
|
||||
#define int32_t s32
|
||||
#define uint8_t u8
|
||||
#define uint16_t u16
|
||||
#define uint32_t u32
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#define POINTER void *
|
||||
|
||||
/* Size of each stack entry / stack alignment size (8 bits on STM8) */
|
||||
#define STACK_ALIGN_SIZE sizeof(uint8_t)
|
||||
|
||||
/**
|
||||
* Critical region protection: this should disable interrupts
|
||||
@@ -84,6 +88,14 @@
|
||||
#define CRITICAL_STORE unsigned char ccr
|
||||
#define CRITICAL_START() ccr = _getCC_(); _sim_()
|
||||
#define CRITICAL_END() _setCC_(ccr)
|
||||
|
||||
/* SDCC: Use custom function */
|
||||
#elif defined(__SDCC_stm8)
|
||||
uint8_t get_cc(void);
|
||||
void set_cc(uint8_t);
|
||||
#define CRITICAL_STORE uint8_t ccr
|
||||
#define CRITICAL_START() ccr = get_cc(); __asm__("sim")
|
||||
#define CRITICAL_END() set_cc(ccr)
|
||||
#endif
|
||||
|
||||
/* Uncomment to enable stack-checking */
|
||||
|
||||
107
ports/stm8/sdcc.mak
Normal file
107
ports/stm8/sdcc.mak
Normal file
@@ -0,0 +1,107 @@
|
||||
KERNEL_DIR=../../kernel
|
||||
TESTS_DIR=../../tests
|
||||
PERIPHS_DIR=stm8s-periphs
|
||||
|
||||
CC=sdcc
|
||||
ASM=sdasstm8
|
||||
LINK=sdcc
|
||||
|
||||
# CPU part number
|
||||
PART=STM8S105
|
||||
|
||||
# Enable stack-checking
|
||||
STACK_CHECK=true
|
||||
|
||||
# Directory for built objects
|
||||
BUILD_DIR=build-sdcc
|
||||
|
||||
# Port/application object files
|
||||
APP_OBJECTS = atomport.rel tests-main.rel uart.rel
|
||||
APP_ASM_OBJECTS = atomport-asm-sdcc.rel
|
||||
|
||||
# STM8S Peripheral driver object files
|
||||
PERIPH_OBJECTS = stm8s_gpio.rel stm8s_tim1.rel stm8s_clk.rel stm8s_uart2.rel
|
||||
|
||||
# Kernel object files
|
||||
KERNEL_OBJECTS = atomkernel.rel atomsem.rel atommutex.rel atomtimer.rel atomqueue.rel
|
||||
|
||||
# Collection of built objects (excluding test applications)
|
||||
ALL_OBJECTS = $(APP_OBJECTS) $(APP_ASM_OBJECTS) $(PERIPH_OBJECTS) $(KERNEL_OBJECTS)
|
||||
BUILT_OBJECTS = $(patsubst %,$(BUILD_DIR)/%,$(ALL_OBJECTS))
|
||||
|
||||
# Test object files (dealt with separately as only one per application build)
|
||||
TEST_OBJECTS = $(notdir $(patsubst %.c,%.rel,$(wildcard $(TESTS_DIR)/*.c)))
|
||||
|
||||
# Target application filenames (.elf) for each test object
|
||||
TEST_HEXS = $(patsubst %.rel,%.ihx,$(TEST_OBJECTS))
|
||||
TEST_ELFS = $(patsubst %.rel,%.elf,$(TEST_OBJECTS))
|
||||
|
||||
# Search build/output directory for dependencies
|
||||
vpath %.rel .\$(BUILD_DIR)
|
||||
vpath %.elf .\$(BUILD_DIR)
|
||||
vpath %.hex .\$(BUILD_DIR)
|
||||
|
||||
# Compiler/Assembler flags
|
||||
CFLAGS= -mstm8 -c -D $(PART) --opt-code-size
|
||||
DBG_CFLAGS= -mstm8 -c -D $(PART) --opt-code-size
|
||||
ASMFLAGS= -loff
|
||||
DBG_ASMFLAGS= -loff
|
||||
LINKFLAGS= -mstm8
|
||||
DBG_LINKFLAGS= --debug -mstm8
|
||||
|
||||
# Enable stack-checking (disable if not required)
|
||||
ifeq ($(STACK_CHECK),true)
|
||||
CFLAGS += -D ATOM_STACK_CHECKING
|
||||
DBG_CFLAGS += --debug -D ATOM_STACK_CHECKING
|
||||
endif
|
||||
|
||||
#################
|
||||
# Build targets #
|
||||
#################
|
||||
|
||||
# All tests
|
||||
all: $(BUILD_DIR) $(TEST_HEXS) sdcc.mak
|
||||
|
||||
# Make build/output directory
|
||||
$(BUILD_DIR):
|
||||
mkdir $(BUILD_DIR)
|
||||
|
||||
# Test HEX files (one application build for each test)
|
||||
$(TEST_HEXS): %.ihx: %.rel $(KERNEL_OBJECTS) $(PERIPH_OBJECTS) $(APP_OBJECTS) $(APP_ASM_OBJECTS)
|
||||
$(LINK) $(BUILD_DIR)/$(notdir $<) $(BUILT_OBJECTS) $(LINKFLAGS) -o $(BUILD_DIR)/$@
|
||||
|
||||
# Test ELF files (one application build for each test)
|
||||
$(TEST_ELFS): %.elf: %.rel $(KERNEL_OBJECTS) $(PERIPH_OBJECTS) $(APP_OBJECTS) $(APP_ASM_OBJECTS)
|
||||
$(LINK) $(BUILD_DIR)/$(notdir $<) $(BUILT_OBJECTS) $(LINKFLAGS) --out-fmt-elf -o $(BUILD_DIR)/$@
|
||||
|
||||
# Kernel objects builder
|
||||
$(KERNEL_OBJECTS): %.rel: $(KERNEL_DIR)/%.c
|
||||
$(CC) $< $(CFLAGS) -I . -I $(PERIPHS_DIR) -o $(BUILD_DIR)/$*.rel
|
||||
|
||||
# Test objects builder
|
||||
$(TEST_OBJECTS): %.rel: $(TESTS_DIR)/%.c
|
||||
$(CC) $< $(CFLAGS) -I . -I $(KERNEL_DIR) -I $(PERIPHS_DIR) -o $(BUILD_DIR)/$*.rel
|
||||
|
||||
# Peripheral objects builder
|
||||
$(PERIPH_OBJECTS): %.rel: $(PERIPHS_DIR)/%.c
|
||||
$(CC) $< $(CFLAGS) -I . -I $(PERIPHS_DIR) -o $(BUILD_DIR)/$*.rel
|
||||
|
||||
# Application C objects builder
|
||||
$(APP_OBJECTS): %.rel: ./%.c
|
||||
$(CC) $< $(CFLAGS) -I . -I $(KERNEL_DIR) -I $(TESTS_DIR) -I $(PERIPHS_DIR) -o $(BUILD_DIR)/$*.rel
|
||||
|
||||
# Application asm objects builder
|
||||
$(APP_ASM_OBJECTS): %.rel: ./%.s
|
||||
$(ASM) $(ASMFLAGS) $(BUILD_DIR)/$(notdir $@) $<
|
||||
|
||||
# Clean
|
||||
clean:
|
||||
rm -f *.o *.elf *.map *.hex *.bin *.lst *.stm8 *.s19
|
||||
rm -rf doxygen-kernel
|
||||
rm -rf doxygen-stm8
|
||||
rm -rf build-sdcc
|
||||
|
||||
doxygen:
|
||||
doxygen $(KERNEL_DIR)/Doxyfile
|
||||
doxygen ./Doxyfile
|
||||
|
||||
@@ -30,15 +30,23 @@
|
||||
#if defined(__CSMC__)
|
||||
#undef _RAISONANCE_
|
||||
#undef _IAR_SYSTEMS_
|
||||
#undef _SDCC_
|
||||
#define _COSMIC_
|
||||
#elif defined(__RCST7__)
|
||||
#undef _COSMIC_
|
||||
#undef _IAR_SYSTEMS_
|
||||
#undef _SDCC_
|
||||
#define _RAISONANCE_
|
||||
#elif defined(__IAR_SYSTEMS_ICC__)
|
||||
#undef _COSMIC_
|
||||
#undef _RAISONANCE_
|
||||
#undef _SDCC_
|
||||
#define _IAR_SYSTEMS_
|
||||
#elif defined(__SDCC_stm8)
|
||||
#undef _COSMIC_
|
||||
#undef _RAISONANCE_
|
||||
#undef _IAR_SYSTEMS_
|
||||
#define _SDCC_
|
||||
#else
|
||||
#error "Unsupported Compiler!" /* Compiler defines not found */
|
||||
#endif
|
||||
@@ -90,6 +98,11 @@
|
||||
#define __CONST const
|
||||
#endif
|
||||
|
||||
#ifdef _SDCC_
|
||||
#define NEAR
|
||||
#define __CONST const
|
||||
#endif
|
||||
|
||||
#ifdef PointerAttr_Far
|
||||
#define PointerAttr FAR
|
||||
#else /* PointerAttr_Near */
|
||||
|
||||
@@ -39,6 +39,10 @@
|
||||
* None
|
||||
* @retval u8 Content of CC register (in A register).
|
||||
*/
|
||||
#ifdef __SDCC_stm8
|
||||
uint8_t get_cc(void);
|
||||
#endif
|
||||
|
||||
u8 ITC_GetCPUCC(void)
|
||||
{
|
||||
#ifdef _COSMIC_
|
||||
@@ -46,6 +50,10 @@ u8 ITC_GetCPUCC(void)
|
||||
_asm("pop a");
|
||||
return; /* Ignore compiler warning, the returned value is in A register */
|
||||
#endif
|
||||
|
||||
#ifdef __SDCC_stm8
|
||||
return get_cc();
|
||||
#endif
|
||||
|
||||
#ifdef _RAISONANCE_
|
||||
return _getCC_();
|
||||
|
||||
@@ -73,12 +73,12 @@
|
||||
* stack for application code local variables etc.
|
||||
*
|
||||
* With all OS tests implemented to date on the STM8, the Main thread
|
||||
* stack has not exceeded 256 bytes. To allow all tests to run we set
|
||||
* stack has not exceeded 384 bytes. To allow all tests to run we set
|
||||
* a minimum main thread stack size of 204 bytes. This may increase in
|
||||
* future as the codebase changes but for the time being is enough to
|
||||
* cope with all of the automated tests.
|
||||
*/
|
||||
#define MAIN_STACK_SIZE_BYTES 256
|
||||
#define MAIN_STACK_SIZE_BYTES 384
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -154,3 +154,19 @@ size_t __write(int handle, const unsigned char *buf, size_t bufSize)
|
||||
return (chars_written);
|
||||
}
|
||||
#endif /* __IAR_SYSTEMS_ICC__ */
|
||||
|
||||
#if defined(__SDCC_stm8)
|
||||
#if __SDCC_REVISION >= 9624
|
||||
int putchar (int c)
|
||||
{
|
||||
return(uart_putchar(c));
|
||||
}
|
||||
#else
|
||||
void putchar (char c)
|
||||
{
|
||||
uart_putchar(c);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user