Merge pull request 'main' (#7) from main into nehlich/ffs

Reviewed-on: romeo/obsw#7
This commit is contained in:
2024-05-24 11:39:06 +02:00
4 changed files with 144 additions and 74 deletions

105
README.md
View File

@ -1,14 +1,66 @@
# ROMEO Onboard Software (OBSW)
## What is ROMEO?
# Build with Docker [For a broader introduction and documentation refer to the OBSW Wiki in the ROMEO Knowledge Base](https://openproject.mm.intra.irs.uni-stuttgart.de/projects/romeo-phase-c/wiki/obsw). This README gives a very brief introduction and aims to document the compile process for experienced developers.
[_Research and Observation in Medium Earth Orbit (ROMEO)_](https://www.irs.uni-stuttgart.de/en/research/satellitetechnology-and-instruments/smallsatelliteprogram/romeo/) is the third small satellite of the Institute of Space Systems (IRS), University of Stuttgart with the objective of technology demonstration in Medium and Low Earth Orbit (MEO/LEO) with a mission duration of 1 year.
The Onboard Software (OBSW) is written in Rust for run-time stability. The implemented framework is losely based on the C++ Flight Software Framework (FSFW) developed at the IRS in cooperation with industry. The shift to Rust was discussed in Paul Nehlich's master thesis: [_Analysis and preparation of the transformation of the Flight Software Framework from C++ to Rust_](https://www.researchgate.net/publication/372439213_Analysis_and_preparation_of_the_transformation_of_the_Flight_Software_Framework_from_C_to_Rust).
<img src="https://egit.irs.uni-stuttgart.de/romeo/obsw/media/branch/main/romeo_design_from_website.bmp" alt="ROMEO Preliminary Design" width="400"/>
(design from IRS ROMEO Website)
## How to Configure This Repository? TODO
# First Stage Bootloader (FSBL)
FSBL code is at https://github.com/Xilinx/embeddedsw/
## Scope
This is the central repository for the flight software of the ROMEO satellite.
It will eventually become the new base of a Rust Flight Software Framework replacing the C++ Flight Software Framework of the FLP, EIVE and SOURCE.
The current working steps are:
- Build Toolchain (Daniel Philipp)
- Hardware itnerfaces (Paul Nehlich)
- CAN Bus (Andy Hinkel)
- RS422 (Paul Nehlich, Joris Janßen)
- Device Handling Fundamentals (Joris Janßen)
- Framework Core Component Implementation (Paul Nehlich, Ulrich Mohr)
- Integration of Space Packets and PUS Services (to be scheduled, Paul Nehlich)
- OBC Board support and Linux Boot Management (Michael Steinert)
- Device Integration
- AOCS
- TCS
- Communications Interfaces
## Prerequisits for build with Docker
##### Info ##### Info
IRS wireguard VPN can cause network issues with docker. IRS wireguard VPN can cause network issues with docker.
##### Install Docker ##### Install Docker
https://www.docker.com/get-started/ If you are using macOS or Windows, please use this tutorial:
- https://www.docker.com/get-started/
On Linux simply use your package manager to install ```docker``` and prepare everything using these commands, to avoid permission denied errors:
```sh
sudo systemctl start docker
sudo groupadd docker
sudo usermod -aG docker $USER
sudo reboot
```
## FSBL ## FSBL
FSBL is the First Stage Boot Loader and prepares the CPU and FPGA configuration for booting up the Second Stage Bootloader and finally the flight software.
##### Clone the repository and build the docker image: ##### Clone the repository and build the docker image:
```sh ```sh
@ -22,20 +74,38 @@ docker build -t compile_fsbl .
docker run -v ./embeddedsw:/fsbl compile_fsbl /bin/bash -c "cd lib/sw_apps/zynq_fsbl/src && make BOARD=zed SHELL=/bin/bash" docker run -v ./embeddedsw:/fsbl compile_fsbl /bin/bash -c "cd lib/sw_apps/zynq_fsbl/src && make BOARD=zed SHELL=/bin/bash"
``` ```
## Requirements [TBC]:
1. `cmake`
2. `arm-none-eabi-gcc`
3. `doxygen`
4. `graphviz`
If you want, copy the fsbl.elf to the docker/compile_fsbl directory for easier access: If you want, copy the fsbl.elf to the docker/compile_fsbl directory for easier access:
```sh ```sh
cp embeddedsw/lib/sw_apps/zynq_fsbl/src/fsbl.elf . cp embeddedsw/lib/sw_apps/zynq_fsbl/src/fsbl.elf .
``` ```
## Steps
1. Configure doxygen:
## mission_rust ## mission_rust
##### Build the docker image: ##### Build the docker image:
```sh ```sh
export DOT_PATH=/usr/local/bin
```
2. Satisfy Rust requirements
```sh
cd ../mission_rust
cargo update
rustup toolchain install nightly
rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu
rustup override set nightly
cargo build -Z build-std
cd docker/compile_mission/ cd docker/compile_mission/
docker build -t compile_mission . docker build -t compile_mission .
``` ```
3. Configure the ROMEO OBSW repository in `.../obsw/`
##### To build the mission_rust, run the following command in the `docker/compile_mission` directory: ##### To build the mission_rust, run the following command in the `docker/compile_mission` directory:
```sh ```sh
docker run -v $(pwd)/../../mission_rust:/mission_rust compile_mission /bin/bash -c "cargo build -Z build-std" docker run -v $(pwd)/../../mission_rust:/mission_rust compile_mission /bin/bash -c "cargo build -Z build-std"
@ -62,18 +132,17 @@ docker run -v $(pwd)/../..:/obsw compile_obsw /bin/bash -c "mkdir -p build_cli &
``` ```
The romeo-obsw binary can now be found in the `build_cli` directory. The romeo-obsw binary can now be found in the `build_cli` directory.
# Debugging on `zedboard`
`zedboard` is the `Xilinx Zynq-7000` development board.
## Requirements [TBC]:
- `OpenOCD`
- `arm-none-eabi-gdb`
## Steps
TODO: discuss this with paul
# Debugging on zedboard 1. Set Zedboard `boot mode` to JTAG and connect debugging PC to zedboard JTAG and UART USB port.
TODO: what is which port, use distinct name/add a graphic
Requirements [TBC]: 2. On PC connected to zedboard JTAG USB port:
- OpenOCD
- arm-none-eabi-gdb
Set Zedboard boot mode to jtag and connect debugging PC to zedboard jtag and uart usb port.
On PC connected to zedboard jtag usb port:
```sh ```sh
openocd -f board/digilent_zedboard.cfg openocd -f board/digilent_zedboard.cfg
``` ```
@ -83,7 +152,7 @@ If you have one around, load bitstream at startup (go get a coffee, takes time w
openocd -f board/digilent_zedboard.cfg -c "init" -c "pld load 0 system.bit" openocd -f board/digilent_zedboard.cfg -c "init" -c "pld load 0 system.bit"
``` ```
To use JTAG Boot for the obsw, you first need to run the FSBL once. 3. To use JTAG Boot for the OBSW, you first need to run the FSBL once.
On build PC (adapt IP if different from debugging PC) in the folder where you build the FSBL as above: On build PC (adapt IP if different from debugging PC) in the folder where you build the FSBL as above:
```sh ```sh
@ -94,14 +163,14 @@ arm-none-eabi-gdb fsbl.elf
>^C^D^D >^C^D^D
``` ```
You can automate this run: ### (Optional) Automate this run:
```sh ```sh
arm-none-eabi-gdb fsbl.elf -iex "target extended-remote localhost:3333" -ex "set pagination off" -ex "load" -ex "break FsblHandoffJtagExit" -ex "cont" -ex="set confirm off" -ex "exit" arm-none-eabi-gdb fsbl.elf -iex "target extended-remote localhost:3333" -ex "set pagination off" -ex "load" -ex "break FsblHandoffJtagExit" -ex "cont" -ex="set confirm off" -ex "exit"
``` ```
It will exit after the Zynq is configured and ready to firmware. It will exit after the Zynq is configured and ready to firmware.
Then load the actual obsw, in the build (`build_cli` in the example above) folder run: Then load the actual OBSW, in the build (`build_cli` in the example above) folder run:
```sh ```sh
arm-none-eabi-gdb romeo-obsw arm-none-eabi-gdb romeo-obsw
>target extended-remote localhost:3333 >target extended-remote localhost:3333
@ -109,9 +178,9 @@ arm-none-eabi-gdb romeo-obsw
>cont >cont
``` ```
Again, cli commands can be moved to the gdb call. Also, a small function is used as marker to return from gdb if the mission code returns (should not happen in production but might be useful during testing). Again, `Command Line Interface (CLI) commands` can be moved to the GNU Debugger (DGB) call. Also, a small function is used as marker to return from GDB if the mission code returns (should not happen in production but might be useful during testing).
```sh ```sh
arm-none-eabi-gdb romeo-obsw -iex "target extended-remote localhost:3333" -ex "set pagination off" -ex "load" -ex "break done" -ex "cont" -ex="set confirm off" -ex "exit" arm-none-eabi-gdb romeo-obsw -iex "target extended-remote localhost:3333" -ex "set pagination off" -ex "load" -ex "break done" -ex "cont" -ex="set confirm off" -ex "exit"
``` ```
Uart usb port should output something at 115200baud, (I use moserial to monitor). UART USB port should output something at `115200baud`, (I use moserial to monitor).

1
docker/compile_fsbl/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
embeddedsw

View File

@ -160,71 +160,71 @@ static const uint16_t stackSizeWords = 512;
StaticTask_t xTaskBuffer; StaticTask_t xTaskBuffer;
StackType_t xStack[512]; StackType_t xStack[512];
void testIp() { // void testIp() {
uartIsrQueue = // uartIsrQueue =
xQueueCreateStatic(QUEUE_LENGTH, 1, ucQueueStorageArea, &xStaticQueue); // xQueueCreateStatic(QUEUE_LENGTH, 1, ucQueueStorageArea, &xStaticQueue);
lwip_init(); // lwip_init();
ip4_addr_t slip_addr = {PP_HTONL(LWIP_MAKEU32(10, 0, 0, 32))}, // ip4_addr_t slip_addr = {PP_HTONL(LWIP_MAKEU32(10, 0, 0, 32))},
slip_mask = {PP_HTONL(LWIP_MAKEU32(255, 255, 255, 0))}, // slip_mask = {PP_HTONL(LWIP_MAKEU32(255, 255, 255, 0))},
slip_gw = {PP_HTONL(LWIP_MAKEU32(10, 0, 0, 1))}; // slip_gw = {PP_HTONL(LWIP_MAKEU32(10, 0, 0, 1))};
netif_add(&netif, &slip_addr, &slip_mask, &slip_gw, NULL, slipif_init, // netif_add(&netif, &slip_addr, &slip_mask, &slip_gw, NULL, slipif_init,
netif_input); // netif_input);
netif_set_default(&netif); // netif_set_default(&netif);
// should be done by driver, which does not do it, so we do it here // // should be done by driver, which does not do it, so we do it here
netif_set_link_up(&netif); // netif_set_link_up(&netif);
netif_set_up(&netif); // netif_set_up(&netif);
udpecho_raw_pcb = udp_new_ip_type(IPADDR_TYPE_ANY); // udpecho_raw_pcb = udp_new_ip_type(IPADDR_TYPE_ANY);
if (udpecho_raw_pcb != NULL) { // if (udpecho_raw_pcb != NULL) {
err_t err; // err_t err;
err = udp_bind(udpecho_raw_pcb, IP_ANY_TYPE, 7); // err = udp_bind(udpecho_raw_pcb, IP_ANY_TYPE, 7);
if (err == ERR_OK) { // if (err == ERR_OK) {
udp_recv(udpecho_raw_pcb, udpecho_raw_recv, NULL); // udp_recv(udpecho_raw_pcb, udpecho_raw_recv, NULL);
} else { // } else {
/* TODO */ // /* TODO */
} // }
} else { // } else {
/* TODO */ // /* TODO */
} // }
/* Install the UART Interrupt handler. */ // /* Install the UART Interrupt handler. */
BaseType_t xStatus = // BaseType_t xStatus =
XScuGic_Connect(&xInterruptController, STDIN_INT_NR, // XScuGic_Connect(&xInterruptController, STDIN_INT_NR,
(Xil_ExceptionHandler)handleUARTInt, NULL); // (Xil_ExceptionHandler)handleUARTInt, NULL);
configASSERT(xStatus == XST_SUCCESS); // configASSERT(xStatus == XST_SUCCESS);
(void)xStatus; /* Remove compiler warning if configASSERT() is not defined. */ // (void)xStatus; /* Remove compiler warning if configASSERT() is not defined. */
// Set trigger level to 62 of 64 bytes, giving interrupt some time to react // // Set trigger level to 62 of 64 bytes, giving interrupt some time to react
XUartPs_WriteReg(STDIN_BASEADDRESS, XUARTPS_RXWM_OFFSET, 62); // XUartPs_WriteReg(STDIN_BASEADDRESS, XUARTPS_RXWM_OFFSET, 62);
// Setting the rx timeout to n*4 -1 bits // // Setting the rx timeout to n*4 -1 bits
XUartPs_WriteReg(STDIN_BASEADDRESS, XUARTPS_RXTOUT_OFFSET, 50); // XUartPs_WriteReg(STDIN_BASEADDRESS, XUARTPS_RXTOUT_OFFSET, 50);
// enable UART Interrupts // // enable UART Interrupts
u32 mask = XUARTPS_IXR_RTRIG | XUARTPS_IXR_RXOVR | XUARTPS_IXR_RXFULL | // u32 mask = XUARTPS_IXR_RTRIG | XUARTPS_IXR_RXOVR | XUARTPS_IXR_RXFULL |
XUARTPS_IXR_TOUT; // XUARTPS_IXR_TOUT;
/* Write the mask to the IER Register */ // /* Write the mask to the IER Register */
XUartPs_WriteReg(STDIN_BASEADDRESS, XUARTPS_IER_OFFSET, mask); // XUartPs_WriteReg(STDIN_BASEADDRESS, XUARTPS_IER_OFFSET, mask);
/* Write the inverse of the Mask to the IDR register */ // /* Write the inverse of the Mask to the IDR register */
XUartPs_WriteReg(STDIN_BASEADDRESS, XUARTPS_IDR_OFFSET, (~mask)); // XUartPs_WriteReg(STDIN_BASEADDRESS, XUARTPS_IDR_OFFSET, (~mask));
/* Enable the interrupt for the UART1 in the interrupt controller. */ // /* Enable the interrupt for the UART1 in the interrupt controller. */
XScuGic_Enable(&xInterruptController, STDIN_INT_NR); // XScuGic_Enable(&xInterruptController, STDIN_INT_NR);
// Start lwip task // // Start lwip task
xTaskCreateStatic( // xTaskCreateStatic(
lwip_main, /* The function that implements the task. */ // lwip_main, /* The function that implements the task. */
"lwip", /* The text name assigned to the task - for debug // "lwip", /* The text name assigned to the task - for debug
only as it is not used by the kernel. */ // only as it is not used by the kernel. */
stackSizeWords, /* The size of the stack to allocate to the task. */ // stackSizeWords, /* The size of the stack to allocate to the task. */
NULL, /* The parameter passed to the task - not used in this // NULL, /* The parameter passed to the task - not used in this
simple case. */ // simple case. */
4, /* The priority assigned to the task. */ // 4, /* The priority assigned to the task. */
xStack, &xTaskBuffer); // xStack, &xTaskBuffer);
} // }

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 MiB