Skip to content

Commit

Permalink
Add: rough improvement on event driven
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonyang-ee committed Jul 3, 2023
1 parent 858ba3e commit 905d0d8
Show file tree
Hide file tree
Showing 8 changed files with 195 additions and 59 deletions.
6 changes: 5 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@
"runToEntryPoint": "main",
"svdFile": "STM32G4_svd_V2.0/STM32G431xx.svd",
"v1": false,
"showDevDebugOutput": "both"
"showDevDebugOutput": "both",
"liveWatch": {
"enabled": false,
"samplesPerSecond": 4
}
}
]
}
8 changes: 4 additions & 4 deletions Application/Inc/FreeRTOSConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
#define configTICK_RATE_HZ ((TickType_t)1000)
#define configMAX_PRIORITIES ( 7 )
#define configMINIMAL_STACK_SIZE ((uint16_t)64)
#define configTOTAL_HEAP_SIZE ((size_t)9000)
#define configTOTAL_HEAP_SIZE ((size_t)7500)
#define configMAX_TASK_NAME_LEN ( 16 )
#define configUSE_16_BIT_TICKS 0
#define configUSE_MUTEXES 1
Expand Down Expand Up @@ -140,9 +140,9 @@ standard names. */
#define configUSE_TRACE_FACILITY 1 // Show RTOS task ID stats
#define configUSE_STATS_FORMATTING_FUNCTIONS 1 // Enable using vTaskList()
#define configRECORD_STACK_HIGH_ADDRESS 1 // Show RTOS stack stats
// #define configGENERATE_RUN_TIME_STATS 1
// #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() MX_TIM7_Init()
// #define portGET_RUN_TIME_COUNTER_VALUE() htim7.Instance->CNT
#define configGENERATE_RUN_TIME_STATS 1
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() MX_TIM7_Init()
#define portGET_RUN_TIME_COUNTER_VALUE() htim7.Instance->CNT

/* NOTE:
Add Those to MX_TIM7_Init()
Expand Down
3 changes: 2 additions & 1 deletion Application/Inc/Instances.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ extern Flash flash;
extern CustomDAC motor_dac;
extern CustomADC sensor_adc;

extern sml::sm<MotorState> motor_sm;
extern sml::sm<StreamState> stream_sm;
extern sml::sm<MainState> main_sm;

#endif /* APPLICATION_INC_INSTANCES */
124 changes: 109 additions & 15 deletions Application/Inc/State.hpp
Original file line number Diff line number Diff line change
@@ -1,35 +1,129 @@
#ifndef APPLICATION_INC_STATE
#define APPLICATION_INC_STATE

#include "DAC.hpp"
#include "sml.hpp"

#include "DAC.hpp"

namespace sml = boost::sml;

// State
struct begin {};
struct on;
struct off;
struct breathing;

struct single_on {};
struct shutting_down {};

// Events
struct start {};
struct stop {};
struct breath {};
struct oneshot {};
struct next {};
struct finish {};
struct shutdown {};
struct toggle {};
struct sub_endded {};

struct Idle {
auto operator()() {
using namespace sml;

// State Machine Actions
auto act_delay = []() { vTaskDelay(1000); };
auto act_start = [](Thread *thread) {
thread->idling_start();
vTaskResume(thread->idling_handle);
};
auto act_shutdown = [](Thread *thread) {
vTaskSuspend(thread->idling_handle);
};

// State Machine Logics
// clang-format off
return make_transition_table(
*state<begin> / act_start = state<on>,
state<on> + event<finish> / act_delay = state<on>,
state<on> + event<shutdown> / act_shutdown = state<shutting_down>,
state<shutting_down> / process(sub_endded{}) = X
);
// clang-format on
}
};

struct DACState {
auto operator()() {
using namespace sml;

auto act_delay = []() { vTaskDelay(1000); };
auto act_start = [](Thread *thread) {
thread->constant_run_start();
vTaskResume(thread->constant_run_handle);
};
auto act_shutdown = [](Thread *thread) {
thread->constant_run_shutdown();
vTaskSuspend(thread->constant_run_handle);
};

// State Machine Logics
// clang-format off
return make_transition_table(
*state<begin> / act_start = state<on>,
state<on> + event<finish> / act_delay = state<on>,
state<on> + event<shutdown> / act_shutdown = state<shutting_down>,
state<shutting_down> / process(sub_endded{}) = X,
state<on> + event<toggle> / act_shutdown = state<off>,
state<off> + event<toggle> = state<begin>
);
// clang-format on
}
};

struct MainState {
auto operator()() {
using namespace sml;

auto act_start = [](Thread thread) {};
auto act_shutdown = [](Thread thread) {};

// State Machine Logics
// clang-format off
return make_transition_table(
*state<begin> + event<start> / act_idle = state<Idle>,
state<Idle> + event<next> / process(shutdown{}),
state<Idle> + event<sub_endded> / act_constant = state<Constant>,
state<Constant> + event<next> / process(shutdown{}),
state<Constant> + event<sub_endded> / act_breathing = state<Breathing>,
state<Breathing> + event<next> / process(shutdown{}),
state<Breathing> + event<sub_endded> / act_idle = state<Idle>
);
// clang-format on
}
};

struct StreamState {
auto operator()() {
using namespace sml;

struct MotorState {
auto operator()() {
using namespace sml;

auto act_start = [](CustomDAC *motor_dac, Thread *thread) { };
// State Machine Actions
auto act_on = [](Thread *thread) {
xTaskResumeFromISR(thread->telemetry_human_handle);
};
auto act_off = [](Thread *thread) {
vTaskSuspend(thread->telemetry_human_handle);
};
auto act_delay = [](Thread *thread) { vTaskDelay(thread->m_stream_freq); };

// State Machine Logics
// clang-format off
return make_transition_table(
*state<off> + event<start> / act_start = state<on>,
state<off> + event<breath> = state<breathing>,
state<on> + event<stop> = state<off>,
state<breathing> + event<stop> = state<off>
*state<off> + event<start> / act_on = state<on>,
state<off> + event<oneshot> / act_on = state<single_on>,
state<single_on> + event<finish> / act_off = state<off>,
state<on> + event<finish> / act_delay = state<on>,
state<on> + event<stop> / act_off = state<off>
);
}
// clang-format on
}
};

#endif /* APPLICATION_INC_STATE */
#endif /* APPLICATION_INC_STATE */
7 changes: 7 additions & 0 deletions Application/Inc/Thread.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ class Thread {
TaskHandle_t parse_handle;
void parse();

TaskHandle_t telemetry_human_handle;
void telemetry_human();

TaskHandle_t init_handle;
void init();

Expand All @@ -27,6 +30,10 @@ class Thread {

TaskHandle_t serial_send_handle;
void serial_send();


// Settings
uint16_t m_stream_freq{500};
};

#endif /* APPLICATION_INC_THREAD */
32 changes: 21 additions & 11 deletions Application/Src/CLI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,9 @@ int32_t CLI::cmd_motor(int32_t argc, char** argv) {
} else if (!strcmp(argv[1], "breath")) {
motor_dac.breath();
} else if (!strcmp(argv[1], "stream_on")) {
xTaskResumeFromISR(thread.utilities_handle);
xTaskResumeFromISR(thread.utilities_handle);
} else if (!strcmp(argv[1], "stream_off")) {
vTaskSuspend(thread.utilities_handle);
vTaskSuspend(thread.utilities_handle);
} else {
serialCOM.sendString("Unknown Command\n");
}
Expand All @@ -155,15 +155,25 @@ int32_t CLI::cmd_motor(int32_t argc, char** argv) {
}

int32_t CLI::cmd_show(int32_t argc, char** argv) {
serialCOM.sendString("LED level: ");
serialCOM.sendNumber(led_user.getLevel());
serialCOM.sendString("\nLED scale: ");
serialCOM.sendNumber(led_user.getScale());
serialCOM.sendString("\nDAC Target Value: ");
serialCOM.sendNumber(motor_dac.getLevel());
serialCOM.sendString("\nADC Sensing Value: ");
serialCOM.sendNumber(sensor_adc.getVolt());
serialCOM.sendLn();
// Detailed Menu
const char* help_text =
"\nShow Telemetry:\n"
" one \tShow Telemetry Once\n"
" all \tStream All Telemetry\n"
" blower \tStream Blower Telemetry\n"
" off \tStop Stream\n\n";

if (!strcmp(argv[1], "help")) {
serialCOM.sendString(help_text);
} else if (!strcmp(argv[1], "all")) {
stream_sm.process_event(start{});
} else if (!strcmp(argv[1], "off")) {
stream_sm.process_event(stop{});
} else if (!strcmp(argv[1], "one")) {
stream_sm.process_event(oneshot{});
} else {
serialCOM.sendString("Unknown Command\n");
}
return 0;
}

Expand Down
65 changes: 42 additions & 23 deletions Application/Src/Thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,43 +9,38 @@ Thread::Thread() {
// auto _task = [](void *arg) { static_cast<Thread *>(arg)->(); };
// xTaskCreate(_task, "", 512, this, 2, &_Handle);

auto t1 = [](void *arg) { static_cast<Thread *>(arg)->parse(); };
xTaskCreate(t1, "cli parsing", 512, this, 2, &parse_handle);

auto t2 = [](void *arg) { static_cast<Thread *>(arg)->init(); };
xTaskCreate(t2, "system init", 256, this, 6, &init_handle);
auto t1 = [](void *arg) { static_cast<Thread *>(arg)->telemetry_human(); };
xTaskCreate(t1, "telemetry_human", 128, this, 1, &telemetry_human_handle);
vTaskSuspend(telemetry_human_handle);

auto t3 = [](void *arg) { static_cast<Thread *>(arg)->utilities(); };
xTaskCreate(t3, "utilities", 128, this, 1, &utilities_handle);

auto a2 = [](void *arg) { static_cast<Thread *>(arg)->app_dac(); };
xTaskCreate(a2, "dac + adc", 128, this, 0, &app_dac_handle);
xTaskCreate(a2, "dac + adc", 64, this, 0, &app_dac_handle);

auto s0 = [](void *arg) { static_cast<Thread *>(arg)->init(); };
xTaskCreate(s0, "system init", 256, this, 6, &init_handle);

auto s1 = [](void *arg) { static_cast<Thread *>(arg)->schedule_20Hz(); };
xTaskCreate(s1, "schedule 20Hz", 64, this, 5, &schedule_20Hz_handle);

auto s2 = [](void *arg) { static_cast<Thread *>(arg)->serial_send(); };
xTaskCreate(s2, "serial send out", 128, this, 0, &serial_send_handle);
auto s11 = [](void *arg) { static_cast<Thread *>(arg)->serial_send(); };
xTaskCreate(s11, "serial send out", 64, this, 0, &serial_send_handle);

auto s12 = [](void *arg) { static_cast<Thread *>(arg)->parse(); };
xTaskCreate(s12, "cli parsing", 512, this, 2, &parse_handle);
}

Thread::~Thread() {}

void Thread::parse() {
while (1) {
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
cli.parse();
}
}

void Thread::init() {
while (1) {
cli.init();
motor_dac.init();
flash.Load();
vTaskSuspend(utilities_handle);
vTaskSuspend(NULL);
}
}
/*---------------------------------------------------------------------------

Applications

---------------------------------------------------------------------------*/


void Thread::utilities() {
while (1) {
Expand All @@ -67,6 +62,23 @@ void Thread::app_dac() {
}
}


/*---------------------------------------------------------------------------

System initialization and periodic update

---------------------------------------------------------------------------*/

void Thread::init() {
while (1) {
cli.init();
motor_dac.init();
flash.Load();
vTaskSuspend(utilities_handle);
vTaskSuspend(NULL);
}
}

void Thread::schedule_20Hz() {
while (1) {
led_user.scheduler();
Expand All @@ -78,4 +90,11 @@ void Thread::serial_send() {
ulTaskNotifyTake(pdTRUE, 300);
serialCOM.sendOut();
}
}

void Thread::parse() {
while (1) {
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
cli.parse();
}
}
9 changes: 5 additions & 4 deletions Application/Src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ Flash flash{};
CustomDAC motor_dac{};
CustomADC sensor_adc{};

sml::sm<MotorState> motor_sm{&motor_dac, &thread};
sml::sm<StreamState> stream_sm{&thread};
sml::sm<MainState> main_sm{&thread};

/**
* @brief The application entry point.
Expand Down Expand Up @@ -64,12 +65,12 @@ void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) {
if (huart->Instance == USART2) {
// Start the DMA again before jumping thread
HAL_UARTEx_ReceiveToIdle_IT(&huart2, serialCOM.m_rx_data, UART_BUFFER);

// Parse Command
cli.setSize(Size);
vTaskNotifyGiveFromISR(thread.parse_handle, NULL);

// Start the DMA again
HAL_UARTEx_ReceiveToIdle_IT(&huart2, serialCOM.m_rx_data, UART_BUFFER);
}
}

Expand Down

0 comments on commit 905d0d8

Please sign in to comment.