mirror of
https://github.com/kelvinlawson/atomthreads.git
synced 2026-01-24 16:53:14 +01:00
Compare commits
35 Commits
release1.1
...
release1.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
916dc11a0c | ||
|
|
b4bc5a9c53 | ||
|
|
e218dbb7be | ||
|
|
545a6932a4 | ||
|
|
912c83f74e | ||
|
|
e34c5a0ffa | ||
|
|
9e4da88b1d | ||
|
|
d25a49edeb | ||
|
|
c9ae8200db | ||
|
|
61e6ca0b10 | ||
|
|
b79c5c7f44 | ||
|
|
2ec7fd2d8c | ||
|
|
eafe07cea9 | ||
|
|
5bc174d316 | ||
|
|
babfd6b9c5 | ||
|
|
5635706d4b | ||
|
|
7f2b53dd61 | ||
|
|
4b42544c3c | ||
|
|
62c2ae9fec | ||
|
|
af47062d90 | ||
|
|
b39b4eac47 | ||
|
|
91793d1398 | ||
|
|
f050c44d73 | ||
|
|
98547058bf | ||
|
|
0a2df500dc | ||
|
|
d4f68440a2 | ||
|
|
02c9cd040c | ||
|
|
973e2fb4aa | ||
|
|
205c05dc25 | ||
|
|
5402faf224 | ||
|
|
c0c953b476 | ||
|
|
619c8c3e4a | ||
|
|
08098370d4 | ||
|
|
394e04ec4a | ||
|
|
538a535fe9 |
@@ -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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, Atomthreads Project. All rights reserved.
|
||||
* 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
|
||||
|
||||
@@ -7,10 +7,11 @@ License: BSD Revised
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
STM8 PORT
|
||||
STM8 PORT - COSMIC COMPILER
|
||||
|
||||
This folder contains a port of the Atomthreads real time kernel for the
|
||||
STM8 processor architecture.
|
||||
STM8 processor architecture. These instructions cover usage of Atomthreads
|
||||
with the Cosmic compiler (CXSTM8).
|
||||
|
||||
All of the cross-platform kernel code is contained in the top-level
|
||||
'kernel' folder, while ports to specific CPU architectures are contained in
|
||||
@@ -20,7 +21,7 @@ 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.s: The main register save/restore assembler routines
|
||||
* atomport-asm-cosmic.s: The main register save/restore assembler routines
|
||||
|
||||
Each Atomthreads port requires also a header file which describes various
|
||||
architecture-specific details such as appropriate types for 8-bit, 16-bit
|
||||
@@ -43,10 +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, utilising the Cosmic 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.
|
||||
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.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
@@ -56,8 +60,8 @@ PREREQUISITES
|
||||
The port works out-of-the-box with the Cosmic compiler tools for building.
|
||||
Applications are generated in .s19 form and can be programmed with any
|
||||
supporting programming software, including the free STVP (visual
|
||||
programmer tool). At this time ST do not provide a command-line programmer
|
||||
application suitable for use with STM8.
|
||||
programmer tool). At this time there does not appear to be a command-line
|
||||
programmer application suitable for use with STM8.
|
||||
|
||||
The Cosmic compiler and STVP are currently Windows-only applications. For
|
||||
users of other operating systems the Cosmic compiler may work in
|
||||
@@ -112,13 +116,15 @@ automated tests.
|
||||
|
||||
BUILD VIA STVD PROJECT
|
||||
|
||||
For building applications using STVD you can use the sample project file
|
||||
atomthreads-sample.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.
|
||||
@@ -152,25 +158,25 @@ should set up your environment variables as follows:
|
||||
|
||||
The full build is carried out using simply:
|
||||
|
||||
* make
|
||||
* make -f cosmic.mak
|
||||
|
||||
All objects are built into the 'build' folder under ports/stm8. The build
|
||||
process builds separate target applications for each automated test, and
|
||||
appropriate .stm8 or .s19 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 objects are built into the 'build-cosmic' folder under ports/stm8. The
|
||||
build process builds separate target applications for each automated test,
|
||||
and appropriate .stm8 or .s19 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 clean
|
||||
* make -f cosmic.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 doxygen
|
||||
* make -f cosmic.mak doxygen
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
@@ -241,11 +247,12 @@ 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 modify
|
||||
PART in the Makefile (or the preprocessor settings for both Debug and
|
||||
Release projects if using the STVD project) to specify your CPU. You may
|
||||
also wish to enable any CPU peripherals which you wish to use in the
|
||||
stm8s_conf.h file.
|
||||
If you are using a CPU other than the STM8S105C6 you should change the
|
||||
PART macro from "STM8S105" to your target CPU. This can be changed in the
|
||||
cosmic.mak Makefile. If you are using the STVD project it should be
|
||||
changed in the project preprocessor settings for both Debug and Release
|
||||
builds. You may also wish to enable any CPU peripherals which you wish to
|
||||
use in the stm8s_conf.h file.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
@@ -255,10 +262,16 @@ 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. Each of
|
||||
these tests is built as an independent application 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.
|
||||
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
|
||||
@@ -291,10 +304,10 @@ 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.stw. 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:
|
||||
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:
|
||||
|
||||
* Toolset: "STM8 Cosmic"
|
||||
* MCU Selection: Appropriate for your platform (STM8S10C56 for Discovery)
|
||||
@@ -347,9 +360,9 @@ 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 161 bytes of stack. At this time the timer2 test is
|
||||
the largest consumer of test thread stack (95 bytes) and the sem4 test
|
||||
consumes the largest main thread stack (161 bytes). If your applications
|
||||
been seen to consume 163 bytes of stack. At this time the timer2 test is
|
||||
the largest consumer of test thread stack (95 bytes) and the sem3 test
|
||||
consumes the largest main thread stack (163 bytes). If your applications
|
||||
have large amounts of local data or call several subroutines then you may
|
||||
find that you need larger than 128 bytes.
|
||||
|
||||
@@ -436,4 +449,73 @@ included in any STM8 products. If it is included in future products then
|
||||
you will need to put the device in the stack compatible mode described.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
WRITING NEW INTERRUPT HANDLERS
|
||||
|
||||
All interrupt handlers which will call out to the OS kernel and potentially
|
||||
cause a thread switch must call atomIntEnter() and atomIntExit(). An
|
||||
example of this can be seen in the timer tick ISR in atomport.c.
|
||||
|
||||
With the Cosmic compiler port it is also necessary to add the @svlreg
|
||||
modifier to any interrupt handlers which call out to the OS kernel.
|
||||
Alternatively you may use the INTERRUPT macro from atomport-private.h which
|
||||
always adds the @svlreg modifier. This modifier ensures that the c_lreg
|
||||
virtual register is saved on the interrupted thread's stack for any
|
||||
preemptive context switches. It also ensures that longs are available for
|
||||
use within any OS kernel code called as part of the interrupt handling.
|
||||
|
||||
You may also implement fast interrupt handlers in the system which do not
|
||||
call atomIntEnter()/atomIntExit() and which do not need the @svlreg
|
||||
modifier, however these ISRs cannot perform OS functions such as posting
|
||||
semaphores or effecting a thread switch.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
COSMIC COMPILER VIRTUAL REGISTERS
|
||||
|
||||
The STM8 has only very few CPU registers, so the Cosmic compiler augments
|
||||
them with three "virtual" registers, which are simply locations in fast
|
||||
memory. These registers are called c_x, c_y and c_lreg.
|
||||
|
||||
The Atomthreads context switch for Cosmic/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.
|
||||
With the Cosmic compiler, interrupt handlers that call out to C functions
|
||||
(as would happen on a thread switch) always save the CPU registers (done by
|
||||
the CPU in fact) and the virtual registers c_x and c_y. For the Atomthreads
|
||||
port we force interrupt handlers to also save the virtual register c_lreg.
|
||||
This is to ensure that the interrupted thread's c_lreg value is preserved
|
||||
across a thread switch, but also ensures that longs can be used within the
|
||||
OS kernel code called by interrupt handlers (c_lreg is used by the compiler
|
||||
for handling longs and floats).
|
||||
|
||||
An alternative scheme would be to not save c_lreg in all interrupt
|
||||
handlers and instead save it in the context-switch function. This would
|
||||
allow interrupt handlers to avoid saving the 4-byte c_lreg on the stack,
|
||||
but it would mean that any OS kernel code called by interrupt handlers
|
||||
could not deal with longs, which would be an unfortunate burden on the
|
||||
core portable OS code just for the benefit of this one architecture and
|
||||
compiler. It would also mean that c_lreg is always saved unnecessarily
|
||||
for every cooperative context switch.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
449
ports/stm8/README-IAR
Normal file
449
ports/stm8/README-IAR
Normal file
@@ -0,0 +1,449 @@
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Library: Atomthreads
|
||||
Author: Kelvin Lawson <kelvinl@users.sf.net>
|
||||
Website: http://atomthreads.com
|
||||
License: BSD Revised
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
STM8 PORT - IAR 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 IAR Embedded Workbench compiler (EWSTM8).
|
||||
|
||||
All of the cross-platform kernel code is contained in the top-level
|
||||
'kernel' folder, while ports to specific CPU architectures are contained in
|
||||
the 'ports' folder tree. A port to a CPU architecture can comprise just one
|
||||
or two modules which provide the architecture-specific functionality, such
|
||||
as the context-switch routine which saves and restores processor registers
|
||||
on a thread switch. In this case, the kernel port is split into two files:
|
||||
|
||||
* atomport.c: Those functions which can be written in C
|
||||
* atomport-asm-iar.s: The main register save/restore assembler routines
|
||||
|
||||
Each Atomthreads port requires also a header file which describes various
|
||||
architecture-specific details such as appropriate types for 8-bit, 16-bit
|
||||
etc variables, the port's system tick frequency, and macros for performing
|
||||
interrupt lockouts / critical sections:
|
||||
|
||||
* 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 IAR compiler. Instructions
|
||||
for users of the other compilers are available in README-COSMIC and
|
||||
README-RAISONANCE.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
PREREQUISITES
|
||||
|
||||
The port works out-of-the-box with the IAR compiler tools for building.
|
||||
Applications are generated in ELF format and can be programmed and debugged
|
||||
using the IAR Embedded Workbench GUI or 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.
|
||||
|
||||
IAR Embedded Workbench for STM8 is a Windows-only application. For
|
||||
users of other operating systems the IAR tools may work in environments
|
||||
like Wine, but the USB programming tools are less likely to be supported.
|
||||
Embedded Workbench for STM8 can, however, be run successfully within a VM
|
||||
such as VirtualBox, including USB download and debug.
|
||||
|
||||
The core software prerequisites are therefore:
|
||||
* IAR Embedded Workbench STM8
|
||||
|
||||
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).
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
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 Embedded Workbench (EWSTM8) project. The EWSTM8 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 EWSTM8 PROJECT
|
||||
|
||||
For building applications using the EWSTM8 IDE you can use the sample
|
||||
project file atomthreads-sample-iar.ewp. 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. You can start the application running, 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 EWSTM8 environment.
|
||||
|
||||
For a Windows system you can obtain a Make application suitable for use
|
||||
with the IAR 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\IAR Systems\Embedded Workbench 6.0\stm8\bin
|
||||
* set MAKE_MODE=DOS
|
||||
|
||||
|
||||
The full build is carried out using simply:
|
||||
|
||||
* make -f iar.mak
|
||||
|
||||
All objects are built into the 'build-iar' folder under ports/stm8. The
|
||||
build process builds separate target applications for each automated test,
|
||||
and appropriate .elf or .s19 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 iar.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 iar.mak doxygen
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
PROGRAMMING MAKEFILE-BUILT APPLICATIONS TO THE TARGET DEVICE
|
||||
|
||||
When developing within EWSTM8, 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 EWSTM8. 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 .s19 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
|
||||
iar.mak Makefile. If you are using the EWSTM8 project it should be
|
||||
changed in the project C/C++ Compiler Preprocessor settings for both Debug
|
||||
and Release builds, and you must also change the target device in the
|
||||
project's "General Options". You may also wish to enable any CPU
|
||||
peripherals which you wish to use in the stm8s_conf.h file.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
RUNNING THE AUTOMATED TESTS
|
||||
|
||||
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 EWSTM8 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 EWSTM8 can be started using the sample project
|
||||
atomthreads-sample-iar.ewp. If you wish to create your own EWSTM8 project
|
||||
from scratch, then you should ensure you change the project settings for
|
||||
both Debug and Release builds as follows:
|
||||
|
||||
* General Options -> Target -> Device: CPU part (e.g. "STM8S105C6")
|
||||
* C/C++ Compiler -> Diagnostics: Suppress "Pa050"
|
||||
* C/C++ Compiler -> Preprocessor -> Defined Symbols:
|
||||
CPU part (e.g. "STM8S105")
|
||||
Thread stack-checking if required ("ATOM_STACK_CHECKING")
|
||||
For example "STM8S105, ATOM_STACK_CHECKING"
|
||||
* Assembler -> Diagnostics: Suppress "Pa050"
|
||||
* Repeat above for Debug and Release projects (you may want to
|
||||
disable ATOM_STACK_CHECKING for Release builds).
|
||||
|
||||
Other options you may wish to change:
|
||||
|
||||
* Tools -> Options -> Editor -> EOL Characters: "Preserve". This preserves
|
||||
the line endings, bearing in mind that the Atomthreads kernels works
|
||||
with many host operating system toolchains.
|
||||
* Options -> Debugger -> "ST Link" (e.g. for STM8S Discovery)
|
||||
|
||||
Add the .C and .S modules from the following folders:
|
||||
* kernel
|
||||
* ports/stm8
|
||||
* ports/stm8s-periphs
|
||||
|
||||
Set include paths as appropriate.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
RAM FOOTPRINT & STACK USAGE
|
||||
|
||||
The Atomthreads kernel is written in well-structured pure C which is highly
|
||||
portable and not targeted at any particular compiler or CPU architecture.
|
||||
For this reason it is not highly optimised for the STM8 architecture, and
|
||||
by its nature will likely have a higher text and data footprint than an
|
||||
RTOS targeted at the STM8 architecture only. The emphasis here is on
|
||||
C-based portable, readable and maintainable code which can run on any CPU
|
||||
architecture, from the 8-bitters up.
|
||||
|
||||
A good rule of thumb when using Atomthreads on the STM8 architecture is
|
||||
that a minimum of 1KB RAM is required in order to support an application
|
||||
with 4 or 5 threads and the idle thread. If a minimum of approximately
|
||||
128 bytes per thread stack is acceptable then you will benefit from the
|
||||
easy-to-read, portable implementation of an RTOS herein.
|
||||
|
||||
The major consumer of RAM when using Atomthreads is your thread stacks.
|
||||
Functionality that is shared between several kernel modules is farmed out
|
||||
to separate functions, resulting in readable and maintainable code but
|
||||
with some associated stack cost of calling out to subroutines. Further,
|
||||
each thread stack is used for saving its own registers on a context
|
||||
switch, and there is no separate interrupt stack which means that each
|
||||
thread stack has to be able to cope with the maximum stack usage of the
|
||||
kernel (and application) interrupt handlers.
|
||||
|
||||
Clearly the stack requirement for each thread depends on what your
|
||||
application code does, and what memory model is used etc, but generally
|
||||
you should find that 128 bytes is enough to allow for the thread to be
|
||||
switched out (and thus save its registers) while deep within a kernel
|
||||
or application call stack, and similarly enough to provide stack for
|
||||
interrupt handlers interrupting while the thread is deep within a kernel
|
||||
or application call stack. You will need to increase this depending on
|
||||
what level of stack the application code in question requires.
|
||||
|
||||
At this time the maximum stack consumed by the test threads within the
|
||||
automated test modules is 85 bytes of stack, and the main test thread has
|
||||
been seen to consume 193 bytes of stack. At this time the queue9 test is
|
||||
the largest consumer of test thread stack (85 bytes) and the sem8 test
|
||||
consumes the largest main thread stack (193 bytes). If your applications
|
||||
have large amounts of local data or call several subroutines then you may
|
||||
find that you need larger than 128 bytes.
|
||||
|
||||
You may monitor the stack usage of your application threads during runtime
|
||||
by defining the macro ATOM_STACK_CHECKING and calling
|
||||
atomThreadStackCheck(). This macro is defined by default in the EWSTM8
|
||||
Debug project so that the automated test modules can check for stack
|
||||
overflows, but you may wish to undefine this in your application
|
||||
when you are happy that the stack usage is acceptable. Enabling
|
||||
ATOM_STACK_CHECKING will increase the size of your threads' TCBs
|
||||
slightly, and will incur a minor CPU cycles overhead whenever threads are
|
||||
created due to prefilling the thread stack with a known value.
|
||||
|
||||
With careful consideration and few threads it would be possible to use
|
||||
a platform with 512 bytes RAM, but not all of the automated test suite
|
||||
would run on such a platform (some of the test modules use 6 threads: a
|
||||
main thread together with 4 test threads and the idle thread).
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
INTERRUPT HANDLING
|
||||
|
||||
Interrupt handlers use the stack of the thread which was running when the
|
||||
interrupt occurred. If no thread rescheduling occurs during the ISR then
|
||||
on exit from the ISR any data stacked by the ISR on the thread's stack is
|
||||
popped off the stack and execution of the thread resumes. If a reschedule
|
||||
during the ISR causes a context switch to a new thread, then the ISR's
|
||||
data will remain on the thread's stack until the thread is scheduled back
|
||||
in.
|
||||
|
||||
Interrupt priorities (via the ITC_SPRx registers) are left in their
|
||||
default power-on state, which disables interrupt nesting. Kernel changes
|
||||
may be required to support interrupt nesting.
|
||||
|
||||
Note that the STM8 programming manual currently describes the following
|
||||
feature:
|
||||
|
||||
"Fast interrupt handling through alternate register files (up to 4
|
||||
contexts) with standard stack compatible mode (for real time OS
|
||||
kernels)"
|
||||
|
||||
This feature was implemented by ST in the core but has to date never been
|
||||
included in any STM8 products. If it is included in future products then
|
||||
you will need to put the device in the stack compatible mode described.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
WRITING NEW INTERRUPT HANDLERS
|
||||
|
||||
All interrupt handlers which will call out to the OS kernel and potentially
|
||||
cause a thread switch must call atomIntEnter() and atomIntExit(). An
|
||||
example of this can be seen in the timer tick ISR in atomport.c.
|
||||
|
||||
You may also implement fast interrupt handlers in the system which do not
|
||||
call atomIntEnter()/atomIntExit(), however these ISRs cannot perform OS
|
||||
functions such as posting semaphores or effecting a thread switch.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
IAR COMPILER VIRTUAL REGISTERS
|
||||
|
||||
The STM8 has only very few CPU registers, so the IAR compiler augments
|
||||
them with sixteen "virtual" registers, which are simply locations in fast
|
||||
memory. These registers are called ?b0 to ?b15.
|
||||
|
||||
The Atomthreads context switch for IAR/STM8 takes advantage of the fact
|
||||
that all CPU and most virtual registers are automatically saved on the
|
||||
stack by the compiler when calling out to C functions (and even then only
|
||||
if necessary). Only the virtual registers ?b8 to ?b15 are expected to be
|
||||
preserved by called functions, so these are the only registers that
|
||||
callers to the context switch routine will not automatically save if
|
||||
necessary.
|
||||
|
||||
For cooperative context switches (where a thread calls an OS kernel
|
||||
function to schedule itself out), most registers will therefore already
|
||||
be saved on a thread's stack if necessary. Only ?b8 to ?b15 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 the
|
||||
virtual registers ?b0 to ?b7. Still only the registers ?b8 to ?b15 have to
|
||||
be saved by the context-switch routine, but in this case ?b0 to ?b7 and the
|
||||
CPU registers are always saved on the thread's stack by the ISR prologue.
|
||||
This is 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.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
452
ports/stm8/README-RAISONANCE
Normal file
452
ports/stm8/README-RAISONANCE
Normal 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.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
364
ports/stm8/atomport-asm-cosmic.s
Normal file
364
ports/stm8/atomport-asm-cosmic.s
Normal file
@@ -0,0 +1,364 @@
|
||||
;
|
||||
; 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.
|
||||
;
|
||||
|
||||
|
||||
; Cosmic assembler routines
|
||||
|
||||
|
||||
; Export functions to other modules
|
||||
xdef _archContextSwitch, _archFirstThreadRestore
|
||||
|
||||
|
||||
; \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 (Cosmic 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
|
||||
;
|
||||
; Cosmic compiler virtual registers:
|
||||
;
|
||||
; c_x, c_y: Scratch memory areas saved by ISRs
|
||||
; c_lreg: Scratch memory area only saved by ISRs with @svlreg
|
||||
;
|
||||
; If this is a cooperative context switch (a thread has called us
|
||||
; to schedule itself out), the Cosmic 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. Note that it is
|
||||
; necessary to add the @svlreg modifier to ISRs which call out to
|
||||
; the OS in order to force a save of c_lreg. The rest of the CPU
|
||||
; registers and the c_x and c_y virtual registers are, however,
|
||||
; always saved by ISRs which call out to C subroutines.
|
||||
;
|
||||
; 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
|
||||
396
ports/stm8/atomport-asm-iar.s
Normal file
396
ports/stm8/atomport-asm-iar.s
Normal file
@@ -0,0 +1,396 @@
|
||||
;
|
||||
; 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.
|
||||
;
|
||||
|
||||
|
||||
; IAR assembler routines
|
||||
|
||||
|
||||
NAME ATOMPORTASM
|
||||
SECTION .text:code
|
||||
|
||||
; Get definitions for virtual registers used by the compiler
|
||||
#include "vregs.inc"
|
||||
|
||||
|
||||
; \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)
|
||||
PUBLIC archContextSwitch
|
||||
archContextSwitch:
|
||||
|
||||
; Parameter locations (IAR calling convention):
|
||||
; old_tcb_ptr = X register (word-width)
|
||||
; new_tcb_ptr = Y register (word-width)
|
||||
|
||||
; STM8 CPU Registers:
|
||||
;
|
||||
; A, X, Y: Standard working registers
|
||||
; SP: Stack pointer
|
||||
; PC: Program counter
|
||||
; CC: Code condition register
|
||||
;
|
||||
; IAR compiler virtual registers
|
||||
;
|
||||
; ?b0 - ?b7: Scratch registers
|
||||
; ?b8 - ?b15: Preserved registers
|
||||
;
|
||||
; The basic scheme is that some registers will already be saved
|
||||
; onto the stack if the caller wishes them not to be clobbered.
|
||||
; We only need to context-switch additional registers which the
|
||||
; caller does not expect to be modified in a subroutine.
|
||||
;
|
||||
; If this is a cooperative context switch (a thread has called us
|
||||
; to schedule itself out), the IAR compiler will have saved any
|
||||
; of the registers which it does not want us to clobber. For IAR
|
||||
; only virtual registers ?b8 to ?b15 are expected to retain their
|
||||
; value across a function call, hence for cooperative context
|
||||
; switches with this compiler we only need to save ?b8 to ?b15.
|
||||
;
|
||||
; 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,
|
||||
; leaving only ?b8 to ?b15 which must be saved.
|
||||
;
|
||||
; The Cosmic compiler version of this context switch routine
|
||||
; does not require any registers to be saved/restored, whereas
|
||||
; this IAR equivalent reqires that 8 of the virtual registers
|
||||
; are.
|
||||
|
||||
; We also have to do a little more work in here: 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.
|
||||
|
||||
; (IAR) Compiler will have already saved any scratch registers
|
||||
; (A, X, Y, CC, and ?b0 to ?b7) which it needs before calling here
|
||||
; for cooperative switches. So these will already be on the stack
|
||||
; and do not need to be context-switched. The same goes for
|
||||
; __interrupt functions (i.e. preemptive switches): with the IAR
|
||||
; compiler A, X, Y and CC will already be saved by interrupt handlers
|
||||
; (those are actually automatically done by the CPU), and (because
|
||||
; we call out from interrupt handlers to C kernel code (e.g.
|
||||
; atomIntExit()) before calling here for a context-switch, the
|
||||
; compiler will also have saved ?b0 to ?b7. This is because those
|
||||
; called C functions cannot know they were called from an interrupt
|
||||
; and will assume that they have ?b0 to ?b7 available as scratch
|
||||
; registers. Either way (cooperative or interrupt/preemptive) we
|
||||
; know that the only registers which must be preserved that are not
|
||||
; already on the stack-frame are ?b8 to ?b15.
|
||||
PUSH ?b8
|
||||
PUSH ?b9
|
||||
PUSH ?b10
|
||||
PUSH ?b11
|
||||
PUSH ?b12
|
||||
PUSH ?b13
|
||||
PUSH ?b14
|
||||
PUSH ?b15
|
||||
|
||||
; The parameter pointing to the the old TCB (a word-width
|
||||
; pointer) is still untouched in the X register.
|
||||
|
||||
; (IAR) Take a copy of the new_tcb_ptr parameter from Y-reg in
|
||||
; a temporary (?b0) register. We need to use Y briefly for SP
|
||||
; access.
|
||||
ldw ?b0, Y
|
||||
|
||||
; 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
|
||||
; except ?b0 which contains our passed new_tcb_ptr parameter (a
|
||||
; pointer to the TCB of the thread which we wish to switch in).
|
||||
;
|
||||
; Our stack frame now contains all registers which need to be
|
||||
; preserved or context-switched. 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).
|
||||
;
|
||||
; 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. We switch
|
||||
; our stack pointer to the new thread's stack pointer, and pop its
|
||||
; context off the stack, before returning to the caller (the
|
||||
; original caller when the new thread was last scheduled out).
|
||||
|
||||
; Get the new thread's stack pointer off the TCB (new_tcb_ptr).
|
||||
; We kept a copy of new_tcb_ptr earlier in ?b0, copy it into X.
|
||||
ldw X,?b0
|
||||
|
||||
; 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
|
||||
|
||||
; (IAR) We only save/restore ?b8 to ?b15
|
||||
POP ?b15
|
||||
POP ?b14
|
||||
POP ?b13
|
||||
POP ?b12
|
||||
POP ?b11
|
||||
POP ?b10
|
||||
POP ?b9
|
||||
POP ?b8
|
||||
|
||||
; 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)
|
||||
PUBLIC archFirstThreadRestore
|
||||
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
|
||||
|
||||
; (IAR) We only context switch ?b8 to ?b15
|
||||
POP ?b15
|
||||
POP ?b14
|
||||
POP ?b13
|
||||
POP ?b12
|
||||
POP ?b11
|
||||
POP ?b10
|
||||
POP ?b9
|
||||
POP ?b8
|
||||
|
||||
; 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
|
||||
@@ -1,5 +1,5 @@
|
||||
;
|
||||
; Copyright (c) 2005, Atomthreads Project. All rights reserved.
|
||||
; 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
|
||||
@@ -28,28 +28,40 @@
|
||||
;
|
||||
|
||||
|
||||
; Raisonance assembler routines
|
||||
|
||||
|
||||
;Distinguish STM8 mode from ST7
|
||||
$modestm8
|
||||
|
||||
|
||||
; Export functions to other modules
|
||||
xdef _archContextSwitch, _archFirstThreadRestore
|
||||
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:
|
||||
?archContextSwitch:
|
||||
|
||||
; Parameter locations:
|
||||
; Parameter locations (Raisonance calling convention):
|
||||
; old_tcb_ptr = X register (word-width)
|
||||
; new_tcb_ptr = stack (word-width)
|
||||
|
||||
@@ -60,9 +72,12 @@ _archContextSwitch:
|
||||
; 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 Cosmic compiler will have saved any
|
||||
; 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
|
||||
@@ -79,10 +94,10 @@ _archContextSwitch:
|
||||
; 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
|
||||
; 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 causes all
|
||||
; registers to be saved in a similar fashion.
|
||||
; 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
|
||||
@@ -106,7 +121,7 @@ _archContextSwitch:
|
||||
; 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
|
||||
; 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
|
||||
@@ -115,7 +130,7 @@ _archContextSwitch:
|
||||
; 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
|
||||
; 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
|
||||
@@ -131,12 +146,12 @@ _archContextSwitch:
|
||||
; 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
|
||||
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
|
||||
|
||||
@@ -158,7 +173,7 @@ _archContextSwitch:
|
||||
; 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
|
||||
; 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.
|
||||
@@ -240,8 +255,8 @@ _archContextSwitch:
|
||||
; 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
|
||||
; 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,
|
||||
@@ -266,7 +281,7 @@ _archContextSwitch:
|
||||
; 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
|
||||
; after which all other new threads will first be run by
|
||||
; archContextSwitch().
|
||||
;
|
||||
; Typically ports will implement something similar here to the
|
||||
@@ -274,21 +289,21 @@ _archContextSwitch:
|
||||
; 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
|
||||
; 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
|
||||
; 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
|
||||
; 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).
|
||||
; 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
|
||||
; 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
|
||||
@@ -316,7 +331,7 @@ _archContextSwitch:
|
||||
; @return None
|
||||
;
|
||||
; void archFirstThreadRestore (ATOM_TCB *new_tcb_ptr)
|
||||
_archFirstThreadRestore:
|
||||
?archFirstThreadRestore:
|
||||
|
||||
; Parameter locations:
|
||||
; new_tcb_ptr = X register (word-width)
|
||||
@@ -324,7 +339,7 @@ _archFirstThreadRestore:
|
||||
; 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
|
||||
; 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
|
||||
@@ -339,7 +354,7 @@ _archFirstThreadRestore:
|
||||
; 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
|
||||
|
||||
@@ -350,4 +365,4 @@ _archFirstThreadRestore:
|
||||
ret
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
@@ -31,9 +31,46 @@
|
||||
#define __ATOM_PORT_PRIVATE_H
|
||||
|
||||
|
||||
/**
|
||||
* Compiler-specific modifier to prevent some functions from saving
|
||||
* and restoring registers on entry and exit, if the function is
|
||||
* known to never complete (e.g. thread entry points).
|
||||
* Reduces stack usage on supporting compilers.
|
||||
*/
|
||||
#ifdef __IAR_SYSTEMS_ICC__
|
||||
#define NO_REG_SAVE __task
|
||||
#else
|
||||
#define NO_REG_SAVE
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Compiler-specific modifiers for interrupt handler functions.
|
||||
*
|
||||
* COSMIC: Uses @interrupt modifier for interrupt handlers. We
|
||||
* also force all interrupts to save c_lreg, a separate memory
|
||||
* area which Cosmic uses for longs and floats. This memory
|
||||
* area must be saved by interrupt handlers for context
|
||||
* switch purposes, and to avoid making it impossible to use
|
||||
* 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).
|
||||
*/
|
||||
#if defined(__CSMC__)
|
||||
#define INTERRUPT @far @interrupt @svlreg
|
||||
#elif defined (__IAR_SYSTEMS_ICC__)
|
||||
#define INTERRUPT __interrupt
|
||||
#elif defined(__RCSTM8__)
|
||||
#define INTERRUPT
|
||||
#endif
|
||||
|
||||
|
||||
/* Function prototypes */
|
||||
void archInitSystemTickTimer (void);
|
||||
@far @interrupt void TIM1_SystemTickISR (void);
|
||||
|
||||
INTERRUPT void TIM1_SystemTickISR (void);
|
||||
|
||||
#endif /* __ATOM_PORT_PRIVATE_H */
|
||||
|
||||
@@ -49,7 +49,15 @@
|
||||
#define TEST_THREAD_STACK_SIZE 128
|
||||
|
||||
/* Uncomment to enable logging of stack usage to UART */
|
||||
/* #define TESTS_LOG_STACK_USAGE */
|
||||
#define TESTS_LOG_STACK_USAGE
|
||||
|
||||
/**
|
||||
* IAR EWSTM8: Ignore warnings on volatile ordering thrown up
|
||||
* by ATOMLOG() statements in the test modules.
|
||||
*/
|
||||
#ifdef __IAR_SYSTEMS_ICC__
|
||||
#pragma diag_suppress=Pa082
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __ATOM_PORT_TESTS_H */
|
||||
|
||||
@@ -31,10 +31,13 @@
|
||||
#include "atom.h"
|
||||
#include "atomport-private.h"
|
||||
#include "stm8s_tim1.h"
|
||||
#if defined(__RCSTM8__)
|
||||
#include <intrins.h>
|
||||
#endif
|
||||
|
||||
|
||||
/** Forward declarations */
|
||||
static void thread_shell (void);
|
||||
static NO_REG_SAVE void thread_shell (void);
|
||||
|
||||
|
||||
/**
|
||||
@@ -66,9 +69,16 @@ static void thread_shell (void);
|
||||
* first time because you can preinitialise the stack context with
|
||||
* a suitable register value that will enable interrupts.
|
||||
*
|
||||
* If the compiler supports it, stack space can be saved by preventing
|
||||
* the function from saving registers on entry. This is because we
|
||||
* are called directly by the context-switch assembler, and know that
|
||||
* threads cannot return from here. The NO_REG_SAVE macro is used to
|
||||
* denote such functions in a compiler-agnostic way, though not all
|
||||
* compilers support it.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static void thread_shell (void)
|
||||
static NO_REG_SAVE void thread_shell (void)
|
||||
{
|
||||
ATOM_TCB *curr_tcb;
|
||||
|
||||
@@ -79,7 +89,13 @@ static void thread_shell (void)
|
||||
* Enable interrupts - these will not be enabled when a thread
|
||||
* is first restored.
|
||||
*/
|
||||
#if defined(__CSMC__)
|
||||
_asm("rim");
|
||||
#elif defined(__IAR_SYSTEMS_ICC__)
|
||||
rim();
|
||||
#elif defined(__RCSTM8__)
|
||||
_rim_();
|
||||
#endif
|
||||
|
||||
/* Call the thread entry point */
|
||||
if (curr_tcb && curr_tcb->entry_point)
|
||||
@@ -101,19 +117,30 @@ static void thread_shell (void)
|
||||
* and running the thread via archFirstThreadRestore() or
|
||||
* archContextSwitch().
|
||||
*
|
||||
* On this port we take advantage of the fact that when the context
|
||||
* switch routine is called the compiler 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 this, it is not
|
||||
* necessary to prefill a new thread's stack with any register
|
||||
* values here. The only entry we need to make in the stack is the
|
||||
* thread's entry point - this is not exactly restored when the
|
||||
* (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
|
||||
* this, it is not necessary to prefill a new thread's stack with any
|
||||
* register values here. The only entry we need to make in the stack
|
||||
* is the thread's entry point - this is not exactly restored when
|
||||
* the thread is context switched in, but rather is popped off the
|
||||
* stack by the context switch routine's RET call. That is used to
|
||||
* direct the program counter to our thread's entry point - we are
|
||||
* faking a return to a caller which never actually existed.
|
||||
*
|
||||
* (IAR) The IAR compiler works around the lack of CPU registers on
|
||||
* STM8 by allocating some space in low SRAM which is used for
|
||||
* "virtual" registers. The compiler uses these like normal CPU
|
||||
* registers, and hence their values must be preserved when
|
||||
* context-switching between threads. Some of these (?b8 to ?b15)
|
||||
* are expected to be preserved by called functions, and hence we
|
||||
* actually need to save/restore those registers (unlike the rest
|
||||
* of the virtual registers and the standard CPU registers). We
|
||||
* therefore must prefill the stack with values for ?b8 to ?b15
|
||||
* here.
|
||||
*
|
||||
* We could pre-initialise the stack so that the RET call goes
|
||||
* directly to the thread entry point, with the thread entry
|
||||
* parameter filled in. On this architecture, however, we use an
|
||||
@@ -172,11 +199,28 @@ void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, void (*entry_poi
|
||||
*/
|
||||
|
||||
/**
|
||||
* In this port we do not initialise any registers via the initial
|
||||
* stack context at all. All thread context has now been
|
||||
* initialised. All that is left is to save the current stack
|
||||
* pointer to the thread's TCB so that it knows where to start
|
||||
* looking when the thread is started.
|
||||
* (IAR) Set up initial values for ?b8 to ?b15.
|
||||
*/
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
*stack_ptr-- = 0; // ?b8
|
||||
*stack_ptr-- = 0; // ?b9
|
||||
*stack_ptr-- = 0; // ?b10
|
||||
*stack_ptr-- = 0; // ?b11
|
||||
*stack_ptr-- = 0; // ?b12
|
||||
*stack_ptr-- = 0; // ?b13
|
||||
*stack_ptr-- = 0; // ?b14
|
||||
*stack_ptr-- = 0; // ?b15
|
||||
#endif
|
||||
|
||||
/**
|
||||
* (COSMIC & RAISONANCE) We do not initialise any registers via the
|
||||
* initial stack context at all.
|
||||
*/
|
||||
|
||||
/**
|
||||
* All thread context has now been initialised. All that is left
|
||||
* is to save the current stack pointer to the thread's TCB so
|
||||
* that it knows where to start looking when the thread is started.
|
||||
*/
|
||||
tcb_ptr->sp_save_ptr = stack_ptr;
|
||||
|
||||
@@ -192,16 +236,16 @@ void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, void (*entry_poi
|
||||
*/
|
||||
void archInitSystemTickTimer ( void )
|
||||
{
|
||||
/* Reset TIM1 */
|
||||
/* Reset TIM1 */
|
||||
TIM1_DeInit();
|
||||
|
||||
/* Configure a 10ms tick */
|
||||
|
||||
/* Configure a 10ms tick */
|
||||
TIM1_TimeBaseInit(10000, TIM1_COUNTERMODE_UP, 1, 0);
|
||||
|
||||
/* Generate an interrupt on timer count overflow */
|
||||
|
||||
/* Generate an interrupt on timer count overflow */
|
||||
TIM1_ITConfig(TIM1_IT_UPDATE, ENABLE);
|
||||
|
||||
/* Enable TIM1 */
|
||||
|
||||
/* Enable TIM1 */
|
||||
TIM1_Cmd(ENABLE);
|
||||
|
||||
}
|
||||
@@ -243,7 +287,13 @@ void archInitSystemTickTimer ( void )
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void TIM1_SystemTickISR (void)
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
#pragma vector = 13
|
||||
#endif
|
||||
INTERRUPT void TIM1_SystemTickISR (void)
|
||||
#if defined(__RCSTM8__)
|
||||
interrupt 11
|
||||
#endif
|
||||
{
|
||||
/* Call the interrupt entry routine */
|
||||
atomIntEnter();
|
||||
@@ -252,7 +302,7 @@ void TIM1_SystemTickISR (void)
|
||||
atomTimerTick();
|
||||
|
||||
/* Ack the interrupt (Clear TIM1:SR1 register bit 0) */
|
||||
TIM1->SR1 = (uint8_t)(~(uint8_t)TIM1_IT_UPDATE);
|
||||
TIM1->SR1 = (uint8_t)(~(uint8_t)TIM1_IT_UPDATE);
|
||||
|
||||
/* Call the interrupt exit routine */
|
||||
atomIntExit(TRUE);
|
||||
|
||||
@@ -33,6 +33,12 @@
|
||||
|
||||
#include "stm8s_type.h"
|
||||
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
#include "intrinsics.h"
|
||||
#elif defined (__RCSTM8__)
|
||||
#include <intrins.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* Required number of system ticks per second (normally 100 for 10ms tick) */
|
||||
#define SYSTEM_TICKS_PER_SEC 100
|
||||
@@ -51,10 +57,25 @@
|
||||
|
||||
|
||||
/* Critical region protection */
|
||||
|
||||
/* COSMIC: Use inline assembler */
|
||||
#if defined(__CSMC__)
|
||||
#define CRITICAL_STORE uint8_t ccr
|
||||
#define CRITICAL_START() _asm ("push CC\npop a\nld (X),A\nsim", &ccr)
|
||||
#define CRITICAL_END() _asm ("ld A,(X)\npush A\npop CC", &ccr)
|
||||
|
||||
/* IAR: Use intrinsics */
|
||||
#elif defined(__IAR_SYSTEMS_ICC__)
|
||||
#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 */
|
||||
/* #define ATOM_STACK_CHECKING */
|
||||
|
||||
@@ -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
|
||||
@@ -83,10 +83,10 @@ String.100.0=STM8S105C6
|
||||
|
||||
[Root.Config.0.Settings.3]
|
||||
String.2.0=Compiling $(InputFile)...
|
||||
String.3.0=cxstm8 +modsl0 -customDebCompat -customOpt-no -customC-pp -customLst -l -dSTM8S105 -dATOM_STACK_CHECKING -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
|
||||
String.3.0=cxstm8 +modsl0 -customDebCompat -customOpt -no +split -customC-pp -customLst -l -dSTM8S105 -dATOM_STACK_CHECKING -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
|
||||
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
|
||||
String.5.0=$(IntermPath)$(InputName).ls
|
||||
String.6.0=2010,3,6,17,19,51
|
||||
String.6.0=2010,5,27,22,48,49
|
||||
|
||||
[Root.Config.0.Settings.4]
|
||||
String.2.0=Assembling $(InputFile)...
|
||||
@@ -166,10 +166,10 @@ String.100.0=STM8S105C6
|
||||
|
||||
[Root.Config.1.Settings.3]
|
||||
String.2.0=Compiling $(InputFile)...
|
||||
String.3.0=cxstm8 +modsl0 -customC-pp -dSTM8S105 -dATOM_STACK_CHECKING -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
|
||||
String.3.0=cxstm8 +modsl0 -customOpt +split -customC-pp -dSTM8S105 -dATOM_STACK_CHECKING -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
|
||||
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
|
||||
String.5.0=$(IntermPath)$(InputName).ls
|
||||
String.6.0=2010,3,6,17,19,51
|
||||
String.6.0=2010,5,27,22,48,49
|
||||
|
||||
[Root.Config.1.Settings.4]
|
||||
String.2.0=Assembling $(InputFile)...
|
||||
@@ -189,7 +189,7 @@ String.3.0=clnk $(ToolsetLibOpts) -o $(OutputPath)$(TargetSName).sm8 -fakeIntege
|
||||
String.3.1=cvdwarf $(OutputPath)$(TargetSName).sm8
|
||||
String.4.0=$(OutputPath)$(TargetFName)
|
||||
String.5.0=$(OutputPath)$(ProjectSFile).elf
|
||||
String.6.0=2010,3,9,0,24,9
|
||||
String.6.0=2010,5,27,22,49,45
|
||||
String.100.0=
|
||||
String.101.0=crtsi.st7
|
||||
String.102.0=+seg .const -b 0x8080 -m 0x7f80 -n .const -it
|
||||
@@ -206,7 +206,7 @@ String.103.1=Eeprom[0x4000-0x43ff]=.eeprom
|
||||
String.103.2=Zero Page[0x2-0xff]=.bsct,.ubsct,.bit,.share
|
||||
String.103.3=Ram[0x100-0x7bf]=.data,.bss
|
||||
String.104.0=0x7ff
|
||||
String.105.0=libis0.sm8;libm0.sm8
|
||||
String.105.0=libisl0.sm8;libm0.sm8
|
||||
Int.0=0
|
||||
Int.1=0
|
||||
|
||||
@@ -247,10 +247,10 @@ Int.1=0
|
||||
|
||||
[Root.Kernel.Config.0.Settings.1]
|
||||
String.2.0=Compiling $(InputFile)...
|
||||
String.3.0=cxstm8 +modsl0 -customDebCompat -customOpt-no -customC-pp -customLst -l -dSTM8S105 -dATOM_STACK_CHECKING -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
|
||||
String.3.0=cxstm8 +modsl0 -customDebCompat -customOpt -no +split -customC-pp -customLst -l -dSTM8S105 -dATOM_STACK_CHECKING -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
|
||||
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
|
||||
String.5.0=$(IntermPath)$(InputName).ls
|
||||
String.6.0=2010,3,6,17,19,51
|
||||
String.6.0=2010,5,27,22,48,49
|
||||
|
||||
[Root.Kernel.Config.0.Settings.2]
|
||||
String.2.0=Assembling $(InputFile)...
|
||||
@@ -271,10 +271,10 @@ Int.1=0
|
||||
|
||||
[Root.Kernel.Config.1.Settings.1]
|
||||
String.2.0=Compiling $(InputFile)...
|
||||
String.3.0=cxstm8 +modsl0 -customC-pp -dSTM8S105 -dATOM_STACK_CHECKING -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
|
||||
String.3.0=cxstm8 +modsl0 -customOpt +split -customC-pp -dSTM8S105 -dATOM_STACK_CHECKING -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
|
||||
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
|
||||
String.5.0=$(IntermPath)$(InputName).ls
|
||||
String.6.0=2010,3,6,17,19,51
|
||||
String.6.0=2010,5,27,22,48,49
|
||||
|
||||
[Root.Kernel.Config.1.Settings.2]
|
||||
String.2.0=Assembling $(InputFile)...
|
||||
@@ -364,10 +364,10 @@ Int.1=0
|
||||
|
||||
[Root.Peripherals.Config.0.Settings.1]
|
||||
String.2.0=Compiling $(InputFile)...
|
||||
String.3.0=cxstm8 +modsl0 -customDebCompat -customOpt-no -customC-pp -customLst -l -dSTM8S105 -dATOM_STACK_CHECKING -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
|
||||
String.3.0=cxstm8 +modsl0 -customDebCompat -customOpt -no +split -customC-pp -customLst -l -dSTM8S105 -dATOM_STACK_CHECKING -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
|
||||
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
|
||||
String.5.0=$(IntermPath)$(InputName).ls
|
||||
String.6.0=2010,3,6,17,19,51
|
||||
String.6.0=2010,5,27,22,48,49
|
||||
|
||||
[Root.Peripherals.Config.0.Settings.2]
|
||||
String.2.0=Assembling $(InputFile)...
|
||||
@@ -391,10 +391,10 @@ Int.1=0
|
||||
|
||||
[Root.Peripherals.Config.1.Settings.1]
|
||||
String.2.0=Compiling $(InputFile)...
|
||||
String.3.0=cxstm8 +modsl0 -customC-pp -dSTM8S105 -dATOM_STACK_CHECKING -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
|
||||
String.3.0=cxstm8 +modsl0 -customOpt +split -customC-pp -dSTM8S105 -dATOM_STACK_CHECKING -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
|
||||
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
|
||||
String.5.0=$(IntermPath)$(InputName).ls
|
||||
String.6.0=2010,3,6,17,19,51
|
||||
String.6.0=2010,5,27,22,48,49
|
||||
|
||||
[Root.Peripherals.Config.1.Settings.2]
|
||||
String.2.0=Assembling $(InputFile)...
|
||||
@@ -491,10 +491,10 @@ Int.1=0
|
||||
|
||||
[Root.Port.Config.0.Settings.1]
|
||||
String.2.0=Compiling $(InputFile)...
|
||||
String.3.0=cxstm8 +modsl0 -customDebCompat -customOpt-no -customC-pp -customLst -l -dSTM8S105 -dATOM_STACK_CHECKING -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
|
||||
String.3.0=cxstm8 +modsl0 -customDebCompat -customOpt -no +split -customC-pp -customLst -l -dSTM8S105 -dATOM_STACK_CHECKING -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
|
||||
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
|
||||
String.5.0=$(IntermPath)$(InputName).ls
|
||||
String.6.0=2010,3,6,17,19,51
|
||||
String.6.0=2010,5,27,22,48,49
|
||||
|
||||
[Root.Port.Config.0.Settings.2]
|
||||
String.2.0=Assembling $(InputFile)...
|
||||
@@ -518,10 +518,10 @@ Int.1=0
|
||||
|
||||
[Root.Port.Config.1.Settings.1]
|
||||
String.2.0=Compiling $(InputFile)...
|
||||
String.3.0=cxstm8 +modsl0 -customC-pp -dSTM8S105 -dATOM_STACK_CHECKING -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
|
||||
String.3.0=cxstm8 +modsl0 -customOpt +split -customC-pp -dSTM8S105 -dATOM_STACK_CHECKING -istm8s-periphs -i../../kernel -i../../tests $(ToolsetIncOpts) -cl$(IntermPath) -co$(IntermPath) $(InputFile)
|
||||
String.4.0=$(IntermPath)$(InputName).$(ObjectExt)
|
||||
String.5.0=$(IntermPath)$(InputName).ls
|
||||
String.6.0=2010,3,6,17,19,51
|
||||
String.6.0=2010,5,27,22,48,49
|
||||
|
||||
[Root.Port.Config.1.Settings.2]
|
||||
String.2.0=Assembling $(InputFile)...
|
||||
@@ -580,11 +580,11 @@ Next=Root.Port.atomport.c
|
||||
[Root.Port.atomport.c]
|
||||
ElemType=File
|
||||
PathName=atomport.c
|
||||
Next=Root.Port.atomport-asm.s
|
||||
Next=Root.Port.atomport-asm-cosmic.s
|
||||
|
||||
[Root.Port.atomport-asm.s]
|
||||
[Root.Port.atomport-asm-cosmic.s]
|
||||
ElemType=File
|
||||
PathName=atomport-asm.s
|
||||
PathName=atomport-asm-cosmic.s
|
||||
Next=Root.Port.stm8_interrupt_vector.c
|
||||
|
||||
[Root.Port.stm8_interrupt_vector.c]
|
||||
369
ports/stm8/atomthreads-sample-iar.ewd
Normal file
369
ports/stm8/atomthreads-sample-iar.ewd
Normal file
@@ -0,0 +1,369 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
|
||||
<project>
|
||||
<fileVersion>2</fileVersion>
|
||||
<configuration>
|
||||
<name>Debug</name>
|
||||
<toolchain>
|
||||
<name>STM8</name>
|
||||
</toolchain>
|
||||
<debug>1</debug>
|
||||
<settings>
|
||||
<name>C-SPY</name>
|
||||
<archiveVersion>1</archiveVersion>
|
||||
<data>
|
||||
<version>0</version>
|
||||
<wantNonLocal>1</wantNonLocal>
|
||||
<debug>1</debug>
|
||||
<option>
|
||||
<name>CSpyMandatory</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSpyInput</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSpyRunToEnable</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSpyRunToName</name>
|
||||
<state>main</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSpyMacOverride</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSpyMacFile</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>DynDriver</name>
|
||||
<state>STLINK_STM8</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSpyDDFOverride</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSpyDDFFile</name>
|
||||
<state>$TOOLKIT_DIR$\config\ddf\iostm8s105c6.ddf</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSpyEnableExtraOptions</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSpyExtraOptions</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSpyImagesSuppressCheck1</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSpyImagesPath1</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSpyImagesSuppressCheck2</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSpyImagesPath2</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSpyImagesSuppressCheck3</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSpyImagesPath3</name>
|
||||
<state></state>
|
||||
</option>
|
||||
</data>
|
||||
</settings>
|
||||
<settings>
|
||||
<name>SIMULATOR_STM8</name>
|
||||
<archiveVersion>1</archiveVersion>
|
||||
<data>
|
||||
<version>0</version>
|
||||
<wantNonLocal>1</wantNonLocal>
|
||||
<debug>1</debug>
|
||||
<option>
|
||||
<name>SimMandatory</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
</data>
|
||||
</settings>
|
||||
<settings>
|
||||
<name>STICE_STM8</name>
|
||||
<archiveVersion>1</archiveVersion>
|
||||
<data>
|
||||
<version>0</version>
|
||||
<wantNonLocal>1</wantNonLocal>
|
||||
<debug>1</debug>
|
||||
<option>
|
||||
<name>STiceMandatory</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>STiceSuppressLoad</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>STiceVerifyLoad</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>STiceLogFileOver</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>STiceLogFile</name>
|
||||
<state>$PROJ_DIR$\cspycomm.log</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>STiceUseSwim</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
</data>
|
||||
</settings>
|
||||
<settings>
|
||||
<name>STLINK_STM8</name>
|
||||
<archiveVersion>1</archiveVersion>
|
||||
<data>
|
||||
<version>0</version>
|
||||
<wantNonLocal>1</wantNonLocal>
|
||||
<debug>1</debug>
|
||||
<option>
|
||||
<name>STlinkMandatory</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>STlinkSuppressLoad</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>STlinkVerifyLoad</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>STlinkLogFileOver</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>STlinkLogFile</name>
|
||||
<state>$PROJ_DIR$\cspycomm.log</state>
|
||||
</option>
|
||||
</data>
|
||||
</settings>
|
||||
<debuggerPlugins>
|
||||
<plugin>
|
||||
<file>$EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin</file>
|
||||
<loadFlag>1</loadFlag>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<file>$EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin</file>
|
||||
<loadFlag>0</loadFlag>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<file>$EW_DIR$\common\plugins\Profiling\Profiling.ENU.ewplugin</file>
|
||||
<loadFlag>1</loadFlag>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<file>$EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin</file>
|
||||
<loadFlag>1</loadFlag>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<file>$EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin</file>
|
||||
<loadFlag>1</loadFlag>
|
||||
</plugin>
|
||||
</debuggerPlugins>
|
||||
</configuration>
|
||||
<configuration>
|
||||
<name>Release</name>
|
||||
<toolchain>
|
||||
<name>STM8</name>
|
||||
</toolchain>
|
||||
<debug>0</debug>
|
||||
<settings>
|
||||
<name>C-SPY</name>
|
||||
<archiveVersion>1</archiveVersion>
|
||||
<data>
|
||||
<version>0</version>
|
||||
<wantNonLocal>1</wantNonLocal>
|
||||
<debug>0</debug>
|
||||
<option>
|
||||
<name>CSpyMandatory</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSpyInput</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSpyRunToEnable</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSpyRunToName</name>
|
||||
<state>main</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSpyMacOverride</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSpyMacFile</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>DynDriver</name>
|
||||
<state>STLINK_STM8</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSpyDDFOverride</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSpyDDFFile</name>
|
||||
<state>$TOOLKIT_DIR$\config\ddf\iostm8s105c6.ddf</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSpyEnableExtraOptions</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSpyExtraOptions</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSpyImagesSuppressCheck1</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSpyImagesPath1</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSpyImagesSuppressCheck2</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSpyImagesPath2</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSpyImagesSuppressCheck3</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CSpyImagesPath3</name>
|
||||
<state></state>
|
||||
</option>
|
||||
</data>
|
||||
</settings>
|
||||
<settings>
|
||||
<name>SIMULATOR_STM8</name>
|
||||
<archiveVersion>1</archiveVersion>
|
||||
<data>
|
||||
<version>0</version>
|
||||
<wantNonLocal>1</wantNonLocal>
|
||||
<debug>0</debug>
|
||||
<option>
|
||||
<name>SimMandatory</name>
|
||||
<state>1</state>
|
||||
</option>
|
||||
</data>
|
||||
</settings>
|
||||
<settings>
|
||||
<name>STICE_STM8</name>
|
||||
<archiveVersion>1</archiveVersion>
|
||||
<data>
|
||||
<version>0</version>
|
||||
<wantNonLocal>1</wantNonLocal>
|
||||
<debug>0</debug>
|
||||
<option>
|
||||
<name>STiceMandatory</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>STiceSuppressLoad</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>STiceVerifyLoad</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>STiceLogFileOver</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>STiceLogFile</name>
|
||||
<state>$PROJ_DIR$\cspycomm.log</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>STiceUseSwim</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
</data>
|
||||
</settings>
|
||||
<settings>
|
||||
<name>STLINK_STM8</name>
|
||||
<archiveVersion>1</archiveVersion>
|
||||
<data>
|
||||
<version>0</version>
|
||||
<wantNonLocal>1</wantNonLocal>
|
||||
<debug>0</debug>
|
||||
<option>
|
||||
<name>STlinkMandatory</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>STlinkSuppressLoad</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>STlinkVerifyLoad</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>STlinkLogFileOver</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>STlinkLogFile</name>
|
||||
<state>$PROJ_DIR$\cspycomm.log</state>
|
||||
</option>
|
||||
</data>
|
||||
</settings>
|
||||
<debuggerPlugins>
|
||||
<plugin>
|
||||
<file>$EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin</file>
|
||||
<loadFlag>1</loadFlag>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<file>$EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin</file>
|
||||
<loadFlag>0</loadFlag>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<file>$EW_DIR$\common\plugins\Profiling\Profiling.ENU.ewplugin</file>
|
||||
<loadFlag>1</loadFlag>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<file>$EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin</file>
|
||||
<loadFlag>1</loadFlag>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<file>$EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin</file>
|
||||
<loadFlag>1</loadFlag>
|
||||
</plugin>
|
||||
</debuggerPlugins>
|
||||
</configuration>
|
||||
</project>
|
||||
|
||||
|
||||
3132
ports/stm8/atomthreads-sample-iar.ewp
Normal file
3132
ports/stm8/atomthreads-sample-iar.ewp
Normal file
File diff suppressed because it is too large
Load Diff
545
ports/stm8/atomthreads-sample-raisonance.stp
Normal file
545
ports/stm8/atomthreads-sample-raisonance.stp
Normal 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
|
||||
16
ports/stm8/atomthreads-sample-stvd.stw
Normal file
16
ports/stm8/atomthreads-sample-stvd.stw
Normal file
@@ -0,0 +1,16 @@
|
||||
; STMicroelectronics Workspace file
|
||||
|
||||
[Version]
|
||||
Keyword=ST7Workspace-V0.7
|
||||
|
||||
[Project0]
|
||||
Filename=atomthreads-sample-cosmic.stp
|
||||
Dependencies=
|
||||
|
||||
[Project1]
|
||||
Filename=atomthreads-sample-raisonance.stp
|
||||
Dependencies=
|
||||
[Options]
|
||||
ActiveProject=atomthreads-cosmic
|
||||
ActiveConfig=Debug
|
||||
AddSortedElements=0
|
||||
@@ -1,12 +0,0 @@
|
||||
; STMicroelectronics Workspace file
|
||||
|
||||
[Version]
|
||||
Keyword=ST7Workspace-V0.7
|
||||
|
||||
[Project0]
|
||||
Filename=atomthreads-sample.stp
|
||||
Dependencies=
|
||||
[Options]
|
||||
ActiveProject=atomthreads
|
||||
ActiveConfig=Debug
|
||||
AddSortedElements=0
|
||||
@@ -38,7 +38,7 @@ build\stm8s_uart2.o
|
||||
build\tests-main.o
|
||||
build\atomport.o
|
||||
build\uart.o
|
||||
build\atomport-asm.o
|
||||
build\atomport-asm-cosmic.o
|
||||
# Caller passes in test application object name as param1
|
||||
@1
|
||||
#<END OBJECT_FILES>
|
||||
|
||||
@@ -2,8 +2,13 @@
|
||||
# Settings #
|
||||
############
|
||||
|
||||
# Set up build environment (using GNU Make)
|
||||
# set PATH=%PATH%;C:\Program Files\GNU_MAKE;C:\Program Files\COSMIC\CXSTM8_16K
|
||||
# set MAKE_MODE=DOS
|
||||
|
||||
# Build all test applications:
|
||||
# make
|
||||
# make -f cosmic.mak
|
||||
|
||||
|
||||
# Location of build tools and atomthreads sources
|
||||
KERNEL_DIR=../../kernel
|
||||
@@ -14,17 +19,19 @@ CC=cxstm8
|
||||
ASM=castm8
|
||||
LINK=clnk
|
||||
CHEX=chex
|
||||
|
||||
# CPU part number
|
||||
PART=STM8S105
|
||||
|
||||
# Enable stack-checking
|
||||
STACK_CHECK=true
|
||||
|
||||
# Directory for built objects
|
||||
BUILD_DIR=build
|
||||
BUILD_DIR=build-cosmic
|
||||
|
||||
# Port/application object files
|
||||
APP_OBJECTS = atomport.o tests-main.o stm8_interrupt_vector.o uart.o
|
||||
APP_ASM_OBJECTS = atomport-asm.o
|
||||
APP_ASM_OBJECTS = atomport-asm-cosmic.o
|
||||
|
||||
# STM8S Peripheral driver object files
|
||||
PERIPH_OBJECTS = stm8s_gpio.o stm8s_tim1.o stm8s_clk.o stm8s_uart2.o
|
||||
@@ -49,8 +56,8 @@ vpath %.elf .\$(BUILD_DIR)
|
||||
vpath %.hex .\$(BUILD_DIR)
|
||||
|
||||
# Compiler/Assembler flags
|
||||
CFLAGS=+modsl0 -pp -d$(PART)
|
||||
DBG_CFLAGS=+modsl0 +debug -pxp -no -pp -l -d$(PART)
|
||||
CFLAGS=+modsl0 +split -pp -d$(PART)
|
||||
DBG_CFLAGS=+modsl0 +split +debug -pxp -no -pp -l -d$(PART)
|
||||
ASMFLAGS=
|
||||
DBG_ASMFLAGS=-xx -u
|
||||
|
||||
@@ -66,7 +73,7 @@ endif
|
||||
#################
|
||||
|
||||
# All tests
|
||||
all: $(BUILD_DIR) $(TEST_S19S) Makefile
|
||||
all: $(BUILD_DIR) $(TEST_S19S) cosmic.mak
|
||||
|
||||
# Make build/output directory
|
||||
$(BUILD_DIR):
|
||||
@@ -79,7 +86,7 @@ $(TEST_S19S): %.s19: %.stm8
|
||||
|
||||
# Test ELF files (one application build for each test)
|
||||
$(TEST_STM8S): %.stm8: %.o $(KERNEL_OBJECTS) $(PERIPH_OBJECTS) $(APP_OBJECTS) $(APP_ASM_OBJECTS)
|
||||
$(LINK) -l$(LIBS_DIR) -o $(BUILD_DIR)/$@ atomthreads.lkf $(BUILD_DIR)/$(notdir $<)
|
||||
$(LINK) -l$(LIBS_DIR) -o $(BUILD_DIR)/$@ -m $(BUILD_DIR)/$(basename $@).map atomthreads.lkf $(BUILD_DIR)/$(notdir $<)
|
||||
|
||||
# Kernel objects builder
|
||||
$(KERNEL_OBJECTS): %.o: $(KERNEL_DIR)/%.c
|
||||
@@ -89,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) $<
|
||||
|
||||
@@ -106,7 +113,7 @@ clean:
|
||||
rm -f *.o *.elf *.map *.hex *.bin *.lst *.stm8 *.s19
|
||||
rm -rf doxygen-kernel
|
||||
rm -rf doxygen-stm8
|
||||
rm -rf build
|
||||
rm -rf build-cosmic
|
||||
|
||||
doxygen:
|
||||
doxygen $(KERNEL_DIR)/Doxyfile
|
||||
137
ports/stm8/iar.mak
Normal file
137
ports/stm8/iar.mak
Normal file
@@ -0,0 +1,137 @@
|
||||
############
|
||||
# Settings #
|
||||
############
|
||||
|
||||
# Set up build environment (using GNU Make)
|
||||
# set PATH=%PATH%;C:\Program Files\GNU_MAKE;C:\Program Files\IAR Systems\Embedded Workbench 6.0\stm8\bin
|
||||
# set MAKE_MODE=DOS
|
||||
|
||||
# Build all test applications:
|
||||
# make -f iar.mak
|
||||
|
||||
|
||||
# Location of build tools and atomthreads sources
|
||||
EWSTM8_DIR=C:\Program Files\IAR Systems\Embedded Workbench 6.0\stm8
|
||||
KERNEL_DIR=../../kernel
|
||||
TESTS_DIR=../../tests
|
||||
PERIPHS_DIR=stm8s-periphs
|
||||
CC=iccstm8
|
||||
ASM=iasmstm8
|
||||
LINK=ilinkstm8
|
||||
HEX=ielftool
|
||||
|
||||
# CPU part number
|
||||
PART=STM8S105
|
||||
|
||||
# Enable stack-checking
|
||||
STACK_CHECK=true
|
||||
|
||||
# Directory for built objects
|
||||
BUILD_DIR=build-iar
|
||||
|
||||
# Port/application object files
|
||||
APP_OBJECTS = atomport.o tests-main.o uart.o
|
||||
APP_ASM_OBJECTS = atomport-asm-iar.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))
|
||||
|
||||
# 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 (.elf) for each test object
|
||||
TEST_ELFS = $(patsubst %.o,%.elf,$(TEST_OBJECTS))
|
||||
TEST_S19S = $(patsubst %.o,%.s19,$(TEST_OBJECTS))
|
||||
|
||||
# Search build/output directory for dependencies
|
||||
vpath %.o .\$(BUILD_DIR)
|
||||
vpath %.elf .\$(BUILD_DIR)
|
||||
vpath %.hex .\$(BUILD_DIR)
|
||||
|
||||
# Compiler/Assembler flags
|
||||
CFLAGS=-e -Oh --code_model small --data_model medium \
|
||||
--dlib_config "$(EWSTM8_DIR)\lib\dlstm8smn.h" -D NDEBUG -D $(PART) \
|
||||
--diag_suppress Pa050
|
||||
DBG_CFLAGS=-e -Ol --no_cse --no_unroll --no_inline --no_code_motion --no_tbaa \
|
||||
--no_cross_call --debug --code_model small --data_model medium \
|
||||
--dlib_config "$(EWSTM8_DIR)\lib\dlstm8smn.h" -D $(PART) \
|
||||
--diag_suppress Pa050
|
||||
|
||||
ASMFLAGS=-M'<>' -ld $(BUILD_DIR)\list --diag_suppress Pa050 --code_model small \
|
||||
--data_model medium
|
||||
DBG_ASMFLAGS=-M'<>' -r -ld $(BUILD_DIR)\list --diag_suppress Pa050 --code_model small \
|
||||
--data_model medium
|
||||
|
||||
LINKFLAGS=--redirect _Printf=_PrintfSmall --redirect _Scanf=_ScanfSmall \
|
||||
--config "$(EWSTM8_DIR)\config\lnkstm8s105c6.icf" --config_def \
|
||||
_CSTACK_SIZE=0x100 --config_def _HEAP_SIZE=0x100 \
|
||||
--entry __iar_program_start
|
||||
DBG_LINKFLAGS=--redirect _Printf=_PrintfSmall --redirect _Scanf=_ScanfSmall \
|
||||
--config "$(EWSTM8_DIR)\config\lnkstm8s105c6.icf" --config_def \
|
||||
_CSTACK_SIZE=0x100 --config_def _HEAP_SIZE=0x100 \
|
||||
--entry __iar_program_start
|
||||
|
||||
# Enable stack-checking (disable if not required)
|
||||
ifeq ($(STACK_CHECK),true)
|
||||
CFLAGS += -D ATOM_STACK_CHECKING
|
||||
DBG_CFLAGS += -D ATOM_STACK_CHECKING
|
||||
endif
|
||||
|
||||
|
||||
#################
|
||||
# Build targets #
|
||||
#################
|
||||
|
||||
# All tests
|
||||
all: $(BUILD_DIR) $(TEST_S19S) iar.mak
|
||||
|
||||
# Make build/output directory
|
||||
$(BUILD_DIR):
|
||||
mkdir $(BUILD_DIR)
|
||||
|
||||
# Test HEX files (one application build for each test)
|
||||
$(TEST_S19S): %.s19: %.elf
|
||||
@echo Building $@
|
||||
$(HEX) $(BUILD_DIR)/$(notdir $<) $(BUILD_DIR)/$@ --srec
|
||||
|
||||
# Test ELF files (one application build for each test)
|
||||
$(TEST_ELFS): %.elf: %.o $(KERNEL_OBJECTS) $(PERIPH_OBJECTS) $(APP_OBJECTS) $(APP_ASM_OBJECTS)
|
||||
$(LINK) $(BUILD_DIR)/$(notdir $<) $(BUILT_OBJECTS) $(LINKFLAGS) -o $(BUILD_DIR)/$@
|
||||
|
||||
# Kernel objects builder
|
||||
$(KERNEL_OBJECTS): %.o: $(KERNEL_DIR)/%.c
|
||||
$(CC) $< $(CFLAGS) -I . -I $(PERIPHS_DIR) -o $(BUILD_DIR)
|
||||
|
||||
# Test objects builder
|
||||
$(TEST_OBJECTS): %.o: $(TESTS_DIR)/%.c
|
||||
$(CC) $< $(CFLAGS) -I . -I $(KERNEL_DIR) -I $(PERIPHS_DIR) -o $(BUILD_DIR)
|
||||
|
||||
# Peripheral objects builder
|
||||
$(PERIPH_OBJECTS): %.o: $(PERIPHS_DIR)/%.c
|
||||
$(CC) $< $(CFLAGS) -I . -I $(PERIPHS_DIR) -o $(BUILD_DIR)
|
||||
|
||||
# Application C objects builder
|
||||
$(APP_OBJECTS): %.o: ./%.c
|
||||
$(CC) $< $(CFLAGS) -I $(KERNEL_DIR) -I $(TESTS_DIR) -I $(PERIPHS_DIR) -o $(BUILD_DIR)
|
||||
|
||||
# Application asm objects builder
|
||||
$(APP_ASM_OBJECTS): %.o: ./%.s
|
||||
$(ASM) $< $(ASMFLAGS) -I $(KERNEL_DIR) -o $(BUILD_DIR)/$(notdir $@)
|
||||
|
||||
# Clean
|
||||
clean:
|
||||
rm -f *.o *.elf *.map *.hex *.bin *.lst *.stm8 *.s19 *.out
|
||||
rm -rf doxygen-kernel
|
||||
rm -rf doxygen-stm8
|
||||
rm -rf build-iar
|
||||
|
||||
doxygen:
|
||||
doxygen $(KERNEL_DIR)/Doxyfile
|
||||
doxygen ./Doxyfile
|
||||
126
ports/stm8/raisonance.mak
Normal file
126
ports/stm8/raisonance.mak
Normal 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
|
||||
@@ -3,6 +3,9 @@
|
||||
*/
|
||||
|
||||
|
||||
/* COSMIC: Requires interrupt vector table */
|
||||
#if defined(__CSMC__)
|
||||
|
||||
/* Import Atomthreads system tick ISR prototype */
|
||||
#include "atomport-private.h"
|
||||
|
||||
@@ -58,3 +61,5 @@ struct interrupt_vector const _vectab[] = {
|
||||
{0x82, NonHandledInterrupt}, /* irq28 */
|
||||
{0x82, NonHandledInterrupt}, /* irq29 */
|
||||
};
|
||||
|
||||
#endif /* __CSMC__ */
|
||||
|
||||
@@ -29,10 +29,16 @@
|
||||
/* Check the used compiler */
|
||||
#if defined(__CSMC__)
|
||||
#undef _RAISONANCE_
|
||||
#undef _IAR_SYSTEMS_
|
||||
#define _COSMIC_
|
||||
#elif defined(__RCST7__)
|
||||
#undef _COSMIC_
|
||||
#undef _IAR_SYSTEMS_
|
||||
#define _RAISONANCE_
|
||||
#elif defined(__IAR_SYSTEMS_ICC__)
|
||||
#undef _COSMIC_
|
||||
#undef _RAISONANCE_
|
||||
#define _IAR_SYSTEMS_
|
||||
#else
|
||||
#error "Unsupported Compiler!" /* Compiler defines not found */
|
||||
#endif
|
||||
@@ -42,7 +48,8 @@
|
||||
Tip: To avoid modifying this file each time you need to switch between these
|
||||
devices, you can define the device in your toolchain compiler preprocessor. */
|
||||
#if !defined (STM8S208) && !defined (STM8S207) && !defined (STM8S105) && !defined (STM8S103) && !defined (STM8S903)
|
||||
#define STM8S208
|
||||
# error "STM8S device not specified"
|
||||
/* #define STM8S208 */
|
||||
/* #define STM8S207 */
|
||||
/* #define STM8S105 */
|
||||
/* #define STM8S103 */
|
||||
@@ -67,12 +74,21 @@
|
||||
#define NEAR @near
|
||||
#define TINY @tiny
|
||||
#define __CONST const
|
||||
#else /* __RCST7__ */
|
||||
#endif
|
||||
|
||||
#ifdef _RAISONANCE_
|
||||
#define FAR far
|
||||
#define NEAR data
|
||||
#define TINY page0
|
||||
#define __CONST code
|
||||
#endif /* __CSMC__ */
|
||||
#endif
|
||||
|
||||
#ifdef _IAR_SYSTEMS_
|
||||
#define FAR __far
|
||||
#define NEAR __near
|
||||
#define TINY __tiny
|
||||
#define __CONST const
|
||||
#endif
|
||||
|
||||
#ifdef PointerAttr_Far
|
||||
#define PointerAttr FAR
|
||||
@@ -2495,7 +2511,9 @@ CFG_TypeDef;
|
||||
#define trap() _trap_() /* Trap (soft IT) */
|
||||
#define wfi() _wfi_() /* Wait For Interrupt */
|
||||
#define halt() _halt_() /* Halt */
|
||||
#else /* COSMIC */
|
||||
#endif
|
||||
|
||||
#ifdef _COSMIC_
|
||||
#define enableInterrupts() {_asm("rim\n");} /* enable interrupts */
|
||||
#define disableInterrupts() {_asm("sim\n");} /* disable interrupts */
|
||||
#define rim() {_asm("rim\n");} /* enable interrupts */
|
||||
@@ -2506,6 +2524,18 @@ CFG_TypeDef;
|
||||
#define halt() {_asm("halt\n");} /* Halt */
|
||||
#endif
|
||||
|
||||
#ifdef _IAR_SYSTEMS_
|
||||
#include <intrinsics.h>
|
||||
#define enableInterrupts() __enable_interrupt() /* enable interrupts */
|
||||
#define disableInterrupts() __disable_interrupt() /* disable interrupts */
|
||||
#define rim() __enable_interrupt() /* enable interrupts */
|
||||
#define sim() __disable_interrupt() /* disable interrupts */
|
||||
#define nop() __no_operation() /* No Operation */
|
||||
#define trap() __trap_() /* Trap (soft IT) */
|
||||
#define wfi() __wait_for_interrupt() /* Wait For Interrupt */
|
||||
#define halt() __halt_() /* Halt */
|
||||
#endif
|
||||
|
||||
/*============================== Handling bits ====================================*/
|
||||
/*-----------------------------------------------------------------------------
|
||||
Method : I
|
||||
|
||||
@@ -49,549 +49,6 @@ uc8 CLKPrescTable[8] = {1, 2, 4, 8, 10, 16, 20, 40}; /*!< Holds the different CL
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Deinitializes the CLK peripheral registers to their default reset
|
||||
* values.
|
||||
* @par Parameters:
|
||||
* None
|
||||
* @retval None
|
||||
* @par Warning:
|
||||
* Resetting the CCOR register: \n
|
||||
* When the CCOEN bit is set, the reset of the CCOR register require
|
||||
* two consecutive write instructions in order to reset first the CCOEN bit
|
||||
* and the second one is to reset the CCOSEL bits.
|
||||
*/
|
||||
void CLK_DeInit(void)
|
||||
{
|
||||
|
||||
CLK->ICKR = CLK_ICKR_RESET_VALUE;
|
||||
CLK->ECKR = CLK_ECKR_RESET_VALUE;
|
||||
CLK->SWR = CLK_SWR_RESET_VALUE;
|
||||
CLK->SWCR = CLK_SWCR_RESET_VALUE;
|
||||
CLK->CKDIVR = CLK_CKDIVR_RESET_VALUE;
|
||||
CLK->PCKENR1 = CLK_PCKENR1_RESET_VALUE;
|
||||
CLK->PCKENR2 = CLK_PCKENR2_RESET_VALUE;
|
||||
CLK->CSSR = CLK_CSSR_RESET_VALUE;
|
||||
CLK->CCOR = CLK_CCOR_RESET_VALUE;
|
||||
while (CLK->CCOR & CLK_CCOR_CCOEN)
|
||||
{}
|
||||
CLK->CCOR = CLK_CCOR_RESET_VALUE;
|
||||
CLK->CANCCR = CLK_CANCCR_RESET_VALUE;
|
||||
CLK->HSITRIMR = CLK_HSITRIMR_RESET_VALUE;
|
||||
CLK->SWIMCCR = CLK_SWIMCCR_RESET_VALUE;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures the High Speed Internal oscillator (HSI).
|
||||
* @par Full description:
|
||||
* If CLK_FastHaltWakeup is enabled, HSI oscillator is automatically
|
||||
* switched-on (HSIEN=1) and selected as next clock master
|
||||
* (CKM=SWI=HSI) when resuming from HALT/ActiveHalt modes.\n
|
||||
* @param[in] NewState this parameter is the Wake-up Mode state.
|
||||
* @retval None
|
||||
*/
|
||||
void CLK_FastHaltWakeUpCmd(FunctionalState NewState)
|
||||
{
|
||||
|
||||
/* check the parameters */
|
||||
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
|
||||
|
||||
if (NewState != DISABLE)
|
||||
{
|
||||
/* Set FHWU bit (HSI oscillator is automatically switched-on) */
|
||||
CLK->ICKR |= CLK_ICKR_FHWU;
|
||||
}
|
||||
else /* FastHaltWakeup = DISABLE */
|
||||
{
|
||||
/* Reset FHWU bit */
|
||||
CLK->ICKR &= (u8)(~CLK_ICKR_FHWU);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable or Disable the External High Speed oscillator (HSE).
|
||||
* @param[in] NewState new state of HSEEN, value accepted ENABLE, DISABLE.
|
||||
* @retval None
|
||||
*/
|
||||
void CLK_HSECmd(FunctionalState NewState)
|
||||
{
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
|
||||
|
||||
if (NewState != DISABLE)
|
||||
{
|
||||
/* Set HSEEN bit */
|
||||
CLK->ECKR |= CLK_ECKR_HSEEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Reset HSEEN bit */
|
||||
CLK->ECKR &= (u8)(~CLK_ECKR_HSEEN);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables or disables the Internal High Speed oscillator (HSI).
|
||||
* @param[in] NewState new state of HSIEN, value accepted ENABLE, DISABLE.
|
||||
* @retval None
|
||||
*/
|
||||
void CLK_HSICmd(FunctionalState NewState)
|
||||
{
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
|
||||
|
||||
if (NewState != DISABLE)
|
||||
{
|
||||
/* Set HSIEN bit */
|
||||
CLK->ICKR |= CLK_ICKR_HSIEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Reset HSIEN bit */
|
||||
CLK->ICKR &= (u8)(~CLK_ICKR_HSIEN);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables or disables the Internal Low Speed oscillator (LSI).
|
||||
* @param[in] NewState new state of LSIEN, value accepted ENABLE, DISABLE.
|
||||
* @retval None
|
||||
*/
|
||||
void CLK_LSICmd(FunctionalState NewState)
|
||||
{
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
|
||||
|
||||
if (NewState != DISABLE)
|
||||
{
|
||||
/* Set LSIEN bit */
|
||||
CLK->ICKR |= CLK_ICKR_LSIEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Reset LSIEN bit */
|
||||
CLK->ICKR &= (u8)(~CLK_ICKR_LSIEN);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables or disablle the Configurable Clock Output (CCO).
|
||||
* @param[in] NewState : New state of CCEN bit (CCO register).
|
||||
* This parameter can be any of the @ref FunctionalState enumeration.
|
||||
* @retval None
|
||||
*/
|
||||
void CLK_CCOCmd(FunctionalState NewState)
|
||||
{
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
|
||||
|
||||
if (NewState != DISABLE)
|
||||
{
|
||||
/* Set CCOEN bit */
|
||||
CLK->CCOR |= CLK_CCOR_CCOEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Reset CCOEN bit */
|
||||
CLK->CCOR &= (u8)(~CLK_CCOR_CCOEN);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts or Stops manually the clock switch execution.
|
||||
* @par Full description:
|
||||
* NewState parameter set the SWEN.
|
||||
* @param[in] NewState new state of SWEN, value accepted ENABLE, DISABLE.
|
||||
* @retval None
|
||||
*/
|
||||
void CLK_ClockSwitchCmd(FunctionalState NewState)
|
||||
{
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
|
||||
|
||||
if (NewState != DISABLE )
|
||||
{
|
||||
/* Enable the Clock Switch */
|
||||
CLK->SWCR |= CLK_SWCR_SWEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable the Clock Switch */
|
||||
CLK->SWCR &= (u8)(~CLK_SWCR_SWEN);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures the slow active halt wake up
|
||||
* @param[in] NewState: specifies the Slow Active Halt wake up state.
|
||||
* can be set of the following values:
|
||||
* - DISABLE: Slow Active Halt mode disabled;
|
||||
* - ENABLE: Slow Active Halt mode enabled.
|
||||
* @retval None
|
||||
*/
|
||||
void CLK_SlowActiveHaltWakeUpCmd(FunctionalState NewState)
|
||||
{
|
||||
|
||||
/* check the parameters */
|
||||
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
|
||||
|
||||
if (NewState != DISABLE)
|
||||
{
|
||||
/* Set S_ACTHALT bit */
|
||||
CLK->ICKR |= CLK_ICKR_SWUAH;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Reset S_ACTHALT bit */
|
||||
CLK->ICKR &= (u8)(~CLK_ICKR_SWUAH);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables or disables the specified peripheral CLK.
|
||||
* @param[in] CLK_Peripheral : This parameter specifies the peripheral clock to gate.
|
||||
* This parameter can be any of the @ref CLK_Peripheral_TypeDef enumeration.
|
||||
* @param[in] NewState : New state of specified peripheral clock.
|
||||
* This parameter can be any of the @ref FunctionalState enumeration.
|
||||
* @retval None
|
||||
*/
|
||||
void CLK_PeripheralClockConfig(CLK_Peripheral_TypeDef CLK_Peripheral, FunctionalState NewState)
|
||||
{
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
|
||||
assert_param(IS_CLK_PERIPHERAL_OK(CLK_Peripheral));
|
||||
|
||||
if (((u8)CLK_Peripheral & (u8)0x10) == 0x00)
|
||||
{
|
||||
if (NewState != DISABLE)
|
||||
{
|
||||
/* Enable the peripheral Clock */
|
||||
CLK->PCKENR1 |= (u8)((u8)1 << ((u8)CLK_Peripheral & (u8)0x0F));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable the peripheral Clock */
|
||||
CLK->PCKENR1 &= (u8)(~(u8)(((u8)1 << ((u8)CLK_Peripheral & (u8)0x0F))));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NewState != DISABLE)
|
||||
{
|
||||
/* Enable the peripheral Clock */
|
||||
CLK->PCKENR2 |= (u8)((u8)1 << ((u8)CLK_Peripheral & (u8)0x0F));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable the peripheral Clock */
|
||||
CLK->PCKENR2 &= (u8)(~(u8)(((u8)1 << ((u8)CLK_Peripheral & (u8)0x0F))));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief configures the Switch from one clock to another
|
||||
* @param[in] CLK_SwitchMode select the clock switch mode.
|
||||
* It can be set of the values of @ref CLK_SwitchMode_TypeDef
|
||||
* @param[in] CLK_NewClock choice of the future clock.
|
||||
* It can be set of the values of @ref CLK_Source_TypeDef
|
||||
* @param[in] NewState Enable or Disable the Clock Switch interrupt.
|
||||
* @param[in] CLK_CurrentClockState current clock to switch OFF or to keep ON.
|
||||
* It can be set of the values of @ref CLK_CurrentClockState_TypeDef
|
||||
* @retval ErrorStatus this shows the clock switch status (ERROR/SUCCESS).
|
||||
*/
|
||||
ErrorStatus CLK_ClockSwitchConfig(CLK_SwitchMode_TypeDef CLK_SwitchMode, CLK_Source_TypeDef CLK_NewClock, FunctionalState ITState, CLK_CurrentClockState_TypeDef CLK_CurrentClockState)
|
||||
{
|
||||
|
||||
CLK_Source_TypeDef clock_master;
|
||||
u16 DownCounter = CLK_TIMEOUT;
|
||||
ErrorStatus Swif = ERROR;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_CLK_SOURCE_OK(CLK_NewClock));
|
||||
assert_param(IS_CLK_SWITCHMODE_OK(CLK_SwitchMode));
|
||||
assert_param(IS_FUNCTIONALSTATE_OK(ITState));
|
||||
assert_param(IS_CLK_CURRENTCLOCKSTATE_OK(CLK_CurrentClockState));
|
||||
|
||||
/* Current clock master saving */
|
||||
clock_master = (CLK_Source_TypeDef)CLK->CMSR;
|
||||
|
||||
/* Automatic switch mode management */
|
||||
if (CLK_SwitchMode == CLK_SWITCHMODE_AUTO)
|
||||
{
|
||||
|
||||
/* Enables Clock switch */
|
||||
CLK->SWCR |= CLK_SWCR_SWEN;
|
||||
|
||||
/* Enables or Disables Switch interrupt */
|
||||
if (ITState != DISABLE)
|
||||
{
|
||||
CLK->SWCR |= CLK_SWCR_SWIEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
CLK->SWCR &= (u8)(~CLK_SWCR_SWIEN);
|
||||
}
|
||||
|
||||
/* Selection of the target clock source */
|
||||
CLK->SWR = (u8)CLK_NewClock;
|
||||
|
||||
while (((CLK->SWCR & CLK_SWCR_SWBSY) && (DownCounter != 0)))
|
||||
{
|
||||
DownCounter--;
|
||||
}
|
||||
|
||||
if (DownCounter != 0)
|
||||
{
|
||||
Swif = SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
Swif = ERROR;
|
||||
}
|
||||
|
||||
}
|
||||
else /* CLK_SwitchMode == CLK_SWITCHMODE_MANUAL */
|
||||
{
|
||||
|
||||
/* Enables or Disables Switch interrupt if required */
|
||||
if (ITState != DISABLE)
|
||||
{
|
||||
CLK->SWCR |= CLK_SWCR_SWIEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
CLK->SWCR &= (u8)(~CLK_SWCR_SWIEN);
|
||||
}
|
||||
|
||||
/* Selection of the target clock source */
|
||||
CLK->SWR = (u8)CLK_NewClock;
|
||||
|
||||
/* In manual mode, there is no risk to be stucked in a loop, value returned
|
||||
is then always SUCCESS */
|
||||
Swif = SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
/* Switch OFF current clock if required */
|
||||
if ((CLK_CurrentClockState == CLK_CURRENTCLOCKSTATE_DISABLE) && ( clock_master == CLK_SOURCE_HSI))
|
||||
{
|
||||
CLK->ICKR &= (u8)(~CLK_ICKR_HSIEN);
|
||||
}
|
||||
else if ((CLK_CurrentClockState == CLK_CURRENTCLOCKSTATE_DISABLE) && ( clock_master == CLK_SOURCE_LSI))
|
||||
{
|
||||
CLK->ICKR &= (u8)(~CLK_ICKR_LSIEN);
|
||||
}
|
||||
else if ((CLK_CurrentClockState == CLK_CURRENTCLOCKSTATE_DISABLE) && ( clock_master == CLK_SOURCE_HSE))
|
||||
{
|
||||
CLK->ECKR &= (u8)(~CLK_ECKR_HSEEN);
|
||||
}
|
||||
|
||||
return(Swif);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures the HSI clock dividers.
|
||||
* @param[in] HSIPrescaler : Specifies the HSI clock divider to apply.
|
||||
* This parameter can be any of the @ref CLK_Prescaler_TypeDef enumeration.
|
||||
* @retval None
|
||||
*/
|
||||
void CLK_HSIPrescalerConfig(CLK_Prescaler_TypeDef HSIPrescaler)
|
||||
{
|
||||
|
||||
/* check the parameters */
|
||||
assert_param(IS_CLK_HSIPRESCALER_OK(HSIPrescaler));
|
||||
|
||||
/* Clear High speed internal clock prescaler */
|
||||
CLK->CKDIVR &= (u8)(~CLK_CKDIVR_HSIDIV);
|
||||
|
||||
/* Set High speed internal clock prescaler */
|
||||
CLK->CKDIVR |= (u8)HSIPrescaler;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Output the selected clock on a dedicated I/O pin.
|
||||
* @param[in] CLK_CCO : Specifies the clock source.
|
||||
* This parameter can be any of the @ref CLK_Output_TypeDef enumeration.
|
||||
* @retval None
|
||||
* @par Required preconditions:
|
||||
* The dedicated I/O pin must be set at 1 in the corresponding Px_CR1 register \n
|
||||
* to be set as input with pull-up or push-pull output.
|
||||
*/
|
||||
void CLK_CCOConfig(CLK_Output_TypeDef CLK_CCO)
|
||||
{
|
||||
|
||||
/* check the parameters */
|
||||
assert_param(IS_CLK_OUTPUT_OK(CLK_CCO));
|
||||
|
||||
/* Clears of the CCO type bits part */
|
||||
CLK->CCOR &= (u8)(~CLK_CCOR_CCOSEL);
|
||||
|
||||
/* Selects the source provided on cco_ck output */
|
||||
CLK->CCOR |= (u8)CLK_CCO;
|
||||
|
||||
/* Enable the clock output */
|
||||
CLK->CCOR |= CLK_CCOR_CCOEN;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables or disables the specified CLK interrupts.
|
||||
* @param[in] CLK_IT This parameter specifies the interrupt sources.
|
||||
* It can be one of the values of @ref CLK_IT_TypeDef.
|
||||
* @param[in] NewState New state of the Interrupt.
|
||||
* Value accepted ENABLE, DISABLE.
|
||||
* @retval None
|
||||
*/
|
||||
void CLK_ITConfig(CLK_IT_TypeDef CLK_IT, FunctionalState NewState)
|
||||
{
|
||||
|
||||
/* check the parameters */
|
||||
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
|
||||
assert_param(IS_CLK_IT_OK(CLK_IT));
|
||||
|
||||
if (NewState != DISABLE)
|
||||
{
|
||||
switch (CLK_IT)
|
||||
{
|
||||
case CLK_IT_SWIF: /* Enable the clock switch interrupt */
|
||||
CLK->SWCR |= CLK_SWCR_SWIEN;
|
||||
break;
|
||||
case CLK_IT_CSSD: /* Enable the clock security system detection interrupt */
|
||||
CLK->CSSR |= CLK_CSSR_CSSDIE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else /*(NewState == DISABLE)*/
|
||||
{
|
||||
switch (CLK_IT)
|
||||
{
|
||||
case CLK_IT_SWIF: /* Disable the clock switch interrupt */
|
||||
CLK->SWCR &= (u8)(~CLK_SWCR_SWIEN);
|
||||
break;
|
||||
case CLK_IT_CSSD: /* Disable the clock security system detection interrupt */
|
||||
CLK->CSSR &= (u8)(~CLK_CSSR_CSSDIE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures the HSI and CPU clock dividers.
|
||||
* @param[in] ClockPrescaler Specifies the HSI or CPU clock divider to apply.
|
||||
* @retval None
|
||||
*/
|
||||
void CLK_SYSCLKConfig(CLK_Prescaler_TypeDef ClockPrescaler)
|
||||
{
|
||||
|
||||
/* check the parameters */
|
||||
assert_param(IS_CLK_PRESCALER_OK(ClockPrescaler));
|
||||
|
||||
if (((u8)ClockPrescaler & (u8)0x80) == 0x00) /* Bit7 = 0 means HSI divider */
|
||||
{
|
||||
CLK->CKDIVR &= (u8)(~CLK_CKDIVR_HSIDIV);
|
||||
CLK->CKDIVR |= (u8)((u8)ClockPrescaler & (u8)CLK_CKDIVR_HSIDIV);
|
||||
}
|
||||
else /* Bit7 = 1 means CPU divider */
|
||||
{
|
||||
CLK->CKDIVR &= (u8)(~CLK_CKDIVR_CPUDIV);
|
||||
CLK->CKDIVR |= (u8)((u8)ClockPrescaler & (u8)CLK_CKDIVR_CPUDIV);
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* @brief Configures the SWIM clock frequency on the fly.
|
||||
* @param[in] CLK_SWIMDivider Specifies the SWIM clock divider to apply.
|
||||
* can be one of the value of @ref CLK_SWIMDivider_TypeDef
|
||||
* @retval None
|
||||
*/
|
||||
void CLK_SWIMConfig(CLK_SWIMDivider_TypeDef CLK_SWIMDivider)
|
||||
{
|
||||
|
||||
/* check the parameters */
|
||||
assert_param(IS_CLK_SWIMDIVIDER_OK(CLK_SWIMDivider));
|
||||
|
||||
if (CLK_SWIMDivider != CLK_SWIMDIVIDER_2)
|
||||
{
|
||||
/* SWIM clock is not divided by 2 */
|
||||
CLK->SWIMCCR |= CLK_SWIMCCR_SWIMDIV;
|
||||
}
|
||||
else /* CLK_SWIMDivider == CLK_SWIMDIVIDER_2 */
|
||||
{
|
||||
/* SWIM clock is divided by 2 */
|
||||
CLK->SWIMCCR &= (u8)(~CLK_SWIMCCR_SWIMDIV);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the divider for the external CAN clock.
|
||||
* @param[in] CLK_CANDivider Specifies the CAN clock divider to apply.
|
||||
* can be one of the value of @ref CLK_CANDivider_TypeDef
|
||||
* @retval None
|
||||
*/
|
||||
void CLK_CANConfig(CLK_CANDivider_TypeDef CLK_CANDivider)
|
||||
{
|
||||
|
||||
/* check the parameters */
|
||||
assert_param(IS_CLK_CANDIVIDER_OK(CLK_CANDivider));
|
||||
|
||||
/* Clear the CANDIV bits */
|
||||
CLK->CANCCR &= (u8)(~CLK_CANCCR_CANDIV);
|
||||
|
||||
/* Select divider */
|
||||
CLK->CANCCR |= (u8)CLK_CANDivider;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables the Clock Security System.
|
||||
* @par Full description:
|
||||
* once CSS is enabled it cannot be disabled until the next reset.
|
||||
* @par Parameters:
|
||||
* None
|
||||
* @retval None
|
||||
*/
|
||||
void CLK_ClockSecuritySystemEnable(void)
|
||||
{
|
||||
/* Set CSSEN bit */
|
||||
CLK->CSSR |= CLK_CSSR_CSSEN;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the clock source used as system clock.
|
||||
* @par Parameters:
|
||||
* None
|
||||
* @retval Clock source used.
|
||||
* can be one of the values of @ref CLK_Source_TypeDef
|
||||
*/
|
||||
CLK_Source_TypeDef CLK_GetSYSCLKSource(void)
|
||||
{
|
||||
return((CLK_Source_TypeDef)CLK->CMSR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function returns the frequencies of different on chip clocks.
|
||||
@@ -628,164 +85,8 @@ u32 CLK_GetClockFreq(void)
|
||||
return((u32)clockfrequency);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Adjusts the Internal High Speed oscillator (HSI) calibration value.
|
||||
* @par Full description:
|
||||
* @param[in] CLK_HSICalibrationValue calibration trimming value.
|
||||
* can be one of the values of @ref CLK_HSITrimValue_TypeDef
|
||||
* @retval None
|
||||
*/
|
||||
void CLK_AdjustHSICalibrationValue(CLK_HSITrimValue_TypeDef CLK_HSICalibrationValue)
|
||||
{
|
||||
|
||||
/* check the parameters */
|
||||
assert_param(IS_CLK_HSITRIMVALUE_OK(CLK_HSICalibrationValue));
|
||||
|
||||
/* Store the new value */
|
||||
CLK->HSITRIMR = (u8)((CLK->HSITRIMR & (u8)(~CLK_HSITRIMR_HSITRIM))|((u8)CLK_HSICalibrationValue));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the SWBSY flag (SWICR Reister)
|
||||
* @par Full description:
|
||||
* This function reset SWBSY flag in order to reset clock switch operations (target
|
||||
* oscillator is broken, stabilization is longing too much, etc.). If at the same time \n
|
||||
* software attempts to set SWEN and clear SWBSY, SWBSY action takes precedence.
|
||||
* @par Parameters:
|
||||
* None
|
||||
* @retval None
|
||||
*/
|
||||
void CLK_SYSCLKEmergencyClear(void)
|
||||
{
|
||||
CLK->SWCR &= (u8)(~CLK_SWCR_SWBSY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks whether the specified CLK flag is set or not.
|
||||
* @par Full description:
|
||||
* @param[in] CLK_FLAG Flag to check.
|
||||
* can be one of the values of @ref CLK_Flag_TypeDef
|
||||
* @retval FlagStatus, status of the checked flag
|
||||
*/
|
||||
FlagStatus CLK_GetFlagStatus(CLK_Flag_TypeDef CLK_FLAG)
|
||||
{
|
||||
|
||||
u16 statusreg = 0;
|
||||
u8 tmpreg = 0;
|
||||
FlagStatus bitstatus = RESET;
|
||||
|
||||
/* check the parameters */
|
||||
assert_param(IS_CLK_FLAG_OK(CLK_FLAG));
|
||||
|
||||
/* Get the CLK register index */
|
||||
statusreg = (u16)((u16)CLK_FLAG & (u16)0xFF00);
|
||||
|
||||
|
||||
if (statusreg == 0x0100) /* The flag to check is in ICKRregister */
|
||||
{
|
||||
tmpreg = CLK->ICKR;
|
||||
}
|
||||
else if (statusreg == 0x0200) /* The flag to check is in ECKRregister */
|
||||
{
|
||||
tmpreg = CLK->ECKR;
|
||||
}
|
||||
else if (statusreg == 0x0300) /* The flag to check is in SWIC register */
|
||||
{
|
||||
tmpreg = CLK->SWCR;
|
||||
}
|
||||
else if (statusreg == 0x0400) /* The flag to check is in CSS register */
|
||||
{
|
||||
tmpreg = CLK->CSSR;
|
||||
}
|
||||
else /* The flag to check is in CCO register */
|
||||
{
|
||||
tmpreg = CLK->CCOR;
|
||||
}
|
||||
|
||||
if ((tmpreg & (u8)CLK_FLAG) != (u8)RESET)
|
||||
{
|
||||
bitstatus = SET;
|
||||
}
|
||||
else
|
||||
{
|
||||
bitstatus = RESET;
|
||||
}
|
||||
|
||||
/* Return the flag status */
|
||||
return((FlagStatus)bitstatus);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks whether the specified CLK interrupt has is enabled or not.
|
||||
* @param[in] CLK_IT specifies the CLK interrupt.
|
||||
* can be one of the values of @ref CLK_IT_TypeDef
|
||||
* @retval ITStatus, new state of CLK_IT (SET or RESET).
|
||||
*/
|
||||
ITStatus CLK_GetITStatus(CLK_IT_TypeDef CLK_IT)
|
||||
{
|
||||
|
||||
ITStatus bitstatus = RESET;
|
||||
|
||||
/* check the parameters */
|
||||
assert_param(IS_CLK_IT_OK(CLK_IT));
|
||||
|
||||
if (CLK_IT == CLK_IT_SWIF)
|
||||
{
|
||||
/* Check the status of the clock switch interrupt */
|
||||
if ((CLK->SWCR & (u8)CLK_IT) == (u8)0x0C)
|
||||
{
|
||||
bitstatus = SET;
|
||||
}
|
||||
else
|
||||
{
|
||||
bitstatus = RESET;
|
||||
}
|
||||
}
|
||||
else /* CLK_IT == CLK_IT_CSSDIE */
|
||||
{
|
||||
/* Check the status of the security system detection interrupt */
|
||||
if ((CLK->CSSR & (u8)CLK_IT) == (u8)0x0C)
|
||||
{
|
||||
bitstatus = SET;
|
||||
}
|
||||
else
|
||||
{
|
||||
bitstatus = RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the CLK_IT status */
|
||||
return bitstatus;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clears the CLK’s interrupt pending bits.
|
||||
* @param[in] CLK_IT specifies the interrupt pending bits.
|
||||
* can be one of the values of @ref CLK_IT_TypeDef
|
||||
* @retval None
|
||||
*/
|
||||
void CLK_ClearITPendingBit(CLK_IT_TypeDef CLK_IT)
|
||||
{
|
||||
|
||||
/* check the parameters */
|
||||
assert_param(IS_CLK_IT_OK(CLK_IT));
|
||||
|
||||
if (CLK_IT == (u8)CLK_IT_CSSD)
|
||||
{
|
||||
/* Clear the status of the security system detection interrupt */
|
||||
CLK->CSSR &= (u8)(~CLK_CSSR_CSSD);
|
||||
}
|
||||
else /* CLK_PendingBit == (u8)CLK_IT_SWIF */
|
||||
{
|
||||
/* Clear the status of the clock switch interrupt */
|
||||
CLK->SWCR &= (u8)(~CLK_SWCR_SWIF);
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -117,47 +117,6 @@ void GPIO_Init(GPIO_TypeDef* GPIOx,
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes data to the specified GPIO data port.
|
||||
* @param[in] GPIOx : Select the GPIO peripheral number (x = A to I).
|
||||
* @param[in] PortVal : Specifies the value to be written to the port output.
|
||||
* data register.
|
||||
* @retval None
|
||||
* @par Required preconditions:
|
||||
* The port must be configured in output mode.
|
||||
*/
|
||||
void GPIO_Write(GPIO_TypeDef* GPIOx, u8 PortVal)
|
||||
{
|
||||
GPIOx->ODR = PortVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes high level to the specified GPIO pins.
|
||||
* @param[in] GPIOx : Select the GPIO peripheral number (x = A to I).
|
||||
* @param[in] PortPins : Specifies the pins to be turned high to the port output.
|
||||
* data register.
|
||||
* @retval None
|
||||
* @par Required preconditions:
|
||||
* The port must be configured in output mode.
|
||||
*/
|
||||
void GPIO_WriteHigh(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins)
|
||||
{
|
||||
GPIOx->ODR |= (u8)PortPins;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes low level to the specified GPIO pins.
|
||||
* @param[in] GPIOx : Select the GPIO peripheral number (x = A to I).
|
||||
* @param[in] PortPins : Specifies the pins to be turned low to the port output.
|
||||
* data register.
|
||||
* @retval None
|
||||
* @par Required preconditions:
|
||||
* The port must be configured in output mode.
|
||||
*/
|
||||
void GPIO_WriteLow(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins)
|
||||
{
|
||||
GPIOx->ODR &= (u8)(~PortPins);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes reverse level to the specified GPIO pins.
|
||||
@@ -173,67 +132,6 @@ void GPIO_WriteReverse(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins)
|
||||
GPIOx->ODR ^= (u8)PortPins;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads the specified GPIO output data port.
|
||||
* @param[in] GPIOx : Select the GPIO peripheral number (x = A to I).
|
||||
* @retval u8 : GPIO output data port value.
|
||||
* @par Required preconditions:
|
||||
* The port must be configured in input mode.
|
||||
*/
|
||||
u8 GPIO_ReadOutputData(GPIO_TypeDef* GPIOx)
|
||||
{
|
||||
return ((u8)GPIOx->ODR);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads the specified GPIO input data port.
|
||||
* @param[in] GPIOx : Select the GPIO peripheral number (x = A to I).
|
||||
* @retval u8 : GPIO input data port value.
|
||||
* @par Required preconditions:
|
||||
* The port must be configured in input mode.
|
||||
*/
|
||||
u8 GPIO_ReadInputData(GPIO_TypeDef* GPIOx)
|
||||
{
|
||||
return ((u8)GPIOx->IDR);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads the specified GPIO input data pin.
|
||||
* @param[in] GPIOx : Select the GPIO peripheral number (x = A to I).
|
||||
* @param[in] GPIO_Pin : This parameter contains the pin number, it can be one member
|
||||
* of the @ref GPIO_Pin_TypeDef enumeration.
|
||||
* @retval BitStatus : GPIO input pin status.
|
||||
* This parameter can be any of the @ref BitStatus enumeration.
|
||||
* @par Required preconditions:
|
||||
* The port must be configured in input mode.
|
||||
*/
|
||||
BitStatus GPIO_ReadInputPin(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin)
|
||||
{
|
||||
return ((BitStatus)(GPIOx->IDR & (vu8)GPIO_Pin));
|
||||
}
|
||||
/**
|
||||
* @brief Configures the external pull-up on GPIOx pins.
|
||||
* @param[in] GPIOx : Select the GPIO peripheral number (x = A to I).
|
||||
* @param[in] GPIO_Pin : This parameter contains the pin number, it can be one or many members
|
||||
* of the @ref GPIO_Pin_TypeDef enumeration.
|
||||
* @param[in] NewState : The new state of the pull up pin.
|
||||
* This parameter can be any of the @ref FunctionalState enumeration.
|
||||
* @retval None
|
||||
*/
|
||||
void GPIO_ExternalPullUpConfig(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin, FunctionalState NewState)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_GPIO_PIN_OK(GPIO_Pin));
|
||||
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
|
||||
|
||||
if (NewState != DISABLE) /* External Pull-Up Set*/
|
||||
{
|
||||
GPIOx->CR1 |= (u8)GPIO_Pin;
|
||||
} else /* External Pull-Up Reset*/
|
||||
{
|
||||
GPIOx->CR1 &= (u8)(~(GPIO_Pin));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
||||
@@ -47,18 +47,18 @@
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GPIO_MODE_IN_FL_NO_IT = (u8)0b00000000, /*!< Input floating, no external interrupt */
|
||||
GPIO_MODE_IN_PU_NO_IT = (u8)0b01000000, /*!< Input pull-up, no external interrupt */
|
||||
GPIO_MODE_IN_FL_IT = (u8)0b00100000, /*!< Input floating, external interrupt */
|
||||
GPIO_MODE_IN_PU_IT = (u8)0b01100000, /*!< Input pull-up, external interrupt */
|
||||
GPIO_MODE_OUT_OD_LOW_FAST = (u8)0b10100000, /*!< Output open-drain, low level, 10MHz */
|
||||
GPIO_MODE_OUT_PP_LOW_FAST = (u8)0b11100000, /*!< Output push-pull, low level, 10MHz */
|
||||
GPIO_MODE_OUT_OD_LOW_SLOW = (u8)0b10000000, /*!< Output open-drain, low level, 2MHz */
|
||||
GPIO_MODE_OUT_PP_LOW_SLOW = (u8)0b11000000, /*!< Output push-pull, low level, 2MHz */
|
||||
GPIO_MODE_OUT_OD_HIZ_FAST = (u8)0b10110000, /*!< Output open-drain, high-impedance level,10MHz */
|
||||
GPIO_MODE_OUT_PP_HIGH_FAST = (u8)0b11110000, /*!< Output push-pull, high level, 10MHz */
|
||||
GPIO_MODE_OUT_OD_HIZ_SLOW = (u8)0b10010000, /*!< Output open-drain, high-impedance level, 2MHz */
|
||||
GPIO_MODE_OUT_PP_HIGH_SLOW = (u8)0b11010000 /*!< Output push-pull, high level, 2MHz */
|
||||
GPIO_MODE_IN_FL_NO_IT = (u8)0x00, // 0b00000000, /*!< Input floating, no external interrupt */
|
||||
GPIO_MODE_IN_PU_NO_IT = (u8)0x40, // 0b01000000, /*!< Input pull-up, no external interrupt */
|
||||
GPIO_MODE_IN_FL_IT = (u8)0x20, // 0b00100000, /*!< Input floating, external interrupt */
|
||||
GPIO_MODE_IN_PU_IT = (u8)0x60, // 0b01100000, /*!< Input pull-up, external interrupt */
|
||||
GPIO_MODE_OUT_OD_LOW_FAST = (u8)0xA0, // 0b10100000, /*!< Output open-drain, low level, 10MHz */
|
||||
GPIO_MODE_OUT_PP_LOW_FAST = (u8)0xE0, // 0b11100000, /*!< Output push-pull, low level, 10MHz */
|
||||
GPIO_MODE_OUT_OD_LOW_SLOW = (u8)0x80, // 0b10000000, /*!< Output open-drain, low level, 2MHz */
|
||||
GPIO_MODE_OUT_PP_LOW_SLOW = (u8)0xC0, // 0b11000000, /*!< Output push-pull, low level, 2MHz */
|
||||
GPIO_MODE_OUT_OD_HIZ_FAST = (u8)0xB0, // 0b10110000, /*!< Output open-drain, high-impedance level,10MHz */
|
||||
GPIO_MODE_OUT_PP_HIGH_FAST = (u8)0xF0, // 0b11110000, /*!< Output push-pull, high level, 10MHz */
|
||||
GPIO_MODE_OUT_OD_HIZ_SLOW = (u8)0x90, // 0b10010000, /*!< Output open-drain, high-impedance level, 2MHz */
|
||||
GPIO_MODE_OUT_PP_HIGH_SLOW = (u8)0xD0 // 0b11010000 /*!< Output push-pull, high level, 2MHz */
|
||||
}GPIO_Mode_TypeDef;
|
||||
|
||||
/**
|
||||
|
||||
@@ -45,9 +45,16 @@ u8 ITC_GetCPUCC(void)
|
||||
_asm("push cc");
|
||||
_asm("pop a");
|
||||
return; /* Ignore compiler warning, the returned value is in A register */
|
||||
#else /* _RAISONANCE_ */
|
||||
#endif
|
||||
|
||||
#ifdef _RAISONANCE_
|
||||
return _getCC_();
|
||||
#endif /* _COSMIC_*/
|
||||
#endif
|
||||
|
||||
#ifdef _IAR_SYSTEMS_
|
||||
__asm("push cc");
|
||||
__asm("pop a");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,6 +31,14 @@
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
/* Public functions ----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* IAR EWSTM8: Ignore unused variable warning on dummy variable.
|
||||
*/
|
||||
#ifdef __IAR_SYSTEMS_ICC__
|
||||
#pragma diag_suppress=Pe550
|
||||
#endif
|
||||
|
||||
|
||||
/** @}
|
||||
* @addtogroup UART2_Public_Functions
|
||||
* @{
|
||||
@@ -149,335 +157,6 @@ void UART2_Init(u32 BaudRate, UART2_WordLength_TypeDef WordLength, UART2_StopBit
|
||||
UART2->CR3 |= (u8)((u8)SyncMode & UART2_CR3_CKEN);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief Enable the UART2 peripheral.
|
||||
* @par Full description:
|
||||
* Enable the UART2 peripheral.
|
||||
* @param[in] NewState new state of the UART2 Communication.
|
||||
* This parameter can be:
|
||||
* - ENABLE
|
||||
* - DISABLE
|
||||
* @retval None
|
||||
*/
|
||||
void UART2_Cmd(FunctionalState NewState)
|
||||
{
|
||||
|
||||
if (NewState != DISABLE)
|
||||
{
|
||||
UART2->CR1 &= (u8)(~UART2_CR1_UARTD); /**< UART2 Enable */
|
||||
}
|
||||
else
|
||||
{
|
||||
UART2->CR1 |= UART2_CR1_UARTD; /**< UART2 Disable (for low power consumption) */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables or disables the specified UART2 interrupts.
|
||||
* @par Full description:
|
||||
* Enables or disables the specified UART2 interrupts.
|
||||
* @param[in] UART2_IT specifies the UART2 interrupt sources to be enabled or disabled.
|
||||
* This parameter can be one of the following values:
|
||||
* - UART2_IT_LBDF: LIN Break detection interrupt
|
||||
* - UART2_IT_LHDF: LIN Break detection interrupt
|
||||
* - UART2_IT_TXE: Tansmit Data Register empty interrupt
|
||||
* - UART2_IT_TC: Transmission complete interrupt
|
||||
* - UART2_IT_RXNE_OR: Receive Data register not empty/Over run error interrupt
|
||||
* - UART2_IT_IDLE: Idle line detection interrupt
|
||||
* - UART2_IT_PE: Parity Error interrupt
|
||||
* @param[in] NewState new state of the specified UART2 interrupts.
|
||||
* This parameter can be: ENABLE or DISABLE.
|
||||
* @retval None
|
||||
*/
|
||||
void UART2_ITConfig(UART2_IT_TypeDef UART2_IT, FunctionalState NewState)
|
||||
{
|
||||
u8 uartreg, itpos = 0x00;
|
||||
assert_param(IS_UART2_CONFIG_IT_OK(UART2_IT));
|
||||
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
|
||||
|
||||
/* Get the UART2 register index */
|
||||
uartreg = (u8)(UART2_IT >> 0x08);
|
||||
|
||||
/* Get the UART2 IT index */
|
||||
itpos = (u8)((u8)1 << (u8)((u8)UART2_IT & (u8)0x0F));
|
||||
|
||||
if (NewState != DISABLE)
|
||||
{
|
||||
/**< Enable the Interrupt bits according to UART2_IT mask */
|
||||
if (uartreg == 0x01)
|
||||
{
|
||||
UART2->CR1 |= itpos;
|
||||
}
|
||||
else if (uartreg == 0x02)
|
||||
{
|
||||
UART2->CR2 |= itpos;
|
||||
}
|
||||
else if (uartreg == 0x03)
|
||||
{
|
||||
UART2->CR4 |= itpos;
|
||||
}
|
||||
else
|
||||
{
|
||||
UART2->CR6 |= itpos;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/**< Disable the interrupt bits according to UART2_IT mask */
|
||||
if (uartreg == 0x01)
|
||||
{
|
||||
UART2->CR1 &= (u8)(~itpos);
|
||||
}
|
||||
else if (uartreg == 0x02)
|
||||
{
|
||||
UART2->CR2 &= (u8)(~itpos);
|
||||
}
|
||||
else if (uartreg == 0x03)
|
||||
{
|
||||
UART2->CR4 &= (u8)(~itpos);
|
||||
}
|
||||
else
|
||||
{
|
||||
UART2->CR6 &= (u8)(~itpos);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief Configures the UART2’s IrDA interface.
|
||||
* @par Full description:
|
||||
* Configures the UART2’s IrDA interface.
|
||||
* @par This function is valid only for UART2.
|
||||
* @param[in] UART2_IrDAMode specifies the IrDA mode.
|
||||
* This parameter can be any of the @ref UART2_IrDAMode_TypeDef values.
|
||||
* @retval None
|
||||
*/
|
||||
void UART2_IrDAConfig(UART2_IrDAMode_TypeDef UART2_IrDAMode)
|
||||
{
|
||||
assert_param(IS_UART2_IRDAMODE_OK(UART2_IrDAMode));
|
||||
|
||||
if (UART2_IrDAMode != UART2_IRDAMODE_NORMAL)
|
||||
{
|
||||
UART2->CR5 |= UART2_CR5_IRLP;
|
||||
}
|
||||
else
|
||||
{
|
||||
UART2->CR5 &= ((u8)~UART2_CR5_IRLP);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables or disables the UART2’s IrDA interface.
|
||||
* @par Full description:
|
||||
* Enables or disables the UART2’s IrDA interface.
|
||||
* @par This function is related to IrDA mode.
|
||||
* @param[in] NewState new state of the IrDA mode.
|
||||
* This parameter can be: ENABLE or DISABLE.
|
||||
* @retval None
|
||||
*/
|
||||
void UART2_IrDACmd(FunctionalState NewState)
|
||||
{
|
||||
|
||||
/* Check parameters */
|
||||
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
|
||||
|
||||
if (NewState != DISABLE)
|
||||
{
|
||||
/* Enable the IrDA mode by setting the IREN bit in the CR3 register */
|
||||
UART2->CR5 |= UART2_CR5_IREN;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable the IrDA mode by clearing the IREN bit in the CR3 register */
|
||||
UART2->CR5 &= ((u8)~UART2_CR5_IREN);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the UART2 LIN Break detection length.
|
||||
* @par Full description:
|
||||
* Sets the UART2 LIN Break detection length.
|
||||
* @param[in] UART2_LINBreakDetectionLength specifies the LIN break detection length.
|
||||
* This parameter can be any of the @ref UART2_LINBreakDetectionLength_TypeDef values.
|
||||
* @retval None
|
||||
*/
|
||||
void UART2_LINBreakDetectionConfig(UART2_LINBreakDetectionLength_TypeDef UART2_LINBreakDetectionLength)
|
||||
{
|
||||
assert_param(IS_UART2_LINBREAKDETECTIONLENGTH_OK(UART2_LINBreakDetectionLength));
|
||||
|
||||
if (UART2_LINBreakDetectionLength != UART2_LINBREAKDETECTIONLENGTH_10BITS)
|
||||
{
|
||||
UART2->CR4 |= UART2_CR4_LBDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
UART2->CR4 &= ((u8)~UART2_CR4_LBDL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configue the UART2 peripheral.
|
||||
* @par Full description:
|
||||
* Configue the UART2 peripheral.
|
||||
* @param[in] UART2_Mode specifies the LIN mode.
|
||||
* This parameter can be any of the @ref UART2_LinMode_TypeDef values.
|
||||
* @param[in] UART2_Autosync specifies the LIN automatic resynchronization mode.
|
||||
* This parameter can be any of the @ref UART2_LinAutosync_TypeDef values.
|
||||
* @param[in] UART2_DivUp specifies the LIN divider update method.
|
||||
* This parameter can be any of the @ref UART2_LinDivUp_TypeDef values.
|
||||
* @retval None
|
||||
*/
|
||||
void UART2_LINConfig(UART2_LinMode_TypeDef UART2_Mode, UART2_LinAutosync_TypeDef UART2_Autosync, UART2_LinDivUp_TypeDef UART2_DivUp)
|
||||
{
|
||||
assert_param(IS_UART2_SLAVE_OK(UART2_Mode));
|
||||
|
||||
assert_param(IS_UART2_AUTOSYNC_OK(UART2_Autosync));
|
||||
|
||||
assert_param(IS_UART2_DIVUP_OK(UART2_DivUp));
|
||||
|
||||
if (UART2_Mode != UART2_LIN_MODE_MASTER)
|
||||
{
|
||||
UART2->CR6 |= UART2_CR6_LSLV;
|
||||
}
|
||||
else
|
||||
{
|
||||
UART2->CR6 &= ((u8)~UART2_CR6_LSLV);
|
||||
}
|
||||
|
||||
if (UART2_Autosync != UART2_LIN_AUTOSYNC_DISABLE)
|
||||
{
|
||||
UART2->CR6 |= UART2_CR6_LASE ;
|
||||
}
|
||||
else
|
||||
{
|
||||
UART2->CR6 &= ((u8)~ UART2_CR6_LASE );
|
||||
}
|
||||
|
||||
if (UART2_DivUp != UART2_LIN_DIVUP_LBRR1)
|
||||
{
|
||||
UART2->CR6 |= UART2_CR6_LDUM;
|
||||
}
|
||||
else
|
||||
{
|
||||
UART2->CR6 &= ((u8)~ UART2_CR6_LDUM);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables or disables the UART2 LIN mode.
|
||||
* @par Full description:
|
||||
* Enables or disables the UART2’s LIN mode.
|
||||
* @param[in] NewState is new state of the UART2 LIN mode.
|
||||
* This parameter can be:
|
||||
* - ENABLE
|
||||
* - DISABLE
|
||||
* @retval None
|
||||
*/
|
||||
void UART2_LINCmd(FunctionalState NewState)
|
||||
{
|
||||
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
|
||||
|
||||
if (NewState != DISABLE)
|
||||
{
|
||||
/* Enable the LIN mode by setting the LINE bit in the CR2 register */
|
||||
UART2->CR3 |= UART2_CR3_LINEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable the LIN mode by clearing the LINE bit in the CR2 register */
|
||||
UART2->CR3 &= ((u8)~UART2_CR3_LINEN);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief Enables or disables the UART2 Smart Card mode.
|
||||
* @par Full description:
|
||||
* Enables or disables the UART2 Smart Card mode.
|
||||
* @par This function is related to SmartCard mode.
|
||||
* @param[in] NewState: new state of the Smart Card mode.
|
||||
* This parameter can be: ENABLE or DISABLE.
|
||||
* @retval None
|
||||
*/
|
||||
void UART2_SmartCardCmd(FunctionalState NewState)
|
||||
{
|
||||
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
|
||||
|
||||
if (NewState != DISABLE)
|
||||
{
|
||||
/* Enable the SC mode by setting the SCEN bit in the CR5 register */
|
||||
UART2->CR5 |= UART2_CR5_SCEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable the SC mode by clearing the SCEN bit in the CR5 register */
|
||||
UART2->CR5 &= ((u8)(~UART2_CR5_SCEN));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables or disables NACK transmission.
|
||||
* @par Full description:
|
||||
* Enables or disables NACK transmission.
|
||||
* @par This function is valid only for UART2 because is related to SmartCard mode.
|
||||
* @param[in] NewState: new state of the Smart Card mode.
|
||||
* This parameter can be: ENABLE or DISABLE.
|
||||
* @retval None
|
||||
*/
|
||||
void UART2_SmartCardNACKCmd(FunctionalState NewState)
|
||||
{
|
||||
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
|
||||
|
||||
if (NewState != DISABLE)
|
||||
{
|
||||
/* Enable the NACK transmission by setting the NACK bit in the CR5 register */
|
||||
UART2->CR5 |= UART2_CR5_NACK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable the NACK transmission by clearing the NACK bit in the CR5 register */
|
||||
UART2->CR5 &= ((u8)~(UART2_CR5_NACK));
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief Selects the UART2 WakeUp method.
|
||||
* @par Full description:
|
||||
* Selects the UART2 WakeUp method.
|
||||
* @param[in] UART2_WakeUp: specifies the UART2 wakeup method.
|
||||
* This parameter can be any of the @ref UART2_WakeUp_TypeDef values.
|
||||
* @retval None
|
||||
*/
|
||||
void UART2_WakeUpConfig(UART2_WakeUp_TypeDef UART2_WakeUp)
|
||||
{
|
||||
assert_param(IS_UART2_WAKEUP_OK(UART2_WakeUp));
|
||||
|
||||
UART2->CR1 &= ((u8)~UART2_CR1_WAKE);
|
||||
UART2->CR1 |= (u8)UART2_WakeUp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Determines if the UART2 is in mute mode or not.
|
||||
* @par Full description:
|
||||
* Determines if the UART2 is in mute mode or not.
|
||||
* @param[in] NewState: new state of the UART2 mode.
|
||||
* This parameter can be:
|
||||
* - ENABLE
|
||||
* - DISABLE
|
||||
* @retval None
|
||||
*/
|
||||
void UART2_ReceiverWakeUpCmd(FunctionalState NewState)
|
||||
{
|
||||
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
|
||||
|
||||
if (NewState != DISABLE)
|
||||
{
|
||||
/* Enable the mute mode UART2 by setting the RWU bit in the CR2 register */
|
||||
UART2->CR2 |= UART2_CR2_RWU;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable the mute mode UART2 by clearing the RWU bit in the CR1 register */
|
||||
UART2->CR2 &= ((u8)~UART2_CR2_RWU);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@@ -493,20 +172,6 @@ u8 UART2_ReceiveData8(void)
|
||||
return ((u8)UART2->DR);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the most recent received data by the UART2 peripheral.
|
||||
* @par Full description:
|
||||
* Returns the most recent received data by the UART2 peripheral.
|
||||
* @retval u16 Received Data
|
||||
* @par Required preconditions:
|
||||
* UART2_Cmd(ENABLE);
|
||||
*/
|
||||
u16 UART2_ReceiveData9(void)
|
||||
{
|
||||
return (u16)((((u16)UART2->DR) | ((u16)(((u16)((u16)UART2->CR1 & (u16)UART2_CR1_R8)) << 1))) & ((u16)0x01FF));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Transmits 8 bit data through the UART2 peripheral.
|
||||
@@ -523,95 +188,6 @@ void UART2_SendData8(u8 Data)
|
||||
UART2->DR = Data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Transmits 9 bit data through the UART2 peripheral.
|
||||
* @par Full description:
|
||||
* Transmits 9 bit data through the UART2 peripheral.
|
||||
* @param[in] Data: the data to transmit.
|
||||
* @retval None
|
||||
* @par Required preconditions:
|
||||
* UART2_Cmd(ENABLE);
|
||||
*/
|
||||
void UART2_SendData9(u16 Data)
|
||||
{
|
||||
UART2->CR1 &= ((u8)~UART2_CR1_T8); /* Clear the transmit data bit 8 */
|
||||
UART2->CR1 |= (u8)(((u8)(Data >> 2)) & UART2_CR1_T8); /* Write the transmit data bit [8] */
|
||||
UART2->DR = (u8)(Data); /* Write the transmit data bit [0:7] */
|
||||
|
||||
}
|
||||
/**
|
||||
* @brief Transmits break characters.
|
||||
* @par Full description:
|
||||
* Transmits break characters on the UART2 peripheral.
|
||||
* @retval None
|
||||
*/
|
||||
void UART2_SendBreak(void)
|
||||
{
|
||||
UART2->CR2 |= UART2_CR2_SBK;
|
||||
}
|
||||
/**
|
||||
* @brief Sets the address of the UART2 node.
|
||||
* @par Full description:
|
||||
* Sets the address of the UART2 node.
|
||||
* @param[in] UART2_Address: Indicates the address of the UART2 node.
|
||||
* @retval None
|
||||
*/
|
||||
|
||||
void UART2_SetAddress(u8 UART2_Address)
|
||||
{
|
||||
/*assert_param for x UART2_Address*/
|
||||
assert_param(IS_UART2_ADDRESS_OK(UART2_Address));
|
||||
|
||||
/* Clear the UART2 address */
|
||||
UART2->CR4 &= ((u8)~UART2_CR4_ADD);
|
||||
/* Set the UART2 address node */
|
||||
UART2->CR4 |= UART2_Address;
|
||||
}
|
||||
/**
|
||||
* @brief Sets the specified UART2 guard time.
|
||||
* @par Full description:
|
||||
* Sets the address of the UART2 node.
|
||||
* @par This function is related to SmartCard mode.
|
||||
* @param[in] UART2_GuardTime: specifies the guard time.
|
||||
* @retval None
|
||||
* @par Required preconditions:
|
||||
* SmartCard Mode Enabled
|
||||
*/
|
||||
void UART2_SetGuardTime(u8 UART2_GuardTime)
|
||||
{
|
||||
/* Set the UART2 guard time */
|
||||
UART2->GTR = UART2_GuardTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the system clock prescaler.
|
||||
* @par Full description:
|
||||
* Sets the system clock prescaler.
|
||||
* @par This function is related to SmartCard and IrDa mode.
|
||||
* @param[in] UART2_Prescaler: specifies the prescaler clock.
|
||||
* This parameter can be one of the following values:
|
||||
* @par IrDA Low Power Mode
|
||||
* The clock source is diveded by the value given in the register (8 bits)
|
||||
* - 0000 0000 Reserved
|
||||
* - 0000 0001 divides the clock source by 1
|
||||
* - 0000 0010 divides the clock source by 2
|
||||
* - ...........................................................
|
||||
* @par Smart Card Mode
|
||||
* The clock source is diveded by the value given in the register (5 significant bits) multipied by 2
|
||||
* - 0 0000 Reserved
|
||||
* - 0 0001 divides the clock source by 2
|
||||
* - 0 0010 divides the clock source by 4
|
||||
* - 0 0011 divides the clock source by 6
|
||||
* - ...........................................................
|
||||
* @retval None
|
||||
* @par Required preconditions:
|
||||
* IrDA Low Power mode or smartcard mode enabled
|
||||
*/
|
||||
void UART2_SetPrescaler(u8 UART2_Prescaler)
|
||||
{
|
||||
/* Load the UART2 prescaler value*/
|
||||
UART2->PSCR = UART2_Prescaler;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks whether the specified UART2 flag is set or not.
|
||||
@@ -686,210 +262,8 @@ FlagStatus UART2_GetFlagStatus(UART2_Flag_TypeDef UART2_FLAG)
|
||||
/* Return the UART2_FLAG status*/
|
||||
return status;
|
||||
}
|
||||
/**
|
||||
* @brief Clears the UART2 flags.
|
||||
* @par Full description:
|
||||
* Clears the UART2 flags.
|
||||
* @param[in] UART2_FLAG specifies the flag to clear
|
||||
* This parameter can be any combination of the following values:
|
||||
* - UART2_FLAG_LBDF: LIN Break detection flag.
|
||||
* - UART2_FLAG_LHDF: LIN Header detection flag.
|
||||
* - UART2_FLAG_LSF: LIN synchrone field flag.
|
||||
* - UART2_FLAG_RXNE: Receive data register not empty flag.
|
||||
* @par Notes:
|
||||
* - PE (Parity error), FE (Framing error), NE (Noise error), OR (OverRun error)
|
||||
* and IDLE (Idle line detected) flags are cleared by software sequence: a read
|
||||
* operation to UART2_SR register (UART2_GetFlagStatus())followed by a read operation
|
||||
* to UART2_DR register(UART2_ReceiveData8() or UART2_ReceiveData9()).
|
||||
* - RXNE flag can be also cleared by a read to the UART2_DR register
|
||||
* (UART2_ReceiveData8()or UART2_ReceiveData9()).
|
||||
* - TC flag can be also cleared by software sequence: a read operation to UART2_SR
|
||||
* register (UART2_GetFlagStatus()) followed by a write operation to UART2_DR register
|
||||
* (UART2_SendData8() or UART2_SendData9()).
|
||||
* - TXE flag is cleared only by a write to the UART2_DR register (UART2_SendData8() or
|
||||
* UART2_SendData9()).
|
||||
* - SBK flag is cleared during the stop bit of break.
|
||||
* @retval None
|
||||
*/
|
||||
|
||||
void UART2_ClearFlag(UART2_Flag_TypeDef UART2_FLAG)
|
||||
{
|
||||
assert_param(IS_UART2_CLEAR_FLAG_OK(UART2_FLAG));
|
||||
|
||||
/*< Clear the Receive Register Not Empty flag */
|
||||
if (UART2_FLAG == UART2_FLAG_RXNE)
|
||||
{
|
||||
UART2->SR = (u8)~(UART2_SR_RXNE);
|
||||
}
|
||||
/*< Clear the LIN Break Detection flag */
|
||||
else if (UART2_FLAG == UART2_FLAG_LBDF)
|
||||
{
|
||||
UART2->CR4 &= (u8)(~UART2_CR4_LBDF);
|
||||
}
|
||||
/*< Clear the LIN Header Detection Flag */
|
||||
else if (UART2_FLAG == UART2_FLAG_LHDF)
|
||||
{
|
||||
UART2->CR6 &= (u8)(~UART2_CR6_LHDF);
|
||||
}
|
||||
/*< Clear the LIN Synch Field flag */
|
||||
else
|
||||
{
|
||||
UART2->CR6 &= (u8)(~UART2_CR6_LSF);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks whether the specified UART2 interrupt has occurred or not.
|
||||
* @par Full description:
|
||||
* Checks whether the specified UART2 interrupt has occurred or not.
|
||||
* @param[in] UART2_IT: Specifies the UART2 interrupt pending bit to check.
|
||||
* This parameter can be one of the following values:
|
||||
* - UART2_IT_LBDF: LIN Break detection interrupt
|
||||
* - UART2_IT_TXE: Tansmit Data Register empty interrupt
|
||||
* - UART2_IT_TC: Transmission complete interrupt
|
||||
* - UART2_IT_RXNE: Receive Data register not empty interrupt
|
||||
* - UART2_IT_IDLE: Idle line detection interrupt
|
||||
* - UART2_IT_OR: OverRun Error interrupt
|
||||
* - UART2_IT_PE: Parity Error interrupt
|
||||
* @retval
|
||||
* ITStatus The new state of UART2_IT (SET or RESET).
|
||||
*/
|
||||
ITStatus UART2_GetITStatus(UART2_IT_TypeDef UART2_IT)
|
||||
{
|
||||
ITStatus pendingbitstatus = RESET;
|
||||
u8 itpos = 0;
|
||||
u8 itmask1 = 0;
|
||||
u8 itmask2 = 0;
|
||||
u8 enablestatus = 0;
|
||||
|
||||
/* Check parameters */
|
||||
assert_param(IS_UART2_GET_IT_OK(UART2_IT));
|
||||
|
||||
/* Get the UART2 IT index*/
|
||||
itpos = (u8)((u8)1 << (u8)((u8)UART2_IT & (u8)0x0F));
|
||||
/* Get the UART2 IT index*/
|
||||
itmask1 = (u8)((u8)UART2_IT >> (u8)4);
|
||||
/* Set the IT mask*/
|
||||
itmask2 = (u8)((u8)1 << itmask1);
|
||||
|
||||
|
||||
|
||||
/* Check the status of the specified UART2 pending bit*/
|
||||
if (UART2_IT == UART2_IT_PE)
|
||||
{
|
||||
/* Get the UART2_ITPENDINGBIT enable bit status*/
|
||||
enablestatus = (u8)((u8)UART2->CR1 & itmask2);
|
||||
/* Check the status of the specified UART2 interrupt*/
|
||||
|
||||
if (((UART2->SR & itpos) != (u8)0x00) && enablestatus)
|
||||
{
|
||||
/* Interrupt occurred*/
|
||||
pendingbitstatus = SET;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Interrupt not occurred*/
|
||||
pendingbitstatus = RESET;
|
||||
}
|
||||
}
|
||||
|
||||
else if (UART2_IT == UART2_IT_LBDF)
|
||||
{
|
||||
/* Get the UART2_IT enable bit status*/
|
||||
enablestatus = (u8)((u8)UART2->CR4 & itmask2);
|
||||
/* Check the status of the specified UART2 interrupt*/
|
||||
if (((UART2->CR4 & itpos) != (u8)0x00) && enablestatus)
|
||||
{
|
||||
/* Interrupt occurred*/
|
||||
pendingbitstatus = SET;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Interrupt not occurred*/
|
||||
pendingbitstatus = RESET;
|
||||
}
|
||||
}
|
||||
else if (UART2_IT == UART2_IT_LHDF)
|
||||
{
|
||||
/* Get the UART2_IT enable bit status*/
|
||||
enablestatus = (u8)((u8)UART2->CR6 & itmask2);
|
||||
/* Check the status of the specified UART2 interrupt*/
|
||||
if (((UART2->CR6 & itpos) != (u8)0x00) && enablestatus)
|
||||
{
|
||||
/* Interrupt occurred*/
|
||||
pendingbitstatus = SET;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Interrupt not occurred*/
|
||||
pendingbitstatus = RESET;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get the UART2_IT enable bit status*/
|
||||
enablestatus = (u8)((u8)UART2->CR2 & itmask2);
|
||||
/* Check the status of the specified UART2 interrupt*/
|
||||
if (((UART2->SR & itpos) != (u8)0x00) && enablestatus)
|
||||
{
|
||||
/* Interrupt occurred*/
|
||||
pendingbitstatus = SET;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Interrupt not occurred*/
|
||||
pendingbitstatus = RESET;
|
||||
}
|
||||
}
|
||||
/* Return the UART2_IT status*/
|
||||
return pendingbitstatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clears the UART2 pending flags.
|
||||
* @par Full description:
|
||||
* Clears the UART2 pending bit.
|
||||
* @param[in] UART2_IT specifies the pending bit to clear
|
||||
* This parameter can be one of the following values:
|
||||
* - UART2_IT_LBDF: LIN Break detection interrupt
|
||||
* - UART2_IT_LHDF: LIN Header detection interrupt
|
||||
* - UART2_IT_RXNE: Receive Data register not empty interrupt.
|
||||
*
|
||||
* @par Notes:
|
||||
* - PE (Parity error), FE (Framing error), NE (Noise error), OR (OverRun error) and
|
||||
* IDLE (Idle line detected) pending bits are cleared by software sequence: a read
|
||||
* operation to UART2_SR register (UART2_GetITStatus()) followed by a read operation
|
||||
* to UART2_DR register (UART2_ReceiveData8() or UART2_ReceiveData9() ).
|
||||
* - RXNE pending bit can be also cleared by a read to the UART2_DR register
|
||||
* (UART2_ReceiveData8() or UART2_ReceiveData9() ).
|
||||
* - TC (Transmit complet) pending bit can be cleared by software sequence: a read
|
||||
* operation to UART2_SR register (UART2_GetITStatus()) followed by a write operation
|
||||
* to UART2_DR register (UART2_SendData8()or UART2_SendData9()).
|
||||
* - TXE pending bit is cleared only by a write to the UART2_DR register
|
||||
* (UART2_SendData8() or UART2_SendData9()).
|
||||
* @retval None
|
||||
*/
|
||||
void UART2_ClearITPendingBit(UART2_IT_TypeDef UART2_IT)
|
||||
{
|
||||
assert_param(IS_UART2_CLEAR_IT_OK(UART2_IT));
|
||||
|
||||
/*< Clear the Receive Register Not Empty pending bit */
|
||||
if (UART2_IT == UART2_IT_RXNE)
|
||||
{
|
||||
UART2->SR = (u8)~(UART2_SR_RXNE);
|
||||
}
|
||||
/*< Clear the LIN Break Detection pending bit */
|
||||
else if (UART2_IT == UART2_IT_LBDF)
|
||||
{
|
||||
UART2->CR4 &= (u8)~(UART2_CR4_LBDF);
|
||||
}
|
||||
/*< Clear the LIN Header Detection pending bit */
|
||||
else
|
||||
{
|
||||
UART2->CR6 &= (u8)(~UART2_CR6_LHDF);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
#include "atom.h"
|
||||
#include "atomport-private.h"
|
||||
#include "atomport-tests.h"
|
||||
#include "atomtests.h"
|
||||
#include "atomtimer.h"
|
||||
#include "uart.h"
|
||||
@@ -104,14 +105,14 @@ extern int _stack;
|
||||
static ATOM_TCB main_tcb;
|
||||
|
||||
/* Main thread's stack area (large so place outside of the small page0 area on STM8) */
|
||||
@near static uint8_t main_thread_stack[MAIN_STACK_SIZE_BYTES];
|
||||
NEAR static uint8_t main_thread_stack[MAIN_STACK_SIZE_BYTES];
|
||||
|
||||
/* Idle thread's stack area (large so place outside of the small page0 area on STM8) */
|
||||
@near static uint8_t idle_thread_stack[IDLE_STACK_SIZE_BYTES];
|
||||
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);
|
||||
|
||||
|
||||
/**
|
||||
@@ -121,8 +122,15 @@ static void main_thread_func (uint32_t data);
|
||||
*
|
||||
* Sets up the STM8 hardware resources (system tick timer interrupt) necessary
|
||||
* for the OS to be started. Creates an application thread and starts the OS.
|
||||
*
|
||||
* If the compiler supports it, stack space can be saved by preventing
|
||||
* the function from saving registers on entry. This is because we
|
||||
* are called directly by the C startup assembler, and know that we will
|
||||
* never return from here. The NO_REG_SAVE macro is used to denote such
|
||||
* functions in a compiler-agnostic way, though not all compilers support it.
|
||||
*
|
||||
*/
|
||||
void main ( void )
|
||||
NO_REG_SAVE void main ( void )
|
||||
{
|
||||
int8_t status;
|
||||
|
||||
@@ -162,11 +170,11 @@ void main ( void )
|
||||
}
|
||||
}
|
||||
|
||||
while (1)
|
||||
;
|
||||
|
||||
/* There was an error starting the OS if we reach here */
|
||||
return;
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -177,15 +185,18 @@ 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)
|
||||
{
|
||||
|
||||
@@ -1,78 +1,157 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "stm8s.h"
|
||||
|
||||
#include "atom.h"
|
||||
#include "atommutex.h"
|
||||
#include "uart.h"
|
||||
|
||||
|
||||
/*
|
||||
* Semaphore for single-threaded access to UART device
|
||||
*/
|
||||
static ATOM_MUTEX uart_mutex;
|
||||
|
||||
|
||||
/*
|
||||
* Initialize the UART to requested baudrate, tx/rx, 8N1.
|
||||
*/
|
||||
int uart_init(uint32_t baudrate)
|
||||
{
|
||||
int status;
|
||||
|
||||
/**
|
||||
* Set up UART2 for putting out debug messages.
|
||||
* This the UART used on STM8S Discovery, change if required.
|
||||
*/
|
||||
UART2_DeInit();
|
||||
UART2_Init (baudrate, UART2_WORDLENGTH_8D, UART2_STOPBITS_1, UART2_PARITY_NO,
|
||||
UART2_SYNCMODE_CLOCK_DISABLE, UART2_MODE_TXRX_ENABLE);
|
||||
|
||||
/* Create a mutex for single-threaded putchar() access */
|
||||
if (atomMutexCreate (&uart_mutex) != ATOM_OK)
|
||||
{
|
||||
status = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = 0;
|
||||
}
|
||||
|
||||
/* Finished */
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \b putchar
|
||||
*
|
||||
* Retarget putchar() to use UART2
|
||||
*
|
||||
* @param[in] c Character to send
|
||||
*
|
||||
* @return Character sent
|
||||
*/
|
||||
char putchar (char c)
|
||||
{
|
||||
/* Block on private access to the UART */
|
||||
if (atomMutexGet(&uart_mutex, 0) == ATOM_OK)
|
||||
{
|
||||
/* Convert \n to \r\n */
|
||||
if (c == '\n')
|
||||
putchar('\r');
|
||||
|
||||
/* Write a character to the UART2 */
|
||||
UART2_SendData8(c);
|
||||
|
||||
/* Loop until the end of transmission */
|
||||
while (UART2_GetFlagStatus(UART2_FLAG_TXE) == RESET)
|
||||
;
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "stm8s.h"
|
||||
|
||||
#include "atom.h"
|
||||
#include "atommutex.h"
|
||||
#include "uart.h"
|
||||
|
||||
|
||||
/*
|
||||
* Semaphore for single-threaded access to UART device
|
||||
*/
|
||||
static ATOM_MUTEX uart_mutex;
|
||||
|
||||
|
||||
/*
|
||||
* Initialize the UART to requested baudrate, tx/rx, 8N1.
|
||||
*/
|
||||
int uart_init(uint32_t baudrate)
|
||||
{
|
||||
int status;
|
||||
|
||||
/**
|
||||
* Set up UART2 for putting out debug messages.
|
||||
* This the UART used on STM8S Discovery, change if required.
|
||||
*/
|
||||
UART2_DeInit();
|
||||
UART2_Init (baudrate, UART2_WORDLENGTH_8D, UART2_STOPBITS_1, UART2_PARITY_NO,
|
||||
UART2_SYNCMODE_CLOCK_DISABLE, UART2_MODE_TXRX_ENABLE);
|
||||
|
||||
/* Create a mutex for single-threaded putchar() access */
|
||||
if (atomMutexCreate (&uart_mutex) != ATOM_OK)
|
||||
{
|
||||
status = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = 0;
|
||||
}
|
||||
|
||||
/* Finished */
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \b uart_putchar
|
||||
*
|
||||
* Write a char out via UART2
|
||||
*
|
||||
* @param[in] c Character to send
|
||||
*
|
||||
* @return Character sent
|
||||
*/
|
||||
char uart_putchar (char c)
|
||||
{
|
||||
/* Block on private access to the UART */
|
||||
if (atomMutexGet(&uart_mutex, 0) == ATOM_OK)
|
||||
{
|
||||
/* Convert \n to \r\n */
|
||||
if (c == '\n')
|
||||
putchar('\r');
|
||||
|
||||
/* Write a character to the UART2 */
|
||||
UART2_SendData8(c);
|
||||
|
||||
/* Loop until the end of transmission */
|
||||
while (UART2_GetFlagStatus(UART2_FLAG_TXE) == RESET)
|
||||
;
|
||||
|
||||
/* Return mutex access */
|
||||
atomMutexPut(&uart_mutex);
|
||||
|
||||
}
|
||||
|
||||
return (c);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return (c);
|
||||
}
|
||||
|
||||
|
||||
/* COSMIC: Requires putchar() routine to override stdio */
|
||||
#if defined(__CSMC__)
|
||||
/**
|
||||
* \b putchar
|
||||
*
|
||||
* Retarget putchar() to use UART2
|
||||
*
|
||||
* @param[in] c Character to send
|
||||
*
|
||||
* @return Character sent
|
||||
*/
|
||||
char putchar (char c)
|
||||
{
|
||||
return (uart_putchar(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__)
|
||||
/**
|
||||
* \b __write
|
||||
*
|
||||
* Override for IAR stream output
|
||||
*
|
||||
* @param[in] handle Stdio handle. -1 to flush.
|
||||
* @param[in] buf Pointer to buffer to be written
|
||||
* @param[in] bufSize Number of characters to be written
|
||||
*
|
||||
* @return Number of characters sent
|
||||
*/
|
||||
size_t __write(int handle, const unsigned char *buf, size_t bufSize)
|
||||
{
|
||||
size_t chars_written = 0;
|
||||
|
||||
/* Ignore flushes */
|
||||
if (handle == -1)
|
||||
{
|
||||
chars_written = (size_t)0;
|
||||
}
|
||||
/* Only allow stdout/stderr output */
|
||||
else if ((handle != 1) && (handle != 2))
|
||||
{
|
||||
chars_written = (size_t)-1;
|
||||
}
|
||||
/* Parameters OK, call the low-level character output routine */
|
||||
else
|
||||
{
|
||||
while (chars_written < bufSize)
|
||||
{
|
||||
uart_putchar (buf[chars_written]);
|
||||
chars_written++;
|
||||
}
|
||||
}
|
||||
|
||||
return (chars_written);
|
||||
}
|
||||
#endif /* __IAR_SYSTEMS_ICC__ */
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -63,16 +63,16 @@ uint32_t test_start (void)
|
||||
uint8_t eight = 8;
|
||||
uint8_t nine = 9;
|
||||
uint8_t ten = 10;
|
||||
uint8_t eleven = 11;
|
||||
uint8_t twelve = 12;
|
||||
uint8_t thirteen = 13;
|
||||
uint8_t fourteen = 14;
|
||||
uint8_t fifteen = 15;
|
||||
uint8_t sixteen = 16;
|
||||
uint8_t seventeen = 17;
|
||||
uint8_t eighteen = 18;
|
||||
uint8_t nineteen = 19;
|
||||
uint8_t twenty = 20;
|
||||
uint16_t eleven = 11;
|
||||
uint16_t twelve = 12;
|
||||
uint16_t thirteen = 13;
|
||||
uint16_t fourteen = 14;
|
||||
uint16_t fifteen = 15;
|
||||
uint32_t sixteen = 16;
|
||||
uint32_t seventeen = 17;
|
||||
uint32_t eighteen = 18;
|
||||
uint32_t nineteen = 19;
|
||||
uint32_t twenty = 20;
|
||||
|
||||
/* Default to zero failures */
|
||||
failures = 0;
|
||||
@@ -83,106 +83,106 @@ uint32_t test_start (void)
|
||||
/* Check all variables contain expected values */
|
||||
if (one != 1)
|
||||
{
|
||||
ATOMLOG (_STR("1(%d)\n"), one);
|
||||
ATOMLOG (_STR("1(%d)\n"), (int)one);
|
||||
failures++;
|
||||
}
|
||||
if (two != 2)
|
||||
{
|
||||
ATOMLOG (_STR("2(%d)\n"), two);
|
||||
ATOMLOG (_STR("2(%d)\n"), (int)two);
|
||||
failures++;
|
||||
}
|
||||
if (three != 3)
|
||||
{
|
||||
ATOMLOG (_STR("3(%d)\n"), three);
|
||||
ATOMLOG (_STR("3(%d)\n"), (int)three);
|
||||
failures++;
|
||||
}
|
||||
if (four != 4)
|
||||
{
|
||||
ATOMLOG (_STR("4(%d)\n"), four);
|
||||
ATOMLOG (_STR("4(%d)\n"), (int)four);
|
||||
failures++;
|
||||
}
|
||||
if (five != 5)
|
||||
{
|
||||
ATOMLOG (_STR("5(%d)\n"), five);
|
||||
ATOMLOG (_STR("5(%d)\n"), (int)five);
|
||||
failures++;
|
||||
}
|
||||
if (six != 6)
|
||||
{
|
||||
ATOMLOG (_STR("6(%d)\n"), six);
|
||||
ATOMLOG (_STR("6(%d)\n"), (int)six);
|
||||
failures++;
|
||||
}
|
||||
if (seven != 7)
|
||||
{
|
||||
ATOMLOG (_STR("7(%d)\n"), seven);
|
||||
ATOMLOG (_STR("7(%d)\n"), (int)seven);
|
||||
failures++;
|
||||
}
|
||||
if (eight != 8)
|
||||
{
|
||||
ATOMLOG (_STR("8(%d)\n"), eight);
|
||||
ATOMLOG (_STR("8(%d)\n"), (int)eight);
|
||||
failures++;
|
||||
}
|
||||
if (nine != 9)
|
||||
{
|
||||
ATOMLOG (_STR("9(%d)\n"), nine);
|
||||
ATOMLOG (_STR("9(%d)\n"), (int)nine);
|
||||
failures++;
|
||||
}
|
||||
if (ten != 10)
|
||||
{
|
||||
ATOMLOG (_STR("10(%d)\n"), ten);
|
||||
ATOMLOG (_STR("10(%d)\n"), (int)ten);
|
||||
failures++;
|
||||
}
|
||||
if (eleven != 11)
|
||||
{
|
||||
ATOMLOG (_STR("11(%d)\n"), eleven);
|
||||
ATOMLOG (_STR("11(%d)\n"), (int)eleven);
|
||||
failures++;
|
||||
}
|
||||
if (twelve != 12)
|
||||
{
|
||||
ATOMLOG (_STR("12(%d)\n"), twelve);
|
||||
ATOMLOG (_STR("12(%d)\n"), (int)twelve);
|
||||
failures++;
|
||||
}
|
||||
if (thirteen != 13)
|
||||
{
|
||||
ATOMLOG (_STR("13(%d)\n"), thirteen);
|
||||
ATOMLOG (_STR("13(%d)\n"), (int)thirteen);
|
||||
failures++;
|
||||
}
|
||||
if (fourteen != 14)
|
||||
{
|
||||
ATOMLOG (_STR("14(%d)\n"), fourteen);
|
||||
ATOMLOG (_STR("14(%d)\n"), (int)fourteen);
|
||||
failures++;
|
||||
}
|
||||
if (fifteen != 15)
|
||||
{
|
||||
ATOMLOG (_STR("15(%d)\n"), fifteen);
|
||||
ATOMLOG (_STR("15(%d)\n"), (int)fifteen);
|
||||
failures++;
|
||||
}
|
||||
if (sixteen != 16)
|
||||
{
|
||||
ATOMLOG (_STR("16(%d)\n"), sixteen);
|
||||
ATOMLOG (_STR("16(%d)\n"), (int)sixteen);
|
||||
failures++;
|
||||
}
|
||||
if (seventeen != 17)
|
||||
{
|
||||
ATOMLOG (_STR("17(%d)\n"), seventeen);
|
||||
ATOMLOG (_STR("17(%d)\n"), (int)seventeen);
|
||||
failures++;
|
||||
}
|
||||
if (eighteen != 18)
|
||||
{
|
||||
ATOMLOG (_STR("18(%d)\n"), eighteen);
|
||||
ATOMLOG (_STR("18(%d)\n"), (int)eighteen);
|
||||
failures++;
|
||||
}
|
||||
if (nineteen != 19)
|
||||
{
|
||||
ATOMLOG (_STR("19(%d)\n"), nineteen);
|
||||
ATOMLOG (_STR("19(%d)\n"), (int)nineteen);
|
||||
failures++;
|
||||
}
|
||||
if (twenty != 20)
|
||||
{
|
||||
ATOMLOG (_STR("20(%d)\n"), twenty);
|
||||
ATOMLOG (_STR("20(%d)\n"), (int)twenty);
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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--)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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--)
|
||||
|
||||
18
tests/sem1.c
18
tests/sem1.c
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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--)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -139,7 +139,7 @@ uint32_t test_start (void)
|
||||
/* Check that time has advanced by exactly 1 tick */
|
||||
if ((end_time - start_time) != 1)
|
||||
{
|
||||
ATOMLOG (_STR("Tick1:%d\n"), (end_time-start_time));
|
||||
ATOMLOG (_STR("Tick1:%d\n"), (int)(end_time-start_time));
|
||||
failures++;
|
||||
}
|
||||
}
|
||||
@@ -175,7 +175,7 @@ uint32_t test_start (void)
|
||||
/* Check that time has advanced by exactly 2 ticks */
|
||||
if ((end_time - start_time) != 2)
|
||||
{
|
||||
ATOMLOG (_STR("Tick2:%d\n"), (end_time-start_time));
|
||||
ATOMLOG (_STR("Tick2:%d\n"), (int)(end_time-start_time));
|
||||
failures++;
|
||||
}
|
||||
}
|
||||
@@ -211,7 +211,7 @@ uint32_t test_start (void)
|
||||
/* Check that time has advanced by exactly 500 ticks */
|
||||
if ((end_time - start_time) != 500)
|
||||
{
|
||||
ATOMLOG (_STR("Tick500:%d\n"), (end_time-start_time));
|
||||
ATOMLOG (_STR("Tick500:%d\n"), (int)(end_time-start_time));
|
||||
failures++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -39,7 +39,6 @@ static ATOM_TIMER timer_cb[4];
|
||||
/* Global test data */
|
||||
static volatile uint32_t cb_order[4];
|
||||
static int cb_cnt = 0;
|
||||
static uint32_t cb_time[4];
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
@@ -136,7 +135,7 @@ uint32_t test_start (void)
|
||||
{
|
||||
if (cb_order[i] != i)
|
||||
{
|
||||
ATOMLOG (_STR("T%d=%d\n"), i, cb_order[i]);
|
||||
ATOMLOG (_STR("T%d=%d\n"), i, (int)cb_order[i]);
|
||||
failures++;
|
||||
}
|
||||
}
|
||||
@@ -165,9 +164,6 @@ static void testCallback (POINTER cb_data)
|
||||
/* Store our callback order in cb_order[] */
|
||||
cb_order[cb_cnt] = expected_order;
|
||||
|
||||
/* Store the current time for debug purposes */
|
||||
cb_time[cb_cnt] = atomTimeGet();
|
||||
|
||||
/* Interrupts are locked out so we can modify cb_cnt without protection */
|
||||
cb_cnt++;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user