13 Commits

Author SHA1 Message Date
Kelvin Lawson
916dc11a0c STM8: Add README for Raisonance RKit-STM8 RTOS port. 2010-06-28 22:38:48 +01:00
Kelvin Lawson
b4bc5a9c53 STM8: Add Raisonance Makefile. 2010-06-28 21:33:16 +01:00
Kelvin Lawson
e218dbb7be STM8: Update Makefile comments. 2010-06-22 00:19:55 +01:00
Kelvin Lawson
545a6932a4 STM8: Rename STVD sample workspace to atomthreads-sample-stvd.stw. This now contains separate projects for both the Cosmic and Raisonance compilers. 2010-06-21 22:32:41 +01:00
Kelvin Lawson
912c83f74e STM8: Add Raisonance sample project. 2010-06-21 22:21:31 +01:00
Kelvin Lawson
e34c5a0ffa STM8: Add Raisonance STM8 assembler layer. 2010-06-21 22:11:13 +01:00
Kelvin Lawson
9e4da88b1d STM8: Add support for Raisonance STM8 compiler in C RTOS port layer. 2010-06-21 21:52:28 +01:00
Kelvin Lawson
d25a49edeb STM8: Macro to specify interrupt handlers on Raisonance STM8. 2010-06-21 21:47:11 +01:00
Kelvin Lawson
c9ae8200db STM8: Add UART putchar() for Raisonance STM8 compiler. 2010-06-21 21:43:53 +01:00
Kelvin Lawson
61e6ca0b10 STM8: Add critical region macros for Raisonance STM8 compiler. 2010-06-21 21:43:07 +01:00
Kelvin Lawson
b79c5c7f44 kernel/atomkernel.c: Formatting changes. 2010-06-21 21:39:59 +01:00
Kelvin Lawson
2ec7fd2d8c STM8: Rename "data" parameters to "param" (Raisonance STM8 does not allow parameters named "data"). 2010-06-07 21:30:16 +01:00
Kelvin Lawson
eafe07cea9 TESTS: Function parameters cannot be named "data" when using Raisonance STM8 compiler. 2010-06-07 21:13:25 +01:00
43 changed files with 1750 additions and 144 deletions

View File

@@ -28,7 +28,7 @@
*/
/**
/**
* \file
* Kernel library.
*
@@ -114,7 +114,7 @@
* run since the thread was created. The context-save area is formatted in
* exactly the same manner.
*
*
*
* \b Functions contained in this module:\n
*
* \b Application-callable initialisation functions: \n
@@ -501,7 +501,7 @@ uint8_t atomThreadCreate (ATOM_TCB *tcb_ptr, uint8_t priority, void (*entry_poin
* have strayed outside of the allowable stack area while leaving some of
* the known-value bytes unmodified. This simple method cannot trap stack
* usage outside of the thread's allocated stack, for which you could use
* additional guard areas (still limited in scope) or compiler/CPU/MMU
* additional guard areas (still limited in scope) or compiler/CPU/MMU
* features.
*
* The function takes a thread's TCB and returns both the number of stack

View File

@@ -44,12 +44,13 @@ 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 both the Cosmic 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 IAR compiler are available in README-IAR.
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.
---------------------------------------------------------------------------
@@ -76,7 +77,7 @@ The core software prerequisites are therefore:
Optionally, application build, program and debug can be carried out
using ST's visual debug tool, STVD.
Use with alternative compiler tools will require some modification, but you
Use with alternative compiler tools may require some modification, but you
can easily replace STVP by your own favourite programmer if required.
@@ -115,13 +116,15 @@ automated tests.
BUILD VIA STVD PROJECT
For building applications using STVD you can use the sample project file
atomthreads-sample-cosmic.stw. This builds a sample full application which
runs the "sem1" automated test. Applications can be downloaded directly to
the target hardware (e.g. STM8S-Discovery) and run via the integrated
debugger. Press the exclamation button to run, and confirm that the LED
flashes once per second (if running on an STM8S-Discovery) to ensure that
the test has passed.
For building applications using STVD you can use the sample workspace
atomthreads-sample-stvd.stw which contains both Cosmic compiler and
Raisonance compiler based projects. You can also import the Cosmic-only
project file atomthreads-sample-cosmic.stp directly. This builds a sample
full application which runs the "sem1" automated test. Applications can be
downloaded directly to the target hardware (e.g. STM8S-Discovery) and run
via the integrated debugger. Press the exclamation button to run, and
confirm that the LED flashes once per second (if running on an
STM8S-Discovery) to ensure that the test has passed.
This is also a good starting point for building your own applications:
simply modify the file tests-main.c which starts the test application.
@@ -301,8 +304,8 @@ initialises the OS, sets up a UART and calls out to the test module entry
functions. You can generally simply replace the call to the test modules by
a call to your own application startup code.
Projects developed within STVD can be started using the sample workspace
atomthreads-sample-cosmic.stw. If you wish to create your own STVD project
Projects developed within STVD can be started using the sample project
atomthreads-sample-cosmic.stp. If you wish to create your own STVD project
from scratch, then you should ensure you change the project settings for
both Debug and Release builds as follows:

View File

@@ -43,12 +43,13 @@ 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 both the Cosmic 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 Cosmic compiler are available in README-COSMIC.
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.
---------------------------------------------------------------------------
@@ -70,7 +71,7 @@ such as VirtualBox, including USB download and debug.
The core software prerequisites are therefore:
* IAR Embedded Workbench STM8
Use with alternative compiler tools will require some modification, but you
Use with alternative compiler tools may require some modification, but you
can easily replace the EWSTM8 IDE by your own favourite programmer if
required (e.g. STVP).

View File

@@ -0,0 +1,452 @@
---------------------------------------------------------------------------
Library: Atomthreads
Author: Kelvin Lawson <kelvinl@users.sf.net>
Website: http://atomthreads.com
License: BSD Revised
---------------------------------------------------------------------------
STM8 PORT - RAISONANCE 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 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:
* 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:
* atomuser.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.
---------------------------------------------------------------------------
PREREQUISITES
The port works out-of-the-box with the Raisonance compiler tools for
building. Applications are generated in .hex form and can be programmed
with any supporting programming software, including the free STVP (visual
programmer tool). At this time there does not appear to be a command-line
programmer application suitable for use with STM8.
The Raisonance compiler and STVP are currently Windows-only applications.
For users of other operating systems the Raisonance compiler may work in
environments like Wine, but the USB programming tools are less likely to
be supported. Both the compiler and the USB programming tool for
STM8S-Discovery (STVP) can, however, be run successfully within a VM such
as VirtualBox.
The core software prerequisites are therefore:
* Raisonance STM8 compiler
* Programming software (e.g. ST's STVP tool)
Optionally, application build, program and debug can be carried out
using ST's visual debug tool, STVD.
Use with alternative compiler tools may require some modification, but you
can easily replace STVP by your own favourite programmer if required.
---------------------------------------------------------------------------
MEMORY MODEL
The sample build configurations use the Small memory model. All global
variables are placed in the Data section rather than page0, which allows
for large arrays such as thread stacks which would not fit in page0.
---------------------------------------------------------------------------
BUILDING THE SOURCE
You may build Atomthreads using whichever build environment you desire. For
your convenience we provide both a ready-rolled Makefile-based build system
and an STVD visual debugger project. The STVD project permits easy
building, programming and debugging, but does not easily support building
a wide range of application builds within the same project, which is
useful for building the numerous automated tests. For the automated tests
you may find it easier to use the Makefile which automatically builds all
automated tests.
---------------------------------------------------------------------------
BUILD VIA STVD PROJECT
For building applications using STVD you can use the sample workspace
atomthreads-sample-stvd.stw which contains both Cosmic compiler and
Raisonance compiler based projects. You can also import the
Raisonance-only project file atomthreads-sample-raisonance.stp directly.
This builds a sample full application which runs the "sem1" automated test.
Applications can be downloaded directly to the target hardware (e.g.
STM8S-Discovery) and run via the integrated debugger. Press the
exclamation button to run, and confirm that the LED flashes once per
second (if running on an STM8S-Discovery) to ensure that the test has
passed.
This is also a good starting point for building your own applications:
simply modify the file tests-main.c which starts the test application.
You can run any of the other automated tests by replacing the file sem1.c
within the project by another of the tests within the atomthreads tests
folder. This is rather painful using a GUI interface due to the large
number of test files, and you may prefer to use the Makefile-based system
instead which builds all automated tests in one command.
---------------------------------------------------------------------------
BUILD VIA MAKEFILE
A Makefile is also provided for building the kernel, port and automated
tests. This is particularly useful for building the automated tests
because many different independent applications need to be built which is
not easily achieved within the STVD environment.
For a Windows system you can obtain a Make application suitable for use
with the Raisonance compiler from:
* http://www.cosmic-software.com/comp_utils/GNU_Make.zip
Assuming you install the above into C:\Program Files\GNU_MAKE, you
should set up your environment variables as follows:
* set PATH=%PATH%;C:\Program Files\GNU_MAKE;C:\Program Files\Raisonance\Ride\bin
* set MAKE_MODE=DOS
The full build is carried out using simply:
* make -f raisonance.mak
All objects are built into the 'build-raisonance' folder under ports/stm8.
The build process builds separate target applications for each automated
test, and appropriate .aof or .hex 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 raisonance.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
When developing within STVD, programs can be downloaded directly to the
target. If, however, you are building applications separately using a
Makefile or similar, then you are not able to program the application
using STVD. None of the tools delivered by ST appear to be designed to
cater for those who build applications externally, but it is possible using
STVP.
The following development workflow can be used (note that these settings
apply to the STM8S-Discovery):
* Build app using Makefile.
* Open STVP and configure to use Swim ST-Link for CPU STM8105C6.
* Open application .hex file and program using "Program All Tabs".
Unfortunately STVP does not have a command to reset and start the CPU
running, but it can be forced into doing so by reconfiguring the
programmer:
* Select "Configure ST Visual Programmer" from the Configure menu.
Your application should now be programmed and running.
If you wish to program and run another application then you can open and
program it in STVP, then use the Configure menu again to reset the
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 TX: CN4 pin 10 (connect to RX at the PC end)
UART RX: CN4 pin 9 (connect to TX 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
Atomthreads contains a set of generic kernel tests which can be run on any
port to prove that all core functionality is working on your target.
The full set of tests can be found in the top-level 'tests' folder. The
Makefile builds each of these tests as independent applications in the
'build' folder. Run them individually using the STVP process described
above. For example to run the 'kern1.c' test use STVP to program and run
it.
You may also build the tests using the STVD project, but to run each
different test you must manually remove the previous test module (e.g.
kern1.c) and replace it with one of other tests, which can be quite time
consuming compared to building all tests in one command via the Makefile.
To view the test results, watch the LED on the STM8S-Discovery. This will
flash once per second if the test passed, and once every 1/8 second if the
test failed.
If you wish to use the UART, connect a serial debug cable to your target
platform (defaults to 9600bps 8N1). On starting, the test applications
print out "Go" on the UART. Once the test is complete they will print
out "Pass" or "Fail", along with other information if the test failed.
Most of the tests complete within a few seconds, but some (particularly
the stress tests) can take several seconds, so be patient.
The full suite of tests endeavours to exercise as much of the kernel code
as possible, and can be used for quick confirmation of core OS
functionality if you ever need to make a change to the kernel or port.
The test application main() is contained in tests-main.c. This initialises
the OS, creates a main thread, and calls out to the test modules. It also
initialises the UART driver for use by stdout.
---------------------------------------------------------------------------
WRITING APPLICATIONS
The easiest way to start a new application which utilises the Atomthreads
scheduler is to base your main application startup on tests-main.c. This
initialises the OS, sets up a UART and calls out to the test module entry
functions. You can generally simply replace the call to the test modules by
a call to your own application startup code.
Projects developed within STVD can be started using the sample project
atomthreads-sample-raisonance.stp. If you wish to create your own STVD
project from scratch, then you should ensure you change the project settings
for both Debug and Release builds as follows:
* Toolset: "Raisonance"
* MCU Selection: Appropriate for your platform (STM8S10C56 for Discovery)
* C Compiler Memory Model: "Small"
* C Compiler Preprocessor Definitions: CPU part (e.g. "STM8S105")
* C Compiler Preprocessor Definitions: Enable thread stack checking if
desired by adding "ATOM_STACK_CHECKING", for example the full
preprocessor line for Discovery might be: "STM8S105 ATOM_STACK_CHECKING"
* Linker Input: You may need to change the DATA setion to start from 0x1
rather than 0x0 to prevent the linker from placing OS data at address
0x0 (which would cause NULL-pointer checks to fail). So far this has
not actually proved necessary, however.
Note that for an RTOS like this the Raisonance compiler must place all
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.
---------------------------------------------------------------------------
RAISONANCE COMPILER VIRTUAL REGISTERS
The STM8 has only very few CPU registers, so the Raisonance compiler
augments them with four "virtual" registers, which are simply locations in
fast memory. These registers are called BH, BL, CH and CL.
The Atomthreads context switch for Raisonance/STM8 takes advantage of the
fact that all CPU and virtual registers are automatically saved on the
stack by the compiler when calling out to C functions (and even then only
if necessary).
For cooperative context switches (where a thread calls an OS kernel
function to schedule itself out), any of these registers which should be
preserved across the function call are automatically saved on the stack by
the compiler before the context switch is even called. This means that no
CPU or virtual registers actually have to be saved in the context switch
routine, making cooperative switches potentially very cheap if few
registers must be preserved.
For preemptive switches (where an ISR has interrupted a thread and wishes
to switch to a new thread), the interrupt handler prologue automatically
saves all CPU registers (actually done automatically by the CPU) and all
of the virtual registers. In this case all registers must always be saved
because the ISR has no knowledge of what registers the interrupted thread
was using, so we cannot take advantage of the potential for saving fewer
than the full set of registers that we achieve with cooperative switches.
---------------------------------------------------------------------------

View File

@@ -0,0 +1,368 @@
;
; Copyright (c) 2010, Atomthreads Project. All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; Modification, are permitted provided that the following conditions
; are met:
;
; 1. Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; 2. Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; 3. No personal names or organizations' names associated with the
; Atomthreads project may be used to endorse or promote products
; derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT AND CONTRIBUTORS
; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
; TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE
; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
; POSSIBILITY OF SUCH DAMAGE.
;
; Raisonance assembler routines
;Distinguish STM8 mode from ST7
$modestm8
; Export functions to other modules
PUBLIC ?archContextSwitch, ?archFirstThreadRestore
; Locate in code segment
MYSEG SEGMENT CODE
RSEG MYSEG
; \b archContextSwitch
;
; Architecture-specific context switch routine.
;
; Note that interrupts are always locked out when this routine is
; called. For cooperative switches, the scheduler will have entered
; a critical region. For preemptions (called from an ISR), the
; ISR will have disabled interrupts on entry.
;
; @param[in] old_tcb_ptr Pointer to the thread being scheduled out
; @param[in] new_tcb_ptr Pointer to the thread being scheduled in
;
; @return None
;
; void archContextSwitch (ATOM_TCB *old_tcb_ptr, ATOM_TCB *new_tcb_ptr)
?archContextSwitch:
; Parameter locations (Raisonance calling convention):
; old_tcb_ptr = X register (word-width)
; new_tcb_ptr = stack (word-width)
; STM8 CPU Registers:
;
; A, X, Y: Standard working registers
; SP: Stack pointer
; PC: Program counter
; CC: Code condition register
;
; Raisonance compiler virtual registers:
;
; BH, BL, CH, CL: Compiler working registers in page0
;
; If this is a cooperative context switch (a thread has called us
; to schedule itself out), the Raisonance compiler will have saved any
; of the registers which it does not want us to clobber. There are
; no registers which are expected to retain their value across a
; function call, hence for cooperative context switches with this
; compiler we do not actually need to save any registers at all.
;
; If we were called from an interrupt routine (because a thread
; is being preemptively scheduled out), the situation is exactly
; the same. Any ISR which calls out to a subroutine will have
; similarly saved all registers which it needs us not to clobber
; which in the case of this compiler is all registers. Again, we
; do not need to save any registers because no registers are
; expected to be unclobbered by a subroutine.
;
; This is an unusual context switch routine, because it does not
; need to actually save any registers. Instead, the act of
; calling this function causes all registers which must not be
; clobbered to be saved on the stack anyway in the case of
; cooperative context switches. For preemptive switches, the
; interrupt service routine which calls out to here also causes
; all registers to be saved in a similar fashion.
; We do have to do some work in here though: we need to store
; the current stack pointer to the current thread's TCB, and
; switch in the new thread by taking the stack pointer from
; the new thread's TCB and making that our new stack pointer.
; The parameter pointing to the the old TCB (a word-width
; pointer) is still untouched in the X register.
; Store current stack pointer as first entry in old_tcb_ptr
ldw Y, SP ; Move current stack pointer into Y register
ldw (X), Y ; Store current stack pointer at first offset in TCB
; At this point, all of the current thread's context has been saved
; so we no longer care about keeping the contents of any registers.
; We do still need the first two bytes on the current thread's stack,
; however, which contain new_tcb_ptr (a pointer to the TCB of the
; thread which we wish to switch in).
;
; Our stack frame now contains all registers (if this is a preemptive
; switch due to an interrupt handler) or those registers which the
; calling function did not wish to be clobbered (if this is a
; cooperative context switch). It also contains the return address
; which will be either a function called via an ISR (for preemptive
; switches) or a function called from thread context (for cooperative
; switches). Finally, the stack also contains the aforementioned
; word which is the new_tcb_ptr parameter passed via the stack.
;
; In addition, the thread's stack pointer (after context-save) is
; stored in the thread's TCB.
; We are now ready to restore the new thread's context. In most
; architecture ports we would typically switch our stack pointer
; to the new thread's stack pointer, and pop all of its context
; off the stack, before returning to the caller (the original
; caller when the new thread was last scheduled out). In this
; port, however, we do not need to actually restore any
; registers here because none are saved when we switch out (at
; least not by this function). We switch to the new thread's
; stack pointer and then return to the original caller, which
; will restore any registers which had to be saved.
; Get the new thread's stack pointer off the TCB (new_tcb_ptr).
; new_tcb_ptr is still stored in the previous thread's stack.
; We are free to use any registers here.
; Pull the new_tcb_ptr parameter from the stack into X register
ldw X,(3,SP)
; Pull the first entry out of new_tcb_ptr (the new thread's
; stack pointer) into X register.
ldw X,(X)
; Switch our current stack pointer to that of the new thread.
ldw SP,X
; Normally we would start restoring registers from the new
; thread's stack here, but we don't save/restore any. We're
; almost done.
; The return address on the stack will now be the new thread's return
; address - i.e. although we just entered this function from a
; function called by the old thread, now that we have restored the new
; thread's stack, we actually return from this function to wherever
; the new thread was when it was previously scheduled out. This could
; be either a regular C routine if the new thread previously scheduled
; itself out cooperatively, or it could be an ISR if this new thread was
; previously preempted (on exiting the ISR, execution will return to
; wherever the new thread was originally interrupted).
; Return to the caller. Note that we always use a regular RET here
; because this is a subroutine regardless of whether we were called
; during an ISR or by a thread cooperatively switching out. The
; difference between RET and IRET on the STM8 architecture is that
; RET only pops the return address off the stack, while IRET also
; pops from the stack all of the CPU registers saved when the ISR
; started, including restoring the interrupt-enable bits from the CC
; register.
;
; It is important that whenever we call this function (whether from
; an ISR for preemptive switches or from thread context for
; cooperative switches) interrupts are always disabled. This means
; that whichever method by which we leave this routine we always
; have to reenable interrupts, so we can use the same context-switch
; routine for preemptive and cooperative switches.
;
; The possible call/return paths are as follows:
;
; Scenario 1 (cooperative -> cooperative):
; Thread A: cooperatively switches out
; * Thread A relinquishes control / cooperatively switches out
; * Interrupts already disabled by kernel for cooperative reschedules
; * Partial register context saved by calling function
; * Call here at thread context
; * Switch to Thread B
; Thread B (was previously cooperatively switched out):
; * Stack context for Thread B contains its return address
; * Return to function which was called at thread context
; * Interrupts are reenabled by CRITICAL_END() call in kernel
; * Return to Thread B application code
;
; Scenario 2 (preemptive -> preemptive):
; Thread A: preemptively switches out
; * ISR occurs
; * Interrupts disabled by CPU at ISR entry (assume no nesting allowed)
; * Full register context saved by CPU at ISR entry
; * Call here at ISR context
; * Switch to Thread B
; Thread B (was previously preemptively switched out):
; * Stack context for Thread B contains its return address
; and all context saved by the CPU on ISR entry
; * Return to function which was called at ISR context
; * Eventually returns to calling ISR which calls IRET
; * IRET performs full register context restore
; * IRET reenables interrupts
; * Return to Thread B application code
;
; Scenario 3 (cooperative -> preemptive):
; Thread A: cooperatively switches out
; * Thread A relinquishes control / cooperatively switches out
; * Interrupts already disabled by kernel for cooperative reschedules
; * Partial register context saved by calling function
; * Call here at thread context
; * Switch to Thread B
; Thread B (was previously preemptively switched out):
; * Stack context for Thread B contains its return address
; and all context saved by the CPU on ISR entry
; * Return to function which was called at ISR context
; * Eventually returns to calling ISR which calls IRET
; * IRET performs full register context restore
; * IRET reenables interrupts
; * Return to Thread B application code
;
; Scenario 4 (preemptive -> cooperative):
; Thread A: preemptively switches out
; * ISR occurs
; * Interrupts disabled by CPU at ISR entry (assume no nesting allowed)
; * Full register context saved by CPU at ISR entry
; * Call here at ISR context
; * Switch to Thread B
; Thread B (was previously cooperatively switched out):
; * Stack context for Thread B contains its return address
; * Return to function which was called at thread context
; * Interrupts are reenabled by CRITICAL_END() call in kernel
; * Return to Thread B application code
;
; The above shows that it does not matter whether we are rescheduling
; from/to thread context or ISR context. It is perfectly valid to
; enter here at ISR context but leave via a thread which previously
; cooperatively switched out because:
; 1. Although the CPU handles ISRs differently by automatically
; stacking all 6 CPU registers, and restoring them on an IRET,
; we handle this because we switch the stack pointer to a
; different thread's stack. Because the stack pointer is
; switched, it does not matter that on entry via ISRs more
; registers are saved on the original thread's stack than entries
; via non-ISRs. Those extra registers will be restored properly
; by an IRET when the thread is eventually scheduled back in
; (which could be a long way off). This assumes that the CPU does
; not have hidden behaviour that occurs on interrupts, and we can
; in fact trick it into leaving via another thread's call stack,
; and performing the IRET much later.
; 2. Although the CPU handles ISRs differently by setting the CC
; register interrupt-enable bits on entry/exit, we handle this
; anyway by always assuming interrupts are disabled on entry
; and exit regardless of the call path.
; Return from subroutine
ret
; \b archFirstThreadRestore
;
; Architecture-specific function to restore and start the first thread.
; This is called by atomOSStart() when the OS is starting. Its job is to
; restore the context for the first thread and start running at its
; entry point.
;
; All new threads have a stack context pre-initialised with suitable
; data for being restored by either this function or the normal
; function used for scheduling threads in, archContextSwitch(). Only
; the first thread run by the system is launched via this function,
; after which all other new threads will first be run by
; archContextSwitch().
;
; Typically ports will implement something similar here to the
; latter half of archContextSwitch(). In this port the context
; switch does not restore many registers, and instead relies on the
; fact that returning from any function which called
; archContextSwitch() will restore any of the necessary registers.
; For new threads which have never been run there is no calling
; function which will restore context on return, therefore we
; do not restore many register values here. It is not necessary
; for the new threads to have initialised values for the scratch
; registers A, X and Y or the code condition register CC which
; leaves SP and PC. SP is restored because this is always needed to
; switch to a new thread's stack context. It is not necessary to
; restore PC, because the thread's entry point is in the stack
; context (when this function returns using RET the PC is
; automatically changed to the thread's entry point because the
; entry point is stored in the preinitialised stack).
;
; When new threads are started interrupts must be enabled, so there
; is some scope for enabling interrupts in the CC here. It must be
; done for all new threads, however, not just the first thread, so
; we use a different system. We instead use a thread shell routine
; which all functions run when they are first started, and
; interrupts are enabled in there. This allows us to avoid having
; to enable interrupts both in here and in the normal context
; switch routine (archContextSwitch()). For the normal context
; switch routine we would otherwise need to pass in notification of
; and implement special handling for the first time a thread is
; restored.
;
; In summary, first threads do not require a set of CPU registers
; to be initialised to known values, so we only set SP to the new
; thread's stack pointer. PC is restored for free because the RET
; call at the end of this function pops the return address off the
; stack.
;
; Note that you can create more than one thread before starting
; the OS - only one thread is restored using this function, so
; all other threads are actually restored by archContextSwitch().
; This is another reminder that the initial context set up by
; archThreadContextInit() must look the same whether restored by
; archFirstThreadRestore() or archContextSwitch().
;
; @param[in] new_tcb_ptr Pointer to the thread being scheduled in
;
; @return None
;
; void archFirstThreadRestore (ATOM_TCB *new_tcb_ptr)
?archFirstThreadRestore:
; Parameter locations:
; new_tcb_ptr = X register (word-width)
; As described above, first thread restores in this port do not
; expect any initial register context to be pre-initialised in
; the thread's stack area. The thread's initial stack need only
; contain the thread's initial entry point, and we do not even
; "restore" that within this function. We leave the thread's entry
; point in the stack, and RET at the end of the function pops it
; off and "returns" to the entry point as if we were called from
; there.
;
; The one thing we do need to set in here, though, is the thread's
; stack pointer. This is available from the passed thread TCB
; structure.
; Get the new thread's stack pointer off the TCB (new_tcb_ptr).
; new_tcb_ptr is stored in the parameter register X. The stack
; pointer it conveniently located at the top of the TCB so no
; indexing is required to pull it out.
ldw X,(X)
; Switch our current stack pointer to that of the new thread.
ldw SP,X
; The "return address" left on the stack now will be the new
; thread's entry point. RET will take us there as if we had
; actually been there before calling this subroutine, whereas
; the return address was actually set up by archThreadContextInit().
ret
end

View File

@@ -55,11 +55,17 @@
* longs in any OS kernel code accessed by interrupt handlers.
*
* IAR: Uses __interrupt modifier for interrupt handlers.
*
* RAISONANCE: Uses no prefix modifier, but specifies
* interrupt vector after (see TIM1_SystemTickISR() for an
* example).
*/
#ifdef __CSMC__
#if defined(__CSMC__)
#define INTERRUPT @far @interrupt @svlreg
#else
#elif defined (__IAR_SYSTEMS_ICC__)
#define INTERRUPT __interrupt
#elif defined(__RCSTM8__)
#define INTERRUPT
#endif

View File

@@ -31,6 +31,9 @@
#include "atom.h"
#include "atomport-private.h"
#include "stm8s_tim1.h"
#if defined(__RCSTM8__)
#include <intrins.h>
#endif
/** Forward declarations */
@@ -90,6 +93,8 @@ static NO_REG_SAVE void thread_shell (void)
_asm("rim");
#elif defined(__IAR_SYSTEMS_ICC__)
rim();
#elif defined(__RCSTM8__)
_rim_();
#endif
/* Call the thread entry point */
@@ -112,8 +117,8 @@ static NO_REG_SAVE void thread_shell (void)
* and running the thread via archFirstThreadRestore() or
* archContextSwitch().
*
* (COSMIC) On this port we take advantage of the fact that when
* the context switch routine is called the compiler will
* (COSMIC & RAISONANCE) On this port we take advantage of the fact
* that when the context switch routine is called these compilers will
* automatically stack all registers which should not be clobbered.
* This means that the context switch need only save and restore the
* stack pointer, which is stored in the thread's TCB. Because of
@@ -208,8 +213,8 @@ void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, void (*entry_poi
#endif
/**
* (COSMIC) We do not initialise any registers via the initial
* stack context at all.
* (COSMIC & RAISONANCE) We do not initialise any registers via the
* initial stack context at all.
*/
/**
@@ -286,6 +291,9 @@ void archInitSystemTickTimer ( void )
#pragma vector = 13
#endif
INTERRUPT void TIM1_SystemTickISR (void)
#if defined(__RCSTM8__)
interrupt 11
#endif
{
/* Call the interrupt entry routine */
atomIntEnter();

View File

@@ -35,6 +35,8 @@
#if defined(__IAR_SYSTEMS_ICC__)
#include "intrinsics.h"
#elif defined (__RCSTM8__)
#include <intrins.h>
#endif
@@ -67,6 +69,12 @@
#define CRITICAL_STORE __istate_t _istate
#define CRITICAL_START() _istate = __get_interrupt_state(); __disable_interrupt()
#define CRITICAL_END() __set_interrupt_state(_istate)
/* Raisonance: Use intrinsics */
#elif defined(__RCSTM8__)
#define CRITICAL_STORE unsigned char ccr
#define CRITICAL_START() ccr = _getCC_(); _sim_()
#define CRITICAL_END() _setCC_(ccr)
#endif
/* Uncomment to enable stack-checking */

View File

@@ -5,7 +5,7 @@ Keyword=ST7Project
Number=1.3
[Project]
Name=atomthreads
Name=atomthreads-cosmic
Toolset=STM8 Cosmic
[Config]
@@ -26,7 +26,7 @@ Debug=$(TargetFName)
[Root]
ElemType=Project
PathName=atomthreads
PathName=atomthreads-cosmic
Child=Root.Kernel
Config.0=Root.Config.0
Config.1=Root.Config.1

View File

@@ -0,0 +1,545 @@
; STMicroelectronics Project file
[Version]
Keyword=ST7Project
Number=1.3
[Project]
Name=atomthreads-raisonance
Toolset=Raisonance
[Config]
0=Config.0
1=Config.1
[Config.0]
ConfigName=Debug
Target=$(ProjectSFile).elf
OutputFolder=Debug
Debug=$(TargetFName)
[Config.1]
ConfigName=Release
Target=$(ProjectSFile).elf
OutputFolder=Release
Debug=$(TargetFName)
[Root]
ElemType=Project
PathName=atomthreads-raisonance
Child=Root.Kernel
Config.0=Root.Config.0
Config.1=Root.Config.1
[Root.Config.0]
Settings.0.0=Root.Config.0.Settings.0
Settings.0.1=Root.Config.0.Settings.1
Settings.0.2=Root.Config.0.Settings.2
Settings.0.3=Root.Config.0.Settings.3
Settings.0.4=Root.Config.0.Settings.4
Settings.0.5=Root.Config.0.Settings.5
Settings.0.6=Root.Config.0.Settings.6
Settings.0.7=Root.Config.0.Settings.7
Settings.0.8=Root.Config.0.Settings.8
[Root.Config.1]
Settings.1.0=Root.Config.1.Settings.0
Settings.1.1=Root.Config.1.Settings.1
Settings.1.2=Root.Config.1.Settings.2
Settings.1.3=Root.Config.1.Settings.3
Settings.1.4=Root.Config.1.Settings.4
Settings.1.5=Root.Config.1.Settings.5
Settings.1.6=Root.Config.1.Settings.6
Settings.1.7=Root.Config.1.Settings.7
Settings.1.8=Root.Config.1.Settings.8
[Root.Config.0.Settings.0]
String.6.0=2010,2,10,16,13,19
String.100.0=ST Assembler Linker
String.100.1=ST7 Cosmic
String.100.2=STM8 Cosmic
String.100.3=ST7 Metrowerks V1.1
String.100.4=Raisonance
String.101.0=Raisonance
String.102.0=C:\Program Files\Raisonance\Ride
String.103.0=bin
String.104.0=INC\ST7;INC
String.105.0=LIB\ST7
String.106.0=Debug
String.107.0=$(ProjectSFile).elf
Int.108=0
[Root.Config.0.Settings.1]
String.6.0=2010,2,10,16,13,19
String.100.0=$(TargetFName)
String.101.0=
String.102.0=
String.103.0=.\;..\..\kernel;stm8s-periphs;..\..\tests;
[Root.Config.0.Settings.2]
String.2.0=
String.6.0=2010,2,10,16,13,19
String.100.0=STM8S105C6
[Root.Config.0.Settings.3]
String.2.0=Compiling $(InputFile)...
String.3.0=rcstm8 $(InputFile) OBJECT($(IntermPath)$(InputName).$(ObjectExt)) $(ToolsetIncOpts) WRV(0) STM8(SMALL) DEBUG DGC(data) AUTO -customSizeOpt -CustomOptimOT(7,SIZE) -CustomBasicLstPR($(IntermPath)$(InputName).lst) CD CO SB LAOB PIN(stm8s-periphs) PIN(../../kernel) PIN(../../tests) DF(STM8S105) DF(ATOM_STACK_CHECKING)
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
String.5.0=$(IntermPath)$(InputName).lst
String.6.0=2010,2,11,13,56,23
[Root.Config.0.Settings.4]
String.2.0=Assembling $(InputFile)...
String.3.0=mastm8 $(InputFile) OBJECT($(IntermPath)$(InputName).$(ObjectExt)) $(ToolsetIncOpts) QUIET ERRORPRINT DEBUG
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
String.5.0=$(IntermPath)$(InputName).lst
String.6.0=2010,2,10,16,13,19
[Root.Config.0.Settings.5]
String.2.0=Running Pre-Link step
String.6.0=2010,2,10,16,13,19
String.8.0=
[Root.Config.0.Settings.6]
String.2.0=Running Linker
String.3.0=rlstm8 $(ObjectFiles) TO($(OutputPath)$(TargetSName).aof) $(ToolsetLibOpts) -CustomOutFile[$(ProjectSFile).elf] -CustomRunHexConv DEBUGLINES DEBUGPUBLICS DEBUGSYMBOLS -customMapFile -customMapFile -customMapFilePR($(OutputPath)$(TargetSName).map)
String.3.1=omf2elf $(OutputPath)$(TargetSName).aof
String.4.0=$(OutputPath)$(TargetFName)
String.5.0=
String.6.0=2010,2,10,16,13,19
String.100.0=DATASTART(0x0) RAMSIZE(0x800) CODESTART(0x8000) CODESIZE(0x8000) STACKTOP(0x800) STACKSIZE(0x200) EEPROMSTART(0x4000) EEPROMSIZE(0x400)
String.101.0=
Int.0=0
Int.1=0
[Root.Config.0.Settings.7]
String.2.0=Running Post-Build step
String.3.0=omf2hex $(OutputPath)$(TargetSName).aof HEX
String.6.0=2010,2,10,16,13,19
[Root.Config.0.Settings.8]
String.2.0=Performing Custom Build on $(InputFile)
String.6.0=2010,2,10,16,13,19
[Root.Config.1.Settings.0]
String.6.0=2010,6,6,21,36,54
String.100.0=ST Assembler Linker
String.100.1=ST7 Cosmic
String.100.2=STM8 Cosmic
String.100.3=ST7 Metrowerks V1.1
String.100.4=Raisonance
String.101.0=Raisonance
String.102.0=C:\Program Files\Raisonance\Ride
String.103.0=bin
String.104.0=INC\ST7;INC
String.105.0=LIB\ST7
String.106.0=Release
String.107.0=$(ProjectSFile).elf
Int.108=0
[Root.Config.1.Settings.1]
String.6.0=2010,6,6,21,35,47
String.100.0=$(TargetFName)
String.101.0=
String.102.0=
String.103.0=.\;..\..\kernel;stm8s-periphs;..\..\tests;
[Root.Config.1.Settings.2]
String.2.0=
String.6.0=2010,6,6,21,35,47
String.100.0=STM8S105C6
[Root.Config.1.Settings.3]
String.2.0=Compiling $(InputFile)...
String.3.0=rcstm8 $(InputFile) OBJECT($(IntermPath)$(InputName).$(ObjectExt)) $(ToolsetIncOpts) WRV(0) STM8(SMALL) DGC(data) AUTO -customSizeOpt -CustomOptimOT(7,SIZE) -CustomBasicLstPR($(IntermPath)$(InputName).lst) CD CO SB LAOB -CustomAutoReloc @$(OutputPath)$(TargetSName).areloc PIN(stm8s-periphs) PIN(../../kernel) PIN(../../tests) DF(STM8S105)
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
String.5.0=$(IntermPath)$(InputName).lst
String.6.0=2010,6,6,22,22,17
[Root.Config.1.Settings.4]
String.2.0=Assembling $(InputFile)...
String.3.0=mastm8 $(InputFile) OBJECT($(IntermPath)$(InputName).$(ObjectExt)) $(ToolsetIncOpts) QUIET NOPR ERRORPRINT MODESTM8
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
String.5.0=$(IntermPath)$(InputName).lst
String.6.0=2010,6,6,21,37,36
[Root.Config.1.Settings.5]
String.2.0=Running Pre-Link step
String.6.0=2010,6,6,21,35,47
[Root.Config.1.Settings.6]
String.2.0=Running Linker
String.3.0=rlstm8 $(ObjectFiles) TO($(OutputPath)$(TargetSName).aof) $(ToolsetLibOpts) -CustomOutFile[$(ProjectSFile).elf] -CustomRunHexConv NODEBUGLINES NODEBUGPUBLICS NODEBUGSYMBOLS -CustomCodeCompConv
String.3.1=ccompst7_7.exe $(OutputPath)$(TargetSName).aof -O($(OutputPath)$(TargetSName).aof) -AOF -NOHEX -C
String.3.2=omf2elf $(OutputPath)$(TargetSName).aof
String.4.0=$(OutputPath)$(TargetFName)
String.5.0=
String.6.0=2010,6,6,21,37,36
String.100.0=DATASTART(0x0) RAMSIZE(0x800) CODESTART(0x8000) CODESIZE(0x8000) STACKTOP(0x800) STACKSIZE(0x200) EEPROMSTART(0x4000) EEPROMSIZE(0x400)
String.101.0=
Int.0=0
Int.1=0
[Root.Config.1.Settings.7]
String.2.0=Running Post-Build step
String.3.0=omf2hex $(OutputPath)$(TargetSName).aof HEX
String.6.0=2010,6,6,21,35,47
[Root.Config.1.Settings.8]
String.2.0=Performing Custom Build on $(InputFile)
String.6.0=2010,6,6,21,35,47
[Root.Kernel]
ElemType=Folder
PathName=Kernel
Child=Root.Kernel...\..\kernel\atom.h
Next=Root.Peripherals
Config.0=Root.Kernel.Config.0
Config.1=Root.Kernel.Config.1
[Root.Kernel.Config.0]
Settings.0.0=Root.Kernel.Config.0.Settings.0
Settings.0.1=Root.Kernel.Config.0.Settings.1
Settings.0.2=Root.Kernel.Config.0.Settings.2
Settings.0.3=Root.Kernel.Config.0.Settings.3
[Root.Kernel.Config.1]
Settings.1.0=Root.Kernel.Config.1.Settings.0
Settings.1.1=Root.Kernel.Config.1.Settings.1
Settings.1.2=Root.Kernel.Config.1.Settings.2
Settings.1.3=Root.Kernel.Config.1.Settings.3
[Root.Kernel.Config.0.Settings.0]
String.6.0=2010,6,6,21,35,47
String.8.0=Debug
Int.0=0
Int.1=0
[Root.Kernel.Config.0.Settings.1]
String.2.0=Compiling $(InputFile)...
String.3.0=rcstm8 $(InputFile) OBJECT($(IntermPath)$(InputName).$(ObjectExt)) $(ToolsetIncOpts) WRV(0) STM8(SMALL) DEBUG DGC(data) AUTO -customDebugOpt -CustomOptimOT(0) -CustomBasicLstPR($(IntermPath)$(InputName).lst) CD CO SB LAOB PIN(stm8s-periphs) PIN(../../kernel) PIN(../../tests) DF(STM8S105) DF(ATOM_STACK_CHECKING)
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
String.5.0=$(IntermPath)$(InputName).lst
String.6.0=2010,6,6,22,22,17
[Root.Kernel.Config.0.Settings.2]
String.2.0=Assembling $(InputFile)...
String.3.0=mastm8 $(InputFile) OBJECT($(IntermPath)$(InputName).$(ObjectExt)) $(ToolsetIncOpts) QUIET ERRORPRINT DEBUG
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
String.5.0=$(IntermPath)$(InputName).lst
String.6.0=2010,6,6,21,35,47
[Root.Kernel.Config.0.Settings.3]
String.2.0=Performing Custom Build on $(InputFile)
String.6.0=2010,6,6,21,35,47
[Root.Kernel.Config.1.Settings.0]
String.6.0=2010,6,6,21,35,47
String.8.0=Release
Int.0=0
Int.1=0
[Root.Kernel.Config.1.Settings.1]
String.2.0=Compiling $(InputFile)...
String.3.0=rcstm8 $(InputFile) OBJECT($(IntermPath)$(InputName).$(ObjectExt)) $(ToolsetIncOpts) WRV(0) STM8(SMALL) DGC(data) AUTO -customSizeOpt -CustomOptimOT(7,SIZE) -CustomBasicLstPR($(IntermPath)$(InputName).lst) CD CO SB LAOB -CustomAutoReloc @$(OutputPath)$(TargetSName).areloc PIN(stm8s-periphs) PIN(../../kernel) PIN(../../tests) DF(STM8S105)
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
String.5.0=$(IntermPath)$(InputName).lst
String.6.0=2010,6,6,22,22,17
[Root.Kernel.Config.1.Settings.2]
String.2.0=Assembling $(InputFile)...
String.3.0=mastm8 $(InputFile) OBJECT($(IntermPath)$(InputName).$(ObjectExt)) $(ToolsetIncOpts) QUIET NOPR ERRORPRINT MODESTM8
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
String.5.0=$(IntermPath)$(InputName).lst
String.6.0=2010,6,6,21,37,36
[Root.Kernel.Config.1.Settings.3]
String.2.0=Performing Custom Build on $(InputFile)
String.6.0=2010,6,6,21,35,47
[Root.Kernel...\..\kernel\atom.h]
ElemType=File
PathName=..\..\kernel\atom.h
Next=Root.Kernel...\..\kernel\atomkernel.c
[Root.Kernel...\..\kernel\atomkernel.c]
ElemType=File
PathName=..\..\kernel\atomkernel.c
Next=Root.Kernel...\..\kernel\atommutex.c
[Root.Kernel...\..\kernel\atommutex.c]
ElemType=File
PathName=..\..\kernel\atommutex.c
Next=Root.Kernel...\..\kernel\atommutex.h
[Root.Kernel...\..\kernel\atommutex.h]
ElemType=File
PathName=..\..\kernel\atommutex.h
Next=Root.Kernel...\..\kernel\atomqueue.c
[Root.Kernel...\..\kernel\atomqueue.c]
ElemType=File
PathName=..\..\kernel\atomqueue.c
Next=Root.Kernel...\..\kernel\atomqueue.h
[Root.Kernel...\..\kernel\atomqueue.h]
ElemType=File
PathName=..\..\kernel\atomqueue.h
Next=Root.Kernel...\..\kernel\atomsem.c
[Root.Kernel...\..\kernel\atomsem.c]
ElemType=File
PathName=..\..\kernel\atomsem.c
Next=Root.Kernel...\..\kernel\atomsem.h
[Root.Kernel...\..\kernel\atomsem.h]
ElemType=File
PathName=..\..\kernel\atomsem.h
Next=Root.Kernel...\..\kernel\atomtimer.c
[Root.Kernel...\..\kernel\atomtimer.c]
ElemType=File
PathName=..\..\kernel\atomtimer.c
Next=Root.Kernel...\..\kernel\atomtimer.h
[Root.Kernel...\..\kernel\atomtimer.h]
ElemType=File
PathName=..\..\kernel\atomtimer.h
[Root.Peripherals]
ElemType=Folder
PathName=Peripherals
Child=Root.Peripherals.stm8s-periphs\stm8s_clk.c
Next=Root.Port
Config.0=Root.Peripherals.Config.0
Config.1=Root.Peripherals.Config.1
[Root.Peripherals.Config.0]
Settings.0.0=Root.Peripherals.Config.0.Settings.0
Settings.0.1=Root.Peripherals.Config.0.Settings.1
Settings.0.2=Root.Peripherals.Config.0.Settings.2
Settings.0.3=Root.Peripherals.Config.0.Settings.3
[Root.Peripherals.Config.1]
Settings.1.0=Root.Peripherals.Config.1.Settings.0
Settings.1.1=Root.Peripherals.Config.1.Settings.1
Settings.1.2=Root.Peripherals.Config.1.Settings.2
Settings.1.3=Root.Peripherals.Config.1.Settings.3
[Root.Peripherals.Config.0.Settings.0]
String.6.0=2010,6,6,21,35,47
String.8.0=Debug
Int.0=0
Int.1=0
[Root.Peripherals.Config.0.Settings.1]
String.2.0=Compiling $(InputFile)...
String.3.0=rcstm8 $(InputFile) OBJECT($(IntermPath)$(InputName).$(ObjectExt)) $(ToolsetIncOpts) WRV(0) STM8(SMALL) DEBUG DGC(data) AUTO -customDebugOpt -CustomOptimOT(0) -CustomBasicLstPR($(IntermPath)$(InputName).lst) CD CO SB LAOB PIN(stm8s-periphs) PIN(../../kernel) PIN(../../tests) DF(STM8S105) DF(ATOM_STACK_CHECKING)
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
String.5.0=$(IntermPath)$(InputName).lst
String.6.0=2010,6,6,22,22,17
[Root.Peripherals.Config.0.Settings.2]
String.2.0=Assembling $(InputFile)...
String.3.0=mastm8 $(InputFile) OBJECT($(IntermPath)$(InputName).$(ObjectExt)) $(ToolsetIncOpts) QUIET ERRORPRINT DEBUG
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
String.5.0=$(IntermPath)$(InputName).lst
String.6.0=2010,6,6,21,35,47
[Root.Peripherals.Config.0.Settings.3]
String.2.0=Performing Custom Build on $(InputFile)
String.6.0=2010,6,6,21,35,47
[Root.Peripherals.Config.1.Settings.0]
String.6.0=2010,6,6,21,35,47
String.8.0=Release
Int.0=0
Int.1=0
[Root.Peripherals.Config.1.Settings.1]
String.2.0=Compiling $(InputFile)...
String.3.0=rcstm8 $(InputFile) OBJECT($(IntermPath)$(InputName).$(ObjectExt)) $(ToolsetIncOpts) WRV(0) STM8(SMALL) DGC(data) AUTO -customSizeOpt -CustomOptimOT(7,SIZE) -CustomBasicLstPR($(IntermPath)$(InputName).lst) CD CO SB LAOB -CustomAutoReloc @$(OutputPath)$(TargetSName).areloc PIN(stm8s-periphs) PIN(../../kernel) PIN(../../tests) DF(STM8S105)
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
String.5.0=$(IntermPath)$(InputName).lst
String.6.0=2010,6,6,22,22,17
[Root.Peripherals.Config.1.Settings.2]
String.2.0=Assembling $(InputFile)...
String.3.0=mastm8 $(InputFile) OBJECT($(IntermPath)$(InputName).$(ObjectExt)) $(ToolsetIncOpts) QUIET NOPR ERRORPRINT MODESTM8
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
String.5.0=$(IntermPath)$(InputName).lst
String.6.0=2010,6,6,21,37,36
[Root.Peripherals.Config.1.Settings.3]
String.2.0=Performing Custom Build on $(InputFile)
String.6.0=2010,6,6,21,35,47
[Root.Peripherals.stm8s-periphs\stm8s_clk.c]
ElemType=File
PathName=stm8s-periphs\stm8s_clk.c
Next=Root.Peripherals.stm8s-periphs\stm8s_uart2.h
[Root.Peripherals.stm8s-periphs\stm8s_uart2.h]
ElemType=File
PathName=stm8s-periphs\stm8s_uart2.h
Next=Root.Peripherals.stm8s-periphs\stm8s_uart2.c
[Root.Peripherals.stm8s-periphs\stm8s_uart2.c]
ElemType=File
PathName=stm8s-periphs\stm8s_uart2.c
Next=Root.Peripherals.stm8s-periphs\stm8s_gpio.c
[Root.Peripherals.stm8s-periphs\stm8s_gpio.c]
ElemType=File
PathName=stm8s-periphs\stm8s_gpio.c
Next=Root.Peripherals.stm8s-periphs\stm8s_tim1.h
[Root.Peripherals.stm8s-periphs\stm8s_tim1.h]
ElemType=File
PathName=stm8s-periphs\stm8s_tim1.h
Next=Root.Peripherals.stm8s-periphs\stm8s_tim1.c
[Root.Peripherals.stm8s-periphs\stm8s_tim1.c]
ElemType=File
PathName=stm8s-periphs\stm8s_tim1.c
Next=Root.Peripherals.stm8s-periphs\stm8s_itc.h
[Root.Peripherals.stm8s-periphs\stm8s_itc.h]
ElemType=File
PathName=stm8s-periphs\stm8s_itc.h
Next=Root.Peripherals.stm8s-periphs\stm8s_gpio.h
[Root.Peripherals.stm8s-periphs\stm8s_gpio.h]
ElemType=File
PathName=stm8s-periphs\stm8s_gpio.h
Next=Root.Peripherals.stm8s-periphs\stm8s_clk.h
[Root.Peripherals.stm8s-periphs\stm8s_clk.h]
ElemType=File
PathName=stm8s-periphs\stm8s_clk.h
Next=Root.Peripherals.stm8s-periphs\stm8s.h
[Root.Peripherals.stm8s-periphs\stm8s.h]
ElemType=File
PathName=stm8s-periphs\stm8s.h
Next=Root.Peripherals.stm8s-periphs\stm8s_type.h
[Root.Peripherals.stm8s-periphs\stm8s_type.h]
ElemType=File
PathName=stm8s-periphs\stm8s_type.h
[Root.Port]
ElemType=Folder
PathName=Port
Child=Root.Port.atomport-asm-raisonance.asm
Config.0=Root.Port.Config.0
Config.1=Root.Port.Config.1
[Root.Port.Config.0]
Settings.0.0=Root.Port.Config.0.Settings.0
Settings.0.1=Root.Port.Config.0.Settings.1
Settings.0.2=Root.Port.Config.0.Settings.2
Settings.0.3=Root.Port.Config.0.Settings.3
[Root.Port.Config.1]
Settings.1.0=Root.Port.Config.1.Settings.0
Settings.1.1=Root.Port.Config.1.Settings.1
Settings.1.2=Root.Port.Config.1.Settings.2
Settings.1.3=Root.Port.Config.1.Settings.3
[Root.Port.Config.0.Settings.0]
String.6.0=2010,6,6,21,35,47
String.8.0=Debug
Int.0=0
Int.1=0
[Root.Port.Config.0.Settings.1]
String.2.0=Compiling $(InputFile)...
String.3.0=rcstm8 $(InputFile) OBJECT($(IntermPath)$(InputName).$(ObjectExt)) $(ToolsetIncOpts) WRV(0) STM8(SMALL) DEBUG DGC(data) AUTO -customDebugOpt -CustomOptimOT(0) -CustomBasicLstPR($(IntermPath)$(InputName).lst) CD CO SB LAOB PIN(stm8s-periphs) PIN(../../kernel) PIN(../../tests) DF(STM8S105) DF(ATOM_STACK_CHECKING)
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
String.5.0=$(IntermPath)$(InputName).lst
String.6.0=2010,6,6,22,22,17
[Root.Port.Config.0.Settings.2]
String.2.0=Assembling $(InputFile)...
String.3.0=mastm8 $(InputFile) OBJECT($(IntermPath)$(InputName).$(ObjectExt)) $(ToolsetIncOpts) QUIET ERRORPRINT DEBUG
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
String.5.0=$(IntermPath)$(InputName).lst
String.6.0=2010,6,6,21,35,47
[Root.Port.Config.0.Settings.3]
String.2.0=Performing Custom Build on $(InputFile)
String.6.0=2010,6,6,21,35,47
[Root.Port.Config.1.Settings.0]
String.6.0=2010,6,6,21,35,47
String.8.0=Release
Int.0=0
Int.1=0
[Root.Port.Config.1.Settings.1]
String.2.0=Compiling $(InputFile)...
String.3.0=rcstm8 $(InputFile) OBJECT($(IntermPath)$(InputName).$(ObjectExt)) $(ToolsetIncOpts) WRV(0) STM8(SMALL) DGC(data) AUTO -customSizeOpt -CustomOptimOT(7,SIZE) -CustomBasicLstPR($(IntermPath)$(InputName).lst) CD CO SB LAOB -CustomAutoReloc @$(OutputPath)$(TargetSName).areloc PIN(stm8s-periphs) PIN(../../kernel) PIN(../../tests) DF(STM8S105)
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
String.5.0=$(IntermPath)$(InputName).lst
String.6.0=2010,6,6,22,22,17
[Root.Port.Config.1.Settings.2]
String.2.0=Assembling $(InputFile)...
String.3.0=mastm8 $(InputFile) OBJECT($(IntermPath)$(InputName).$(ObjectExt)) $(ToolsetIncOpts) QUIET NOPR ERRORPRINT MODESTM8
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
String.5.0=$(IntermPath)$(InputName).lst
String.6.0=2010,6,6,21,37,36
[Root.Port.Config.1.Settings.3]
String.2.0=Performing Custom Build on $(InputFile)
String.6.0=2010,6,6,21,35,47
[Root.Port.atomport-asm-raisonance.asm]
ElemType=File
PathName=atomport-asm-raisonance.asm
Next=Root.Port...\..\tests\sem1.c
[Root.Port...\..\tests\sem1.c]
ElemType=File
PathName=..\..\tests\sem1.c
Next=Root.Port.uart.h
[Root.Port.uart.h]
ElemType=File
PathName=uart.h
Next=Root.Port.uart.c
[Root.Port.uart.c]
ElemType=File
PathName=uart.c
Next=Root.Port.atomport-tests.h
[Root.Port.atomport-tests.h]
ElemType=File
PathName=atomport-tests.h
Next=Root.Port.tests-main.c
[Root.Port.tests-main.c]
ElemType=File
PathName=tests-main.c
Next=Root.Port.atomport-private.h
[Root.Port.atomport-private.h]
ElemType=File
PathName=atomport-private.h
Next=Root.Port.atomport.h
[Root.Port.atomport.h]
ElemType=File
PathName=atomport.h
Next=Root.Port.stm8s_conf.h
[Root.Port.stm8s_conf.h]
ElemType=File
PathName=stm8s_conf.h
Next=Root.Port.atomport.c
[Root.Port.atomport.c]
ElemType=File
PathName=atomport.c

View File

@@ -6,7 +6,11 @@ Keyword=ST7Workspace-V0.7
[Project0]
Filename=atomthreads-sample-cosmic.stp
Dependencies=
[Project1]
Filename=atomthreads-sample-raisonance.stp
Dependencies=
[Options]
ActiveProject=atomthreads
ActiveConfig=Release
ActiveProject=atomthreads-cosmic
ActiveConfig=Debug
AddSortedElements=0

View File

@@ -96,7 +96,7 @@ $(KERNEL_OBJECTS): %.o: $(KERNEL_DIR)/%.c
$(TEST_OBJECTS): %.o: $(TESTS_DIR)/%.c
$(CC) $(CFLAGS) -i. -i$(KERNEL_DIR) -i$(PERIPHS_DIR) -co$(BUILD_DIR) $<
# Kernel objects builder
# Peripheral objects builder
$(PERIPH_OBJECTS): %.o: $(PERIPHS_DIR)/%.c
$(CC) $(CFLAGS) -i. -i$(PERIPHS_DIR) -co$(BUILD_DIR) $<

View File

@@ -113,7 +113,7 @@ $(KERNEL_OBJECTS): %.o: $(KERNEL_DIR)/%.c
$(TEST_OBJECTS): %.o: $(TESTS_DIR)/%.c
$(CC) $< $(CFLAGS) -I . -I $(KERNEL_DIR) -I $(PERIPHS_DIR) -o $(BUILD_DIR)
# Kernel objects builder
# Peripheral objects builder
$(PERIPH_OBJECTS): %.o: $(PERIPHS_DIR)/%.c
$(CC) $< $(CFLAGS) -I . -I $(PERIPHS_DIR) -o $(BUILD_DIR)

126
ports/stm8/raisonance.mak Normal file
View File

@@ -0,0 +1,126 @@
############
# Settings #
############
# Set up build environment (using GNU Make)
# set PATH=%PATH%;C:\Program Files\GNU_MAKE;C:\Program Files\Raisonance\Ride\bin
# set MAKE_MODE=DOS
# Build all test applications:
# make -f raisonance.mak
# Location of build tools and atomthreads sources
KERNEL_DIR=../../kernel
TESTS_DIR=../../tests
PERIPHS_DIR=stm8s-periphs
LIBS_DIR=C:\Program Files\Raisonance\Ride
CC=rcstm8
ASM=mastm8
LINK=rlstm8
MAKEHEX=omf2hex
# CPU part number
PART=STM8S105
# Enable stack-checking
STACK_CHECK=true
# Directory for built objects
BUILD_DIR=build-raisonance
# Port/application object files
APP_OBJECTS = atomport.o tests-main.o uart.o
APP_ASM_OBJECTS = atomport-asm-raisonance.o
# STM8S Peripheral driver object files
PERIPH_OBJECTS = stm8s_gpio.o stm8s_tim1.o stm8s_clk.o stm8s_uart2.o
# Kernel object files
KERNEL_OBJECTS = atomkernel.o atomsem.o atommutex.o atomtimer.o atomqueue.o
# 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))
comma := ,
space :=
space +=
BUILT_OBJECTS_CS = $(subst $(space),$(comma),$(BUILT_OBJECTS))
# Test object files (dealt with separately as only one per application build)
TEST_OBJECTS = $(notdir $(patsubst %.c,%.o,$(wildcard $(TESTS_DIR)/*.c)))
# Target application filenames (.aof and .hex) for each test object
TEST_AOFS = $(patsubst %.o,%.aof,$(TEST_OBJECTS))
TEST_HEXS = $(patsubst %.o,%.hex,$(TEST_OBJECTS))
# Search build/output directory for dependencies
vpath %.o .\$(BUILD_DIR)
vpath %.aof .\$(BUILD_DIR)
vpath %.hex .\$(BUILD_DIR)
# Compiler/Assembler flags
CFLAGS=WRV(0) STM8(SMALL) DGC(data) AUTO OT(7,SIZE) CD CO SB LAOB DF($(PART))
DBG_CFLAGS=WRV(0) STM8(SMALL) DEBUG DGC(data) AUTO OT(0) CD CO SB LAOB DF($(PART))
ASMFLAGS=QUIET NOPR ERRORPRINT MODESTM8
DBG_ASMFLAGS=QUIET ERRORPRINT DEBUG MODESTM8
LDFLAGS=NODEBUGLINES NODEBUGPUBLICS NODEBUGSYMBOLS DATASTART(0x0) RAMSIZE(0x800) CODESTART(0x8000) CODESIZE(0x8000) STACKTOP(0x800) STACKSIZE(0x200) EEPROMSTART(0x4000) EEPROMSIZE(0x400)
DBG_LDFLAGS=DEBUGLINES DEBUGPUBLICS DEBUGSYMBOLS DATASTART(0x0) RAMSIZE(0x800) CODESTART(0x8000) CODESIZE(0x8000) STACKTOP(0x800) STACKSIZE(0x200) EEPROMSTART(0x4000) EEPROMSIZE(0x400)
# Enable stack-checking (disable if not required)
ifeq ($(STACK_CHECK),true)
CFLAGS += DF(ATOM_STACK_CHECKING)
DBG_CFLAGS += DF(ATOM_STACK_CHECKING)
endif
#################
# Build targets #
#################
# All tests
all: $(BUILD_DIR) $(TEST_HEXS) raisonance.mak
# Make build/output directory
$(BUILD_DIR):
mkdir $(BUILD_DIR)
# Test HEX files (one application build for each test)
$(TEST_HEXS): %.hex: %.aof
@echo Building $@
$(MAKEHEX) $(BUILD_DIR)/$<
# Test ELF files (one application build for each test)
$(TEST_AOFS): %.aof: %.o $(KERNEL_OBJECTS) $(PERIPH_OBJECTS) $(APP_OBJECTS) $(APP_ASM_OBJECTS)
$(LINK) -P "$(BUILD_DIR)/$(notdir $<),$(BUILT_OBJECTS_CS)" TO($(BUILD_DIR)/$@) LIBPATH("$(LIBS_DIR)\Lib\ST7") PR($(BUILD_DIR)/$(basename $@).map) $(LDFLAGS)
# Kernel objects builder
$(KERNEL_OBJECTS): %.o: $(KERNEL_DIR)/%.c
$(CC) $< OBJECT($(BUILD_DIR)/$@) $(CFLAGS) PR($(BUILD_DIR)/$(basename $(notdir $<)).lst) PIN(".") PIN("$(PERIPHS_DIR)") PIN("$(LIBS_DIR)\inc") PIN("$(LIBS_DIR)\inc\ST7")
# Test objects builder
$(TEST_OBJECTS): %.o: $(TESTS_DIR)/%.c
$(CC) $< OBJECT($(BUILD_DIR)/$@) $(CFLAGS) PR($(BUILD_DIR)/$(basename $(notdir $<)).lst) PIN(".") PIN("$(KERNEL_DIR)") PIN("$(PERIPHS_DIR)") PIN("$(LIBS_DIR)\inc") PIN("$(LIBS_DIR)\inc\ST7")
# Peripheral objects builder
$(PERIPH_OBJECTS): %.o: $(PERIPHS_DIR)/%.c
$(CC) $< OBJECT($(BUILD_DIR)/$@) $(CFLAGS) PR($(BUILD_DIR)/$(basename $(notdir $<)).lst) PIN(".") PIN("$(PERIPHS_DIR)") PIN("$(LIBS_DIR)\inc") PIN("$(LIBS_DIR)\inc\ST7")
# Application C objects builder
$(APP_OBJECTS): %.o: ./%.c
$(CC) $< OBJECT($(BUILD_DIR)/$@) $(CFLAGS) PR($(BUILD_DIR)/$(basename $(notdir $<)).lst) PIN(".") PIN("$(KERNEL_DIR)") PIN("$(TESTS_DIR)") PIN("$(PERIPHS_DIR)") PIN("$(LIBS_DIR)\inc") PIN("$(LIBS_DIR)\inc\ST7")
# Application asm objects builder
$(APP_ASM_OBJECTS): %.o: ./%.asm
$(ASM) $< OBJECT($(BUILD_DIR)/$@) $(ASMFLAGS) PR($(BUILD_DIR)/$(basename $(notdir $<)).lst) PIN(".") PIN("$(KERNEL_DIR)") PIN("$(LIBS_DIR)\inc") PIN("$(LIBS_DIR)\inc\ST7")
# Clean
clean:
rm -f *.o *.O *.elf *.aof *.map *.hex *.bin *.lst *.LST *.stm8 *.s19
rm -rf doxygen-kernel
rm -rf doxygen-stm8
rm -rf build-raisonance
doxygen:
doxygen $(KERNEL_DIR)/Doxyfile
doxygen ./Doxyfile

View File

@@ -112,7 +112,7 @@ NEAR static uint8_t idle_thread_stack[IDLE_STACK_SIZE_BYTES];
/* Forward declarations */
static void main_thread_func (uint32_t data);
static void main_thread_func (uint32_t param);
/**
@@ -185,15 +185,18 @@ NO_REG_SAVE void main ( void )
*
* This is the first thread that will be executed when the OS is started.
*
* @param[in] data Unused (optional thread entry parameter)
* @param[in] param Unused (optional thread entry parameter)
*
* @return None
*/
static void main_thread_func (uint32_t data)
static void main_thread_func (uint32_t param)
{
uint32_t test_status;
int sleep_ticks;
/* Compiler warnings */
param = param;
/* Initialise UART (9600bps) */
if (uart_init(9600) != 0)
{

View File

@@ -96,6 +96,25 @@ char putchar (char c)
#endif /* __CSMC__ */
/* RAISONANCE: Requires putchar() routine to override stdio */
#if defined(__RCSTM8__)
/**
* \b putchar
*
* Retarget putchar() to use UART2
*
* @param[in] c Character to send
*
* @return 1 on success
*/
int putchar (char c)
{
uart_putchar(c);
return (1);
}
#endif /* __RCSTM8__ */
/* IAR: Requires __write() routine to override stdio */
#if defined(__IAR_SYSTEMS_ICC__)
/**

View File

@@ -39,7 +39,7 @@ static uint8_t test_thread_stack[TEST_THREAD_STACK_SIZE];
/* Forward declarations */
static void test_thread_func (uint32_t data);
static void test_thread_func (uint32_t param);
/**
@@ -107,12 +107,15 @@ uint32_t test_start (void)
*
* Entry point for test thread.
*
* @param[in] data Unused (optional thread entry parameter)
* @param[in] param Unused (optional thread entry parameter)
*
* @return None
*/
static void test_thread_func (uint32_t data)
static void test_thread_func (uint32_t param)
{
/* Compiler warnings */
param = param;
/* Wait forever */
while (1)
{

View File

@@ -47,7 +47,7 @@ static volatile int sleep_request[2];
/* Forward declarations */
static void test_thread_func (uint32_t data);
static void test_thread_func (uint32_t param);
/**
@@ -213,16 +213,16 @@ uint32_t test_start (void)
*
* Entry point for test thread.
*
* @param[in] data Thread ID (0 = low prio, 1 = high prio)
* @param[in] param Thread ID (0 = low prio, 1 = high prio)
*
* @return None
*/
static void test_thread_func (uint32_t data)
static void test_thread_func (uint32_t param)
{
int thread_id;
/* Pull out thread ID */
thread_id = (int)data;
thread_id = (int)param;
/* Run forever */
while (1)

View File

@@ -50,7 +50,7 @@ static int volatile test_started;
/* Forward declarations */
static void test_thread_func (uint32_t data);
static void test_thread_func (uint32_t param);
/**
@@ -184,11 +184,11 @@ uint32_t test_start (void)
*
* Entry point for test thread.
*
* @param[in] data Thread ID (0 to 3)
* @param[in] param Thread ID (0 to 3)
*
* @return None
*/
static void test_thread_func (uint32_t data)
static void test_thread_func (uint32_t param)
{
int thread_id, expected_thread;
int time_error, thread_error;
@@ -196,7 +196,7 @@ static void test_thread_func (uint32_t data)
CRITICAL_STORE;
/* Pull out thread ID */
thread_id = (int)data;
thread_id = (int)param;
/* Run forever */
while (1)

View File

@@ -48,8 +48,8 @@ static volatile int g_result;
/* Forward declarations */
static void test1_thread_func (uint32_t data);
static void test2_thread_func (uint32_t data);
static void test1_thread_func (uint32_t param);
static void test2_thread_func (uint32_t param);
/**
@@ -291,14 +291,17 @@ uint32_t test_start (void)
*
* Entry point for test thread 1.
*
* @param[in] data Unused (optional thread entry parameter)
* @param[in] param Unused (optional thread entry parameter)
*
* @return None
*/
static void test1_thread_func (uint32_t data)
static void test1_thread_func (uint32_t param)
{
uint8_t status;
/* Compiler warnings */
param = param;
/*
* Wait on mutex1 with no timeout. We are expecting to be woken up
* by the main thread while blocking.
@@ -327,14 +330,17 @@ static void test1_thread_func (uint32_t data)
*
* Entry point for test thread 2.
*
* @param[in] data Unused (optional thread entry parameter)
* @param[in] param Unused (optional thread entry parameter)
*
* @return None
*/
static void test2_thread_func (uint32_t data)
static void test2_thread_func (uint32_t param)
{
uint8_t status;
/* Compiler warnings */
param = param;
/*
* Wait on mutex1 with timeout. We are expecting to be woken up
* by the main thread while blocking.

View File

@@ -50,7 +50,7 @@ static volatile int g_result, g_owned;
/* Forward declarations */
static void testCallback (POINTER cb_data);
static void test_thread_func (uint32_t data);
static void test_thread_func (uint32_t param);
/**
@@ -296,14 +296,17 @@ static void testCallback (POINTER cb_data)
*
* Entry point for test thread.
*
* @param[in] data Unused (optional thread entry parameter)
* @param[in] param Unused (optional thread entry parameter)
*
* @return None
*/
static void test_thread_func (uint32_t data)
static void test_thread_func (uint32_t param)
{
uint8_t status;
/* Compiler warnings */
param = param;
/*
* Take mutex2 so that main thread can test mutex APIs on a mutex
* which it does not own.

View File

@@ -47,7 +47,7 @@ static volatile uint8_t wake_cnt;
static volatile uint8_t wake_order[4];
/* Forward declarations */
static void test_thread_func (uint32_t data);
static void test_thread_func (uint32_t param);
/**
@@ -246,16 +246,16 @@ uint32_t test_start (void)
* four test threads, with the thread number/ID (1-4) passed as the entry
* point parameter.
*
* @param[in] data Thread number (1,2,3,4)
* @param[in] param Thread number (1,2,3,4)
*
* @return None
*/
static void test_thread_func (uint32_t data)
static void test_thread_func (uint32_t param)
{
uint8_t thread_id;
/* Thread ID is passed through the function parameter */
thread_id = (uint8_t)data;
thread_id = (uint8_t)param;
/*
* Wait for mutex1 to be posted. At creation of all test threads the mutex

View File

@@ -56,7 +56,7 @@ static volatile int g_failures;
/* Forward declarations */
static void test_thread_func (uint32_t data);
static void test_thread_func (uint32_t param);
/**
@@ -242,16 +242,19 @@ uint32_t test_start (void)
* Entry point for test thread. The same thread entry point is used for all
* four test threads.
*
* @param[in] data Unused (optional thread entry parameter)
* @param[in] param Unused (optional thread entry parameter)
*
* @return None
*/
static void test_thread_func (uint32_t data)
static void test_thread_func (uint32_t param)
{
uint32_t loop_cnt;
uint8_t status;
CRITICAL_STORE;
/* Compiler warnings */
param = param;
/* Run a Get/Put pair many times */
loop_cnt = NUM_TEST_LOOPS;
while (loop_cnt--)

View File

@@ -48,7 +48,7 @@ static volatile int shared_data;
/* Forward declarations */
static void test_thread_func (uint32_t data);
static void test_thread_func (uint32_t param);
/**
@@ -255,14 +255,17 @@ uint32_t test_start (void)
*
* Entry point for test thread.
*
* @param[in] data Unused (optional thread entry parameter)
* @param[in] param Unused (optional thread entry parameter)
*
* @return None
*/
static void test_thread_func (uint32_t data)
static void test_thread_func (uint32_t param)
{
uint8_t status;
/* Compiler warnings */
param = param;
/* Repeatedly attempt to get the mutex and set shared_data to 1 */
while (1)
{

View File

@@ -52,7 +52,7 @@ static volatile int shared_data;
/* Forward declarations */
static void test_thread_func (uint32_t data);
static void test_thread_func (uint32_t param);
/**
@@ -246,14 +246,17 @@ uint32_t test_start (void)
*
* Entry point for test thread.
*
* @param[in] data Unused (optional thread entry parameter)
* @param[in] param Unused (optional thread entry parameter)
*
* @return None
*/
static void test_thread_func (uint32_t data)
static void test_thread_func (uint32_t param)
{
uint8_t status;
/* Compiler warnings */
param = param;
/* Repeatedly attempt to get the mutex and set shared_data to 1 */
while (1)
{

View File

@@ -50,7 +50,7 @@ static volatile int shared_data;
/* Forward declarations */
static void testCallback (POINTER cb_data);
static void test_thread_func (uint32_t data);
static void test_thread_func (uint32_t param);
/**
@@ -210,14 +210,17 @@ uint32_t test_start (void)
*
* Entry point for test thread.
*
* @param[in] data Unused (optional thread entry parameter)
* @param[in] param Unused (optional thread entry parameter)
*
* @return None
*/
static void test_thread_func (uint32_t data)
static void test_thread_func (uint32_t param)
{
uint8_t status;
/* Compiler warnings */
param = param;
/* Block on the mutex */
if ((status = atomMutexGet (&mutex1, 0)) != ATOM_OK)
{

View File

@@ -48,7 +48,7 @@ static volatile int pass_flag[3];
/* Forward declarations */
static void test_thread_func (uint32_t data);
static void test_thread_func (uint32_t param);
/**
@@ -192,17 +192,17 @@ uint32_t test_start (void)
*
* Entry point for test threads.
*
* @param[in] data Thread ID (0-2)
* @param[in] param Thread ID (0-2)
*
* @return None
*/
static void test_thread_func (uint32_t data)
static void test_thread_func (uint32_t param)
{
uint8_t status;
int thread_id;
/* Pull out the passed thread ID */
thread_id = (int)data;
thread_id = (int)param;
/*
* Wait on mutex1 with timeout. We are expecting to be woken up

View File

@@ -48,7 +48,7 @@ static volatile int shared_data;
/* Forward declarations */
static void test_thread_func (uint32_t data);
static void test_thread_func (uint32_t param);
/**
@@ -185,14 +185,17 @@ uint32_t test_start (void)
*
* Entry point for test thread.
*
* @param[in] data Unused (optional thread entry parameter)
* @param[in] param Unused (optional thread entry parameter)
*
* @return None
*/
static void test_thread_func (uint32_t data)
static void test_thread_func (uint32_t param)
{
uint8_t status;
/* Compiler warnings */
param = param;
/* Block on the mutex */
if ((status = atomMutexGet (&mutex1, 0)) != ATOM_OK)
{

View File

@@ -53,8 +53,8 @@ static volatile int g_result;
/* Forward declarations */
static void test1_thread_func (uint32_t data);
static void test2_thread_func (uint32_t data);
static void test1_thread_func (uint32_t param);
static void test2_thread_func (uint32_t param);
/**
@@ -237,14 +237,17 @@ uint32_t test_start (void)
*
* Entry point for test thread 1.
*
* @param[in] data Unused (optional thread entry parameter)
* @param[in] param Unused (optional thread entry parameter)
*
* @return None
*/
static void test1_thread_func (uint32_t data)
static void test1_thread_func (uint32_t param)
{
uint8_t status, msg;
/* Compiler warnings */
param = param;
/*
* Wait on queue1 with no timeout. We are expecting to be woken up
* by the main thread while blocking.
@@ -273,14 +276,17 @@ static void test1_thread_func (uint32_t data)
*
* Entry point for test thread 2.
*
* @param[in] data Unused (optional thread entry parameter)
* @param[in] param Unused (optional thread entry parameter)
*
* @return None
*/
static void test2_thread_func (uint32_t data)
static void test2_thread_func (uint32_t param)
{
uint8_t status, msg;
/* Compiler warnings */
param = param;
/*
* Wait on queue1 with timeout. We are expecting to be woken up
* by the main thread while blocking.

View File

@@ -53,8 +53,8 @@ static volatile int g_result;
/* Forward declarations */
static void test1_thread_func (uint32_t data);
static void test2_thread_func (uint32_t data);
static void test1_thread_func (uint32_t param);
static void test2_thread_func (uint32_t param);
/**
@@ -269,14 +269,17 @@ uint32_t test_start (void)
*
* Entry point for test thread 1.
*
* @param[in] data Unused (optional thread entry parameter)
* @param[in] param Unused (optional thread entry parameter)
*
* @return None
*/
static void test1_thread_func (uint32_t data)
static void test1_thread_func (uint32_t param)
{
uint8_t status, msg;
/* Compiler warnings */
param = param;
/* Set a test value for posting to the queue */
msg = 0x66;
@@ -309,14 +312,17 @@ static void test1_thread_func (uint32_t data)
*
* Entry point for test thread 2.
*
* @param[in] data Unused (optional thread entry parameter)
* @param[in] param Unused (optional thread entry parameter)
*
* @return None
*/
static void test2_thread_func (uint32_t data)
static void test2_thread_func (uint32_t param)
{
uint8_t status, msg;
/* Compiler warnings */
param = param;
/* Set a test value for posting to the queue */
msg = 0x66;

View File

@@ -53,7 +53,7 @@ static volatile uint8_t wake_cnt;
static volatile uint8_t wake_order[4];
/* Forward declarations */
static void test_thread_func (uint32_t data);
static void test_thread_func (uint32_t param);
/**
@@ -263,17 +263,17 @@ uint32_t test_start (void)
* four test threads, with the thread number/ID (1-4) passed as the entry
* point parameter.
*
* @param[in] data Thread number (1,2,3,4)
* @param[in] param Thread number (1,2,3,4)
*
* @return None
*/
static void test_thread_func (uint32_t data)
static void test_thread_func (uint32_t param)
{
uint8_t thread_id;
uint8_t msg;
/* Thread ID is passed through the function parameter */
thread_id = (uint8_t)data;
thread_id = (uint8_t)param;
/*
* Wait for a message to appear on queue1. At creation of all test

View File

@@ -70,7 +70,7 @@ static volatile int g_result;
/* Forward declarations */
static void test1_thread_func (uint32_t data);
static void test1_thread_func (uint32_t param);
/**
@@ -215,15 +215,18 @@ uint32_t test_start (void)
*
* Entry point for test thread 1.
*
* @param[in] data Unused (optional thread entry parameter)
* @param[in] param Unused (optional thread entry parameter)
*
* @return None
*/
static void test1_thread_func (uint32_t data)
static void test1_thread_func (uint32_t param)
{
uint32_t msg;
int num_entries, count, failures;
/* Compiler warnings */
param = param;
/* Default to no errors */
failures = 0;

View File

@@ -53,7 +53,7 @@ static volatile int pass_flag[3];
/* Forward declarations */
static void test_thread_func (uint32_t data);
static void test_thread_func (uint32_t param);
/**
@@ -192,18 +192,18 @@ uint32_t test_start (void)
*
* Entry point for test threads.
*
* @param[in] data Thread ID (0-2)
* @param[in] param Thread ID (0-2)
*
* @return None
*/
static void test_thread_func (uint32_t data)
static void test_thread_func (uint32_t param)
{
uint8_t status;
uint8_t msg;
int thread_id;
/* Pull out the passed thread ID */
thread_id = (int)data;
thread_id = (int)param;
/*
* Wait on queue1 with timeout. We are expecting to be woken up

View File

@@ -62,7 +62,7 @@ static volatile int g_failures;
/* Forward declarations */
static void test_thread_func (uint32_t data);
static void test_thread_func (uint32_t param);
/**
@@ -237,17 +237,20 @@ uint32_t test_start (void)
* Entry point for test thread. The same thread entry point is used for all
* four test threads.
*
* @param[in] data Unused (optional thread entry parameter)
* @param[in] param Unused (optional thread entry parameter)
*
* @return None
*/
static void test_thread_func (uint32_t data)
static void test_thread_func (uint32_t param)
{
uint32_t loop_cnt;
uint8_t status;
uint8_t msg;
CRITICAL_STORE;
/* Compiler warnings */
param = param;
/* Run a Put/Get pair many times */
loop_cnt = NUM_TEST_LOOPS;
while (loop_cnt--)

View File

@@ -45,8 +45,8 @@ static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE];
/* Forward declarations */
static void test1_thread_func (uint32_t data);
static void test2_thread_func (uint32_t data);
static void test1_thread_func (uint32_t param);
static void test2_thread_func (uint32_t param);
/**
@@ -298,14 +298,17 @@ uint32_t test_start (void)
*
* Entry point for test thread 1.
*
* @param[in] data Unused (optional thread entry parameter)
* @param[in] param Unused (optional thread entry parameter)
*
* @return None
*/
static void test1_thread_func (uint32_t data)
static void test1_thread_func (uint32_t param)
{
uint8_t status;
/* Compiler warnings */
param = param;
/*
* Wait on sem1 with no timeout. We are expecting to be woken up
* by the main thread while blocking.
@@ -337,13 +340,16 @@ static void test1_thread_func (uint32_t data)
*
* Entry point for test thread 2.
*
* @param[in] data Unused (optional thread entry parameter)
* @param[in] param Unused (optional thread entry parameter)
*
* @return None
*/
static void test2_thread_func (uint32_t data)
static void test2_thread_func (uint32_t param)
{
uint8_t status;
/* Compiler warnings */
param = param;
/*
* Wait on sem1 with timeout. We are expecting to be woken up

View File

@@ -49,7 +49,7 @@ static volatile uint8_t wake_order[4];
/* Forward declarations */
static void test_thread_func (uint32_t data);
static void test_thread_func (uint32_t param);
/**
@@ -242,16 +242,16 @@ uint32_t test_start (void)
* four test threads, with the thread number/ID (1-4) passed as the entry
* point parameter.
*
* @param[in] data Thread number (1,2,3,4)
* @param[in] param Thread number (1,2,3,4)
*
* @return None
*/
static void test_thread_func (uint32_t data)
static void test_thread_func (uint32_t param)
{
uint8_t thread_id;
/* Thread ID is passed through the function parameter */
thread_id = (uint8_t)data;
thread_id = (uint8_t)param;
/*
* Wait for sem1 to be posted. At creation of all test threads

View File

@@ -55,7 +55,7 @@ static volatile int g_failures;
/* Forward declarations */
static void test_thread_func (uint32_t data);
static void test_thread_func (uint32_t param);
/**
@@ -231,16 +231,19 @@ uint32_t test_start (void)
* Entry point for test thread. The same thread entry point is used for all
* four test threads.
*
* @param[in] data Unused (optional thread entry parameter)
* @param[in] param Unused (optional thread entry parameter)
*
* @return None
*/
static void test_thread_func (uint32_t data)
static void test_thread_func (uint32_t param)
{
uint32_t loop_cnt;
uint8_t status;
CRITICAL_STORE;
/* Compiler warnings */
param = param;
/* Run a Get/Put pair many times */
loop_cnt = NUM_TEST_LOOPS;
while (loop_cnt--)

View File

@@ -44,7 +44,7 @@ static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE];
/* Forward declarations */
static void test_thread_func (uint32_t data);
static void test_thread_func (uint32_t param);
/**
@@ -193,14 +193,17 @@ uint32_t test_start (void)
*
* Entry point for test thread.
*
* @param[in] data Unused (optional thread entry parameter)
* @param[in] param Unused (optional thread entry parameter)
*
* @return None
*/
static void test_thread_func (uint32_t data)
static void test_thread_func (uint32_t param)
{
uint8_t status;
/* Compiler warnings */
param = param;
/* Block on sem1. Main thread will post when we should wake up. */
if ((status = atomSemGet (&sem1, 0)) != ATOM_OK)
{

View File

@@ -48,7 +48,7 @@ static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE];
/* Forward declarations */
static void test_thread_func (uint32_t data);
static void test_thread_func (uint32_t param);
/**
@@ -176,16 +176,19 @@ uint32_t test_start (void)
*
* Entry point for test thread.
*
* @param[in] data Unused (optional thread entry parameter)
* @param[in] param Unused (optional thread entry parameter)
*
* @return None
*/
static void test_thread_func (uint32_t data)
static void test_thread_func (uint32_t param)
{
uint8_t status;
int count;
int failures;
/* Compiler warnings */
param = param;
/*
* Attempt to decrement sem1 ten times, which should happen immediately
* each time.

View File

@@ -48,7 +48,7 @@ static volatile int shared_data;
/* Forward declarations */
static void test_thread_func (uint32_t data);
static void test_thread_func (uint32_t param);
/**
@@ -262,14 +262,17 @@ uint32_t test_start (void)
*
* Entry point for test thread.
*
* @param[in] data Unused (optional thread entry parameter)
* @param[in] param Unused (optional thread entry parameter)
*
* @return None
*/
static void test_thread_func (uint32_t data)
static void test_thread_func (uint32_t param)
{
uint8_t status;
/* Compiler warnings */
param = param;
/* Repeatedly attempt to get the mutex and set shared_data to 1 */
while (1)
{

View File

@@ -48,7 +48,7 @@ static volatile int test_running;
/* Forward declarations */
static void test_thread_func (uint32_t data);
static void test_thread_func (uint32_t param);
static void testCallback (POINTER cb_data);
@@ -221,17 +221,17 @@ uint32_t test_start (void)
*
* Entry point for test thread.
*
* @param[in] data sleep_flag passed through here
* @param[in] param sleep_flag passed through here
*
* @return None
*/
static void test_thread_func (uint32_t data)
static void test_thread_func (uint32_t param)
{
uint8_t status;
int sleep_flag, count, failures;
/* Were we requested to sleep occasionally? */
sleep_flag = (int)data;
sleep_flag = (int)param;
/* Run until the main thread sets the finish flag or we get an error */
failures = 0;

View File

@@ -48,7 +48,7 @@ static volatile int pass_flag[3];
/* Forward declarations */
static void test_thread_func (uint32_t data);
static void test_thread_func (uint32_t param);
/**
@@ -185,17 +185,17 @@ uint32_t test_start (void)
*
* Entry point for test threads.
*
* @param[in] data Thread ID (0-2)
* @param[in] param Thread ID (0-2)
*
* @return None
*/
static void test_thread_func (uint32_t data)
static void test_thread_func (uint32_t param)
{
uint8_t status;
int thread_id;
/* Pull out the passed thread ID */
thread_id = (int)data;
thread_id = (int)param;
/*
* Wait on sem1 with timeout. We are expecting to be woken up

View File

@@ -50,7 +50,7 @@ static volatile int g_failure_cnt[3];
/* Forward declarations */
static void test_thread_func (uint32_t data);
static void test_thread_func (uint32_t param);
/**
@@ -157,17 +157,17 @@ uint32_t test_start (void)
* three test threads, with the thread number/ID (1-3) passed as the entry
* point parameter.
*
* @param[in] data Thread number (1,2,3)
* @param[in] param Thread number (1,2,3)
*
* @return None
*/
static void test_thread_func (uint32_t data)
static void test_thread_func (uint32_t param)
{
uint8_t thread_id;
uint32_t start_time, end_time;
/* Thread ID is passed through the function parameter */
thread_id = (uint8_t)data;
thread_id = (uint8_t)param;
/*
* Sleep for 1 tick to ensure that the thread starts near