--------------------------------------------------------------------------- Library: Atomthreads Author: Kelvin Lawson Website: http://atomthreads.com License: BSD Revised --------------------------------------------------------------------------- STM8 PORT This folder contains a port of the Atomthreads real time kernel for the STM8 processor architecture. 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.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: * stm8_interrupt_vector.c: List of interrupt handlers for vector table * tests-main.c: Main application file (used for launching automated tests) * 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, 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. --------------------------------------------------------------------------- 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. The Cosmic compiler and STVP are currently Windows-only applications. For users of other operating systems the Cosmic 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: * Cosmic 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 Cosmic modsl0 memory model. This places all data outside of the short 0x0-0x255 page0 area, which allows large data blocks such as thread stacks to fit. You could instead use the more efficient mods0 memory model which places data in the short page0 area, and force large data areas like thread stacks outside of page0 by adding @near modifiers or specifying data areas by the linker file etc. The default configuration is modsl0 (place outside of page0) to allow for the most portable application compilation, with the option of optimising this by placing data in page0 if desired. There is no requirement that you compile your applications using the modsl0 memory model. --------------------------------------------------------------------------- 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 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. 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, 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 Cosmic 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\COSMIC\STMS_16K * set MAKE_MODE=DOS The full build is carried out using simply: * make 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 built objects etc can be cleaned using: * make 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 --------------------------------------------------------------------------- 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. The tools delivered by ST do not appear to offer any easy way of downloading and running applications built externally. For the time being the following (slow) development workflow is possible (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. * Program using STVP. Unfortunately STVP does not reset and start the CPU running. The following can be used to do this: * cd \Program Files\STMicroelectronics\st_toolset\stvd\swim * ..\gdb7.exe --command=gdbswim_stlink.ini * emulator-reset-port-mcu usb://usb stm8s105c6 * run Your application should now be programmed and running. If you wish to run another application, you must stop GDB using Ctrl-C and request STVP to communicate with the USB debugger again (either by selecting "Configure ST Visual Programmer" or just closing and reopening the STVP application). You can then download a new application and repeat the GDB steps. You must force a USB reconnect within STVP because it loses communication with the debugger while GDB is in use. This is clearly not a very efficient workflow but it appears that at this time there are no applications for simple programming and running of applications to the STM8S-Discovery hardware. Other development platforms and debugger hardware may have better tools available, this only applies to the Discovery. --------------------------------------------------------------------------- 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 application makes use of an LED on one of the GPIO ports of the Discovery board to indicate whether the automated tests passed or failed. This is not a core port feature and would not be required in user applications. If you are using a CPU other than the STM8S105C6 you should modify stm8s_conf.h to specify your CPU. You may also wish to enable in that file any CPU peripherals which you wish to use. --------------------------------------------------------------------------- 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 usr STVP to program it, and GDB to start the application running. 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. 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. --------------------------------------------------------------------------- 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 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. --------------------------------------------------------------------------- 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. While 128 bytes has so far been found to be sufficient for the stack needs of all of the automated test module threads, the main test thread does typically require more due to the additional variables and subroutines called. You may monitor the stack usage of your application threads during runtime by defining the macro ATOM_STACK_CHECKING and calling atomThreadStackCheck(). This macro is defined by default in the Makefile so that the automated test modules can check for stack overflows, but you may wish to undefine this in your application Makefiles when you are happy that the stack usage is acceptable. Enabling ATOM_STACK_CHECKING will increase the size of your threads' TCBs slightly, and will incur a minor CPU cycles overhead whenever threads are created due to prefilling the thread stack with a known value. With careful consideration and few threads it would be possible to use a platform with 512 bytes RAM, but not all of the automated test suite would run on such a platform (some of the test modules use 6 threads: a main thread together with 4 test threads and the idle thread). The RAM layout used for the automated test applications is as follows: RAM Top: * Startup Stack (64 bytes) * Data & BSS area (thread stacks, other application data) RAM Bottom. This is not prescribed, you may use whichever layout you wish for your applications. The startup stack area starts at the top of RAM and is only used for first initialisation of the OS and main thread. This uses 64 bytes and could be reused once the OS is started, but for the purposes of the automated test applications it is not reused. Generally you would ensure that this is reused in your own application code. The application's data starts at the bottom of RAM, and this includes all of the thread stacks which are statically allocated arrays. The idle thread, main thread, and automated test thread stacks are allocated here. If your application includes a large amount of data which is nearing the top of RAM, then you must be careful that conflicts do not occur with the startup stack. The startup stack uses the 64 bytes from RAMTOP down. This is not reserved with the linker, so you will receive no warning if your own data encroaches on this area. It may not matter because the startup stack is only used before the OS is started, but if the data here cannot be corrupted before the OS is started then you should make other arrangements, such as moving the startup stack elsewhere or placing data which can be overwritten in this area. To check whether your application data overlaps with the startup stack you can view the MAP file for the application. This shows how much RAM is used by the data and BSS areas. If you have 2048 bytes RAM, then you will need to ensure that the application data uses less than (2048-64) bytes, or be sure that it is safe to utilise that area for the startup stack before the OS is started. The default layout provided with Atomthreads matches the STM8S-Discovery with 2KB RAM. The linker file reserves the first 0x500 bytes for data areas. The region from here up to the end of RAM (0x800) is used for the the 64 byte startup stack and any other data you require. You may wish to place some of your thread's stacks in the area above 0x500, or you may prefer to increase the size of the data area beyond 0x500. A simple layout would be to allow everything up to (RAMTOP-64) to be used for application data, leaving the top 64 bytes for use by the startup stack. This way the linker would warn you if your application data overlapped with the startup stack. As mentioned previously, this RAM layout is only the one utilised by the test applications. You may choose whatever layout you like. Note that on this platform data can be placed at address 0x0, but the Atomthreads kernel performs validity checks on pointers to ensure they are not NULL pointers (point to address 0x0). For this reason the example projects (STVD and Makefile) force the linker to not use address 0x0 and instead start the page0 space at 0x2. This ensures that the linker does not place any data at address 0x0, and hence all NULL-ptr checks are still suitable checks for valid pointers. This does, however, waste 2 bytes. For your own projects you can force this within STVD by editing the project linker settings (Input -> Zero Page start at 0x2) or by editing the linker .LKF file as can be seen in atomthreads.lkf. ---------------------------------------------------------------------------