Skip to content

Commit 6cba508

Browse files
Added Emergency Service
1 parent 141224e commit 6cba508

File tree

11 files changed

+215
-42
lines changed

11 files changed

+215
-42
lines changed

CMakeLists.txt

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
cmake_minimum_required(VERSION 3.22)
22

3+
34
set(CONFIG_DIR ${CMAKE_CURRENT_SOURCE_DIR}/cfg)
45
set(BOARD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/boards/XCORE)
56
# Set custom port path
67
set(XBOT_CUSTOM_PORT_PATH ${CMAKE_SOURCE_DIR}/portable)
78

89

9-
# Setup compiler settings
10-
set(CMAKE_CXX_STANDARD 20)
11-
set(CMAKE_CXX_STANDARD_REQUIRED ON)
12-
set(CMAKE_CXX_EXTENSIONS ON)
1310

1411

1512

@@ -24,16 +21,19 @@ include("cmake/gcc-arm-none-eabi.cmake")
2421
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)
2522

2623
# Enable CMake support for ASM and C languages
27-
enable_language(C ASM)
24+
enable_language(C CXX ASM)
2825

2926
# Core project settings
3027
project(${CMAKE_PROJECT_NAME})
3128
message("Build type: " ${CMAKE_BUILD_TYPE})
3229

3330
# Create an executable object type
3431
add_executable(${CMAKE_PROJECT_NAME})
35-
36-
32+
set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES
33+
CXX_STANDARD 17
34+
CXX_STANDARD_REQUIRED ON
35+
CXX_EXTENSIONS ON
36+
)
3737
# Add lib subdirectory
3838
add_subdirectory(ext)
3939

@@ -45,23 +45,16 @@ target_link_directories(${CMAKE_PROJECT_NAME} PRIVATE
4545
# Add sources to executable
4646
target_sources(${CMAKE_PROJECT_NAME} PRIVATE
4747
main.cpp
48-
src/globals.c
49-
src/globals.h
48+
src/globals.cpp
5049
src/heartbeat.c
51-
src/heartbeat.h
5250
src/id_eeprom.c
53-
src/id_eeprom.h
5451
src/boot_service_discovery.c
55-
src/boot_service_discovery.h
5652
src/status_led.c
57-
src/status_led.h
5853
src/services/imu_service/imu_service.cpp
59-
src/services/imu_service/imu_service.hpp
6054
src/services/power_service/power_service.cpp
61-
src/services/power_service/power_service.hpp
55+
src/services/emergency_service/emergency_service.cpp
6256
# BQ2567 driver
6357
src/drivers/bq_2576/bq_2576.cpp
64-
src/drivers/bq_2576/bq_2576.hpp
6558
# VESC driver
6659
src/drivers/vesc/buffer.cpp
6760
src/drivers/vesc/VescUart.cpp
@@ -84,10 +77,12 @@ target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC
8477
# Add user defined libraries
8578
ChibiOS
8679
LSM6DS3TR
80+
etl::etl
8781
)
8882

8983
target_add_service(${CMAKE_PROJECT_NAME} ImuService ${CMAKE_CURRENT_SOURCE_DIR}/services/imu_service.json)
9084
target_add_service(${CMAKE_PROJECT_NAME} PowerService ${CMAKE_CURRENT_SOURCE_DIR}/services/power_service.json)
85+
target_add_service(${CMAKE_PROJECT_NAME} EmergencyService ${CMAKE_CURRENT_SOURCE_DIR}/services/emergency_service.json)
9186

9287
set_target_properties(${CMAKE_PROJECT_NAME}
9388
PROPERTIES SUFFIX ".elf")

cfg/etl_profile.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#ifndef ETL_PROFILE_H
2+
#define ETL_PROFILE_H
3+
4+
#define ETL_NO_STL
5+
#endif

cmake/gcc-arm-none-eabi.cmake

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
set(CMAKE_SYSTEM_NAME Generic)
22
set(CMAKE_SYSTEM_PROCESSOR arm)
33

4-
set(CMAKE_C_COMPILER_FORCED TRUE)
5-
set(CMAKE_CXX_COMPILER_FORCED TRUE)
64
set(CMAKE_C_COMPILER_ID GNU)
75
set(CMAKE_CXX_COMPILER_ID GNU)
86

ext/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ add_subdirectory(xbot_framework)
77
target_link_libraries(xbot-service PUBLIC ChibiOS)
88
target_compile_definitions(xbot-service PUBLIC XBOT_ENABLE_STATIC_STACK)
99

10-
add_subdirectory(LSM6DS3TR-C-PID)
10+
add_subdirectory(LSM6DS3TR-C-PID)
11+
add_subdirectory(etl)

ext/etl/CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Include(FetchContent)
2+
3+
FetchContent_Declare(
4+
etl
5+
GIT_REPOSITORY https://github.com/ETLCPP/etl
6+
GIT_TAG 20.39.4
7+
)
8+
9+
FetchContent_MakeAvailable(etl)

main.cpp

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,25 @@
33
#include "hal.h"
44
// clang-format on
55

6+
#ifdef USE_SEGGER_SYSTEMVIEW
67
#include <SEGGER_RTT.h>
78
#include <SEGGER_RTT_streams.h>
9+
#endif
810
#include <boot_service_discovery.h>
9-
#include <chprintf.h>
1011
#include <drivers/vesc/VescUart.h>
11-
#include <globals.h>
1212
#include <heartbeat.h>
1313
#include <id_eeprom.h>
1414
#include <lwipthread.h>
1515
#include <status_led.h>
1616

17+
#include <globals.hpp>
1718
#include <xbot-service/Io.hpp>
1819
#include <xbot-service/portable/system.hpp>
1920

21+
#include "services/emergency_service/emergency_service.hpp"
2022
#include "services/imu_service/imu_service.hpp"
2123
#include "services/power_service/power_service.hpp"
24+
EmergencyService emergency_service{1};
2225
ImuService imu_service{4};
2326
PowerService power_service{5};
2427

@@ -27,14 +30,16 @@ static THD_WORKING_AREA(waTestThread, 500);
2730
static void test_thread(void *p) {
2831
static VescUart vesc_uart(&UARTD2);
2932
while (1) {
33+
#ifdef USE_SEGGER_SYSTEMVIEW
3034
SEGGER_SYSVIEW_Print("keepalive");
3135
vesc_uart.sendKeepalive();
3236
SEGGER_SYSVIEW_Print("request");
3337
vesc_uart.requestVescValues();
3438
SEGGER_SYSVIEW_Print("parse");
3539
vesc_uart.parseVescValues();
3640
SEGGER_SYSVIEW_Print("wait");
37-
chThdSleepMilliseconds(50);
41+
#endif
42+
chThdSleepMilliseconds(1000);
3843
}
3944
}
4045

@@ -98,11 +103,31 @@ int main(void) {
98103

99104
xbot::service::system::initSystem();
100105
xbot::service::Io::start();
106+
emergency_service.start();
101107
imu_service.start();
102108
power_service.start();
103109

104110
chThdCreateStatic(waTestThread, sizeof(waTestThread), NORMALPRIO, test_thread,
105111
NULL);
106112

113+
// Subscribe to global events and dispatch to our services
114+
event_listener_t event_listener;
115+
chEvtRegister(&mower_events, &event_listener, 1);
116+
while (1) {
117+
uint32_t event = chEvtWaitAnyTimeout(ALL_EVENTS, TIME_INFINITE);
118+
// event no 1 == "mower_events"
119+
if (event == 1) {
120+
// Get the flags provided by the event
121+
uint32_t flags = chEvtGetAndClearFlags(&event_listener);
122+
if (flags & MOWER_EVT_EMERGENCY_CHANGED) {
123+
// Get the new emergency value
124+
chMtxLock(&mower_status_mutex);
125+
uint32_t status_copy = mower_status;
126+
chMtxUnlock(&mower_status_mutex);
127+
// Notify services
128+
}
129+
}
130+
}
131+
107132
chThdSleep(TIME_INFINITE);
108133
}

src/globals.c renamed to src/globals.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,16 @@
22
// Created by clemens on 01.10.24.
33
//
44

5-
#include "globals.h"
5+
#include "globals.hpp"
6+
67
struct board_info board_info = {0};
78
struct carrier_board_info carrier_board_info = {0};
89

10+
EVENTSOURCE_DECL(mower_events);
11+
MUTEX_DECL(mower_status_mutex);
12+
// Start with emergency engaged
13+
uint32_t mower_status = MOWER_FLAG_EMERGENCY_LATCH;
14+
915
void InitGlobals() {
1016
ID_EEPROM_GetBoardInfo(&board_info);
1117
ID_EEPROM_GetCarrierBoardInfo(&carrier_board_info);

src/globals.h

Lines changed: 0 additions & 19 deletions
This file was deleted.

src/globals.hpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//
2+
// Created by clemens on 01.10.24.
3+
//
4+
5+
#ifndef GLOBALS_H
6+
#define GLOBALS_H
7+
8+
#include <id_eeprom.h>
9+
10+
#include "ch.h"
11+
// Event to notify threads whenever the emergency flags have changed
12+
static constexpr uint32_t MOWER_EVT_EMERGENCY_CHANGED = 1;
13+
14+
// Flag to track if there was an emergency which has not been reset
15+
static constexpr uint32_t MOWER_FLAG_EMERGENCY_LATCH = 1;
16+
// Flag to track if there is currently an emergency (this is updated by the
17+
// high-prio emergency task)
18+
static constexpr uint32_t MOWER_FLAG_EMERGENCY_ACTIVE = 2;
19+
20+
extern struct board_info board_info;
21+
extern struct carrier_board_info carrier_board_info;
22+
23+
// event source for mower events (e.g. emergency)
24+
extern event_source_t mower_events;
25+
extern mutex_t mower_status_mutex;
26+
extern uint32_t mower_status;
27+
28+
void InitGlobals();
29+
#endif // GLOBALS_H
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
//
2+
// Created by clemens on 26.07.24.
3+
//
4+
5+
#include "emergency_service.hpp"
6+
7+
#include "../../globals.hpp"
8+
9+
bool EmergencyService::Configure() {
10+
// No config needed
11+
return true;
12+
}
13+
void EmergencyService::OnStart() {
14+
emergency_reason = "Boot";
15+
// set the emergency and notify services
16+
chMtxLock(&mower_status_mutex);
17+
mower_status |= MOWER_FLAG_EMERGENCY_LATCH;
18+
chMtxUnlock(&mower_status_mutex);
19+
chEvtBroadcastFlags(&mower_events, MOWER_EVT_EMERGENCY_CHANGED);
20+
}
21+
22+
void EmergencyService::OnStop() {
23+
emergency_reason = "Stopped";
24+
// set the emergency and notify services
25+
chMtxLock(&mower_status_mutex);
26+
mower_status |= MOWER_FLAG_EMERGENCY_LATCH;
27+
chMtxUnlock(&mower_status_mutex);
28+
chEvtBroadcastFlags(&mower_events, MOWER_EVT_EMERGENCY_CHANGED);
29+
}
30+
void EmergencyService::OnCreate() {}
31+
32+
void EmergencyService::tick() {
33+
// Get the current emergency state
34+
chMtxLock(&mower_status_mutex);
35+
uint32_t status_copy = mower_status;
36+
chMtxUnlock(&mower_status_mutex);
37+
bool emergency_latch = (status_copy & MOWER_FLAG_EMERGENCY_LATCH) != 0;
38+
bool emergency_active = (status_copy & MOWER_FLAG_EMERGENCY_ACTIVE) != 0;
39+
// Check timeout, but only overwrite if no emergency is currently active
40+
// reasoning is that we want to keep the original reason and not overwrite
41+
// with "timeout"
42+
if (!emergency_latch &&
43+
chVTTimeElapsedSinceX(last_clear_emergency_message_) > TIME_S2I(1)) {
44+
emergency_reason = "Timeout";
45+
// set the emergency and notify services
46+
chMtxLock(&mower_status_mutex);
47+
mower_status |= MOWER_FLAG_EMERGENCY_LATCH;
48+
chMtxUnlock(&mower_status_mutex);
49+
chEvtBroadcastFlags(&mower_events, MOWER_EVT_EMERGENCY_CHANGED);
50+
// The last flags did not have emergency yet, so need to set it here as well
51+
emergency_latch = true;
52+
}
53+
54+
StartTransaction();
55+
SendEmergencyActive(emergency_active);
56+
57+
SendEmergencyLatch(emergency_latch);
58+
SendEmergencyReason(emergency_reason.c_str(), emergency_reason.length());
59+
CommitTransaction();
60+
}
61+
62+
bool EmergencyService::OnSetEmergencyChanged(const uint8_t& new_value) {
63+
if (new_value) {
64+
emergency_reason = "High Level Emergency";
65+
// set the emergency and notify services
66+
chMtxLock(&mower_status_mutex);
67+
mower_status |= MOWER_FLAG_EMERGENCY_LATCH;
68+
chMtxUnlock(&mower_status_mutex);
69+
chEvtBroadcastFlags(&mower_events, MOWER_EVT_EMERGENCY_CHANGED);
70+
} else {
71+
// Get the current emergency state
72+
chMtxLock(&mower_status_mutex);
73+
uint32_t status_copy = mower_status;
74+
chMtxUnlock(&mower_status_mutex);
75+
bool emergency_active = (status_copy & MOWER_FLAG_EMERGENCY_ACTIVE) != 0;
76+
77+
// want to reset emergency, but only do it, if no emergency exists right now
78+
if (!emergency_active) {
79+
// clear the emergency and notify services
80+
chMtxLock(&mower_status_mutex);
81+
mower_status &= ~MOWER_FLAG_EMERGENCY_LATCH;
82+
chMtxUnlock(&mower_status_mutex);
83+
chEvtBroadcastFlags(&mower_events, MOWER_EVT_EMERGENCY_CHANGED);
84+
emergency_reason = "None";
85+
last_clear_emergency_message_ = chVTGetSystemTime();
86+
}
87+
}
88+
return true;
89+
}

0 commit comments

Comments
 (0)