mirror of
https://git.intern.spaceteamaachen.de/ALPAKA/TACOS.git
synced 2025-06-10 16:45:59 +00:00
doc: Added READMEs for TACOS usage
This commit is contained in:
parent
648fa38667
commit
9e4ac9d73a
190
README.md
190
README.md
@ -1,18 +1,63 @@
|
||||
# TACOS
|
||||
|
||||
This is the Trajectory Analysis Control OS (TACOS) that serves as a starting point for developing TACOS-based projects, by implementing threads in the App directory. TACOS is a subset of the features provided by ALPAKA. In particular, TACOS consists of the STM32-specific components of sta-core, rtos-2 and rtos2-utils.
|
||||
This is the Trajectory Analysis Control OS (TACOS) that serves as a framework for flight computer development. TACOS offers a state machine, a CAN bus interface, a watchdog and other HAL features through it's submodules. It runs on cmsis-rtos2 FreeRTOS on STM32 microcontrollers with C++ (maybe future versions will offer external C interfaces to support a wide array of languages...).
|
||||
|
||||
## Setting Up TACOS
|
||||
To use TACOS one should implement threads, which fulfill the various roles of the module in the App directory. TACOS utilizes [ALPAKA](https://git.intern.spaceteamaachen.de/ALPAKA) features, in particular requiring [sta-core](https://git.intern.spaceteamaachen.de/ALPAKA/sta-core) and [rtos2-utils](https://git.intern.spaceteamaachen.de/ALPAKA/rtos2-utils), as such it requires these to be in it's include path.
|
||||
|
||||
Add this as a library an existing CubeIDE project using FreeRTOS. Generally, we advise you to add it as a submodule. Make sure that you add the include paths for Tacos, i.e. sta-core and rtos2-utils, to the project with the following steps:
|
||||
```
|
||||
Properties -> C/C++ General -> Paths and Symbols -> Includes -> GNU C -> Add...
|
||||
Properties -> C/C++ General -> Paths and Symbols -> Includes -> GNU C++ -> Add...
|
||||
Properties -> C/C++ General -> Paths and Symbols -> Source Location -> Add Folder...
|
||||
## Setting up a TACOS project
|
||||
|
||||
### Setting up the project
|
||||
|
||||
First one must create a new CubeIDE project with FreeRTOS. To avoid doing that however we recommend using the [ioc-collection](https://git.intern.spaceteamaachen.de/ALPAKA/ioc-collection) to get a preconfigured IOC for the STM microcontroller you are using. From here follow the following steps:
|
||||
|
||||
1. ```Import -> General -> Import an Existing STM32CubeMX Configuration File (.ioc)```
|
||||
2. Select the .ioc file from the ioc-collection
|
||||
3. Enter the project name and location you want to save the project to
|
||||
4. Select C++ as the target language
|
||||
5. Click "Finish"
|
||||
|
||||
|
||||
### Setting up the folder structure
|
||||
|
||||
Now it is necessary to setup the dependencies and include paths for TACOS. For this first create a new folder in the project directory called `Libs`. Then create another folder in the project directory called `App` with the subfolders `Inc` and `Src`. Now also create a folder called `sta` in the `Inc` folder. Finally add the empty files `App/Inc/sta/config.hpp` and `App/Src/startup.cpp`.
|
||||
|
||||
Now your project should look like this:
|
||||
```
|
||||
...
|
||||
App/
|
||||
├── Inc/
|
||||
│ ├── sta/
|
||||
│ │ └── config.hpp
|
||||
├── Src/
|
||||
│ └── startup.cpp
|
||||
Libs/
|
||||
...
|
||||
```
|
||||
|
||||
Create a new thread via the project's IOC and call `startTACOS()` from this thread. If your thread is called `defaultTask`, the corresponding function `StartDefaultTask` generated in `Core/Src/freertos.c` should look like this:
|
||||
### Setting up the dependencies
|
||||
|
||||
First it is recommended to initialize a git repository in the project folder with `git init`. Then add the TACOS, sta-core and rtos2-utils repositories as submodules in the `Libs` folder with the following commands:
|
||||
```bash
|
||||
cd Libs
|
||||
git submodule add https://git.intern.spaceteamaachen.de/ALPAKA/TACOS.git
|
||||
git submodule add https://git.intern.spaceteamaachen.de/ALPAKA/sta-core.git
|
||||
git submodule add https://git.intern.spaceteamaachen.de/ALPAKA/rtos2-utils.git
|
||||
```
|
||||
|
||||
Make sure that you add the include paths for TACOS, sta-core and rtos2-utils to the project with the following steps:
|
||||
1. `Properties -> C/C++ General -> Paths and Symbols -> Includes -> GNU C -> Add...`
|
||||
2. Select `Add to all languages` and `Is a workspace path`
|
||||
3. Click on `Workspace` and select a folder from the `YOUR_PROJECT_FOLDER/(Libs|App)` directory
|
||||
- Always select the `include` or `Inc` folder for the include paths
|
||||
- If the path you want to add is not in the list, refresh the project with `F5` in the `Project Explorer` and try again
|
||||
4. Repeat for TACOS, sta-core, rtos2-utils and the App folder
|
||||
5. `Properties -> C/C++ General -> Paths and Symbols -> Source Location -> Add Folder...`
|
||||
- Add the `App` and `Libs` folders
|
||||
|
||||
### Starting TACOS
|
||||
|
||||
Navigate to the `Core/Src/freertos.c` file and add the following code to the `StartDefaultTask` function:
|
||||
```cpp
|
||||
void StartDefaultTask(void *argument)
|
||||
{
|
||||
/* USER CODE BEGIN StartDefaultTask */
|
||||
@ -28,9 +73,11 @@ void StartDefaultTask(void *argument)
|
||||
}
|
||||
```
|
||||
|
||||
## Configuring TACOS
|
||||
This will start the TACOS startup and initialize all TACOS threads (which will then initialize yours).
|
||||
|
||||
### Configuring TACOS
|
||||
In order to use TACOS, you need to provide a configuration file in the path `sta/config.hpp`. The following code is an example for a TACOS-project using default configuration:
|
||||
```
|
||||
```cpp
|
||||
#ifndef INC_STA_CONFIG_HPP_
|
||||
#define INC_STA_CONFIG_HPP_
|
||||
|
||||
@ -50,6 +97,7 @@ In order to use TACOS, you need to provide a configuration file in the path `sta
|
||||
#define STA_RTOS_SYSTEM_EVENTS_ENABLE
|
||||
// #define STA_RTOS_SYSTEM_WATCHDOG_ENABLE
|
||||
// #define STA_RTOS_WATCHDOG_ENABLE
|
||||
// #define STA_TACOS_WATCHDOG_FREQUENCY 10000
|
||||
#define STA_CAN_BUS_ENABLE
|
||||
|
||||
// Statemachine settings.
|
||||
@ -61,12 +109,85 @@ In order to use TACOS, you need to provide a configuration file in the path `sta
|
||||
#endif /* INC_STA_CONFIG_HPP_ */
|
||||
```
|
||||
PS: For not officially supported chips use this as the include:
|
||||
```
|
||||
```cpp
|
||||
#include <sta/devices/stm32/mcu/common.hpp>
|
||||
#define STA_MCU_LITTLE_ENDIAN
|
||||
#define STA_PLATFORM_STM32
|
||||
```
|
||||
## Setting up the CAN Bus
|
||||
|
||||
### Implementing your own threads
|
||||
|
||||
Let's create a simple thread that prints "Hello World" every second. First create a new file in the `App/Inc/tasks` folder called `spam_task.hpp`. Then add the following code:
|
||||
```cpp
|
||||
#ifndef INC_TASKS_SPAM_TASK_HPP_
|
||||
#define INC_TASKS_SPAM_TASK_HPP_
|
||||
|
||||
#include <sta/tacos.hpp>
|
||||
|
||||
namespace tasks
|
||||
{
|
||||
class SpamTask : public sta::tacos::TacosThread {
|
||||
public:
|
||||
SpamTask();
|
||||
|
||||
// One time function that is called when the thread is created.
|
||||
void init() override;
|
||||
|
||||
// Repeatable function that is called every time the thread is executed.
|
||||
void func() override;
|
||||
};
|
||||
} // namespace tasks
|
||||
|
||||
#endif /* INC_TASKS_SPAM_TASK_HPP_ */
|
||||
```
|
||||
This code defines a new thread that inherits from `TacosThread` and implements the `init` and `func` functions. The `init` function is called once when the thread is created and the `func` function is called every time the thread is executed.
|
||||
|
||||
Now create a new file in the `App/Src/tasks` folder called `spam_task.cpp` and add the following code:
|
||||
```cpp
|
||||
#include <tasks/spam_task.hpp>
|
||||
|
||||
namespace tasks {
|
||||
SpamTask::SpamTask() :
|
||||
TacosThread("SPAM", osPriorityNormal){}
|
||||
|
||||
void SpamTask::init() {
|
||||
// Nothing to init...
|
||||
}
|
||||
|
||||
void SpamTask::func() {
|
||||
// Print "Hello World" every second.
|
||||
STA_DEBUG_PRINTLN("Hello World");
|
||||
this->periodicDelay(1); // Execute this function with 1 Hz.
|
||||
}
|
||||
} // namespace tasks
|
||||
```
|
||||
|
||||
To start this thread, we first need to fill out the `startup.cpp` file. This file may look like this:
|
||||
```cpp
|
||||
#include <sta/tacos.hpp>
|
||||
#include <tasks/spam_task.hpp>
|
||||
|
||||
#include <sta/debug/debug.hpp>
|
||||
|
||||
namespace sta
|
||||
{
|
||||
namespace tacos
|
||||
{
|
||||
void onStatemachineInit()
|
||||
{
|
||||
// ###### Register different threads for different states here. ######
|
||||
// Register a "Spam Task" thread for all states except 1 and 2.
|
||||
sta::tacos::addThread<tasks::SpamTask>(ALL_STATES - state_set{1,2});
|
||||
|
||||
STA_DEBUG_PRINTF("The answer to everything is %d", 42);
|
||||
}
|
||||
} // namespace tacos
|
||||
} // namespace sta
|
||||
```
|
||||
|
||||
And that's it! Now you have a thread that prints "Hello World" every second. Simply build the project and flash it to your microcontroller and be amazed by the Spam!
|
||||
|
||||
### Setting up the CAN Bus
|
||||
|
||||
To enable the CAN Bus two things need to be done:
|
||||
1. Enable CAN in the IOC with the RX0 and RX1 Interrupts enabled.
|
||||
@ -79,4 +200,47 @@ PS: For not officially supported chips add this:
|
||||
#define STA_STM32_CAN_HANDLE {YOUR_HCAN_HANDLE}
|
||||
```
|
||||
|
||||
After this messages will automatically be forwarded to the task with it's ID. To send messages use the interface defined in `tacos.hpp`.
|
||||
There are two options for handling incoming CAN messages:
|
||||
1. If `#define STA_CAN_BUS_FWD_ENABLE` is set, the messages will be forwarded to the task with the ID of the message.
|
||||
- Tasks set their ID with `setID(uint32_t id)` in their constructor.
|
||||
- From here they can handle the message by going through their `CAN_queue_` with `CanSysMsg msg; CAN_queue_.get(&msg);`
|
||||
2. All messages will trigger the weakly defined handleSysMessage callback.
|
||||
- This could be implemented like this:
|
||||
```cpp
|
||||
namespace sta
|
||||
{
|
||||
namespace tacos
|
||||
{
|
||||
bool handleSysMessage(CanMsgHeader &header, uint8_t *payload)
|
||||
{
|
||||
// Print the message ID and the first byte of the payload.
|
||||
//(please don't do this in production, it will crash the system sooner or later)
|
||||
STA_DEBUG_PRINTF("> ID: %d", header.sid);
|
||||
|
||||
switch (header.sid)
|
||||
{
|
||||
// State transition message
|
||||
case STA_TACOS_CAN_BUS_SYS_MSG_ID:
|
||||
// First byte of payload is the origin state, second byte is the destination state
|
||||
tacos::setState(payload[0], payload[1], 0, true);
|
||||
return true;
|
||||
|
||||
case MODULE_SW_RESET_CAN_ID:
|
||||
HAL_NVIC_SystemReset();
|
||||
|
||||
return true; // :)
|
||||
|
||||
// ...
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return false; // I know, i know, this is not necessary, but it's good practice. And you know what they say about good practice: Do it!
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Further information
|
||||
To look into other function of TACOS please consult the READMEs in the include folder or the doxygen documentation. Also consult the sta-core and rtos2-utils READMEs for further information on the features that TACOS uses.
|
93
include/sta/README.md
Normal file
93
include/sta/README.md
Normal file
@ -0,0 +1,93 @@
|
||||
# TACOS.hpp
|
||||
|
||||
The TACOS API is defined in the tacos.hpp, in normal use cases you should only need to include this file.
|
||||
|
||||
## Functions
|
||||
|
||||
```cpp
|
||||
uint16_t getState()
|
||||
```
|
||||
|
||||
Retrieves the current state of the TACOS state machine.
|
||||
|
||||
---
|
||||
```cpp
|
||||
void requestState(uint32_t from, uint32_t to, uint32_t lockout = 0, bool publish = true)
|
||||
```
|
||||
|
||||
Requests a state transition. Invalid state transitions will be dismissed. First come, first serve.
|
||||
|
||||
- **Parameters**:
|
||||
- `from`: The starting state for the transition.
|
||||
- `to`: The target state to transition to.
|
||||
- `lockout`: (Optional) A timer to block further transitions.
|
||||
- `publish`: (Optional) Whether to publish the state transition to the CAN bus.
|
||||
|
||||
```cpp
|
||||
void forceState(uint32_t from, uint32_t to, uint32_t lockout = 0, bool publish = true)
|
||||
```
|
||||
|
||||
Forces a state transition. Will be ignored if already in the given state. Triggers instantly.
|
||||
|
||||
- **Parameters**:
|
||||
- `from`: The starting state for the transition.
|
||||
- `to`: The target state to transition to.
|
||||
- `lockout`: (Optional) A timer to block further transitions.
|
||||
- `publish`: (Optional) Whether to publish the state transition to the CAN bus.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
void setStateTimed(uint32_t from, uint32_t to, uint32_t millis, uint32_t lockout = 0, bool publish = false)
|
||||
```
|
||||
|
||||
Requests a state transition after a specified time.
|
||||
|
||||
- **Parameters**:
|
||||
- `from`: The starting state.
|
||||
- `to`: The target state.
|
||||
- `millis`: The wait time in milliseconds before requesting the transition.
|
||||
- `lockout`: (Optional) A timer for blocking subsequent transitions.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
template<typename T, typename ... Args> std::shared_ptr<T> addThread(std::set<uint16_t> states, Args ... args)
|
||||
```
|
||||
|
||||
Registers a new thread to be run by TACOS.
|
||||
|
||||
- **Template Parameters**:
|
||||
- `T`: The class type of the thread, which should inherit from `TacosThread`.
|
||||
- **Parameters**:
|
||||
- `states`: A set of states in which the thread should be active.
|
||||
- `args`: The constructor arguments for the thread class.
|
||||
|
||||
---
|
||||
|
||||
### CAN Bus Functions (Conditional)
|
||||
|
||||
The following functions are available only if `STA_TACOS_CAN_BUS_ENABLED` is defined:
|
||||
|
||||
```cpp
|
||||
bool queueCanBusMsg(CanSysMsg & msg, uint32_t timeout)
|
||||
```
|
||||
|
||||
Queues a message to be sent over the CAN bus.
|
||||
|
||||
- **Parameters**:
|
||||
- `msg`: The message to be sent.
|
||||
- `timeout`: The maximum time to wait for sending the message.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
bool publishState(uint32_t from, uint32_t to, uint32_t timeout = 0)
|
||||
```
|
||||
|
||||
Publishes a state transition message to the CAN bus.
|
||||
|
||||
- **Parameters**:
|
||||
- `from`: The starting state for the transition.
|
||||
- `to`: The target state.
|
||||
- `timeout`: (Optional) A timeout for CAN communication.
|
23
include/sta/tacos/README.md
Normal file
23
include/sta/tacos/README.md
Normal file
@ -0,0 +1,23 @@
|
||||
# TACOS tasks and prototypes
|
||||
|
||||
## Statemachine
|
||||
The statemachine is the core of TACOS. It is responsible for managing the state of the system and executing the threads that are registered to it. The statemachine is a singleton and can be accessed via `sta::tacos::Statemachine::instance()`.
|
||||
|
||||
For further info check the file or the doxygen documentation.
|
||||
|
||||
## Watchdog
|
||||
The watchdog checks if all threads are setting a flag after every func call. If a thread does not set the flag in the given interval the thread is restarted.
|
||||
|
||||
The watchdog is enabled and configured with the following defines:
|
||||
```cpp
|
||||
#define STA_RTOS_WATCHDOG_ENABLE
|
||||
#define STA_TACOS_WATCHDOG_FREQUENCY 10000
|
||||
```
|
||||
|
||||
## CAN Bus
|
||||
The CAN bus is used to communicate between different devices. The CAN bus task is triggered by IRQ from the transceiver or if something is inserted into it's output queue.
|
||||
|
||||
This thing is a huge steaming (but functioning) pile of shit. Further documentation is on hold until rework.
|
||||
|
||||
## Thread.hpp
|
||||
Here the TacosThread is defined. Very straight forward. Just take a look inside.
|
3
include/sta/tacos/c_api/README.md
Normal file
3
include/sta/tacos/c_api/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
# TACOS C API
|
||||
|
||||
Currently the only C API is the entry point for starting up TACOS. This will be extended to provide full functionality via C calling conventions.
|
Loading…
x
Reference in New Issue
Block a user