Skip to content

Commit

Permalink
Node: Support for shell commands & Modules (#70)
Browse files Browse the repository at this point in the history
  • Loading branch information
AnnsAnns committed May 13, 2024
2 parents 42bde23 + 93843c6 commit 8dcc9d2
Show file tree
Hide file tree
Showing 12 changed files with 197 additions and 16 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@
"lcd.h": "c",
"ili9341.h": "c",
"ili9341_params.h": "c",
"lvgl_riot.h": "c"
"lvgl_riot.h": "c",
"shell.h": "c"
},
"[shellscript][c][cpp]": {
"editor.tabSize": 4,
Expand Down
11 changes: 8 additions & 3 deletions node/code/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,19 @@ DEVELHELP ?= 1
FEATURES_REQUIRED += cpp
FEATURES_REQUIRED += libstdcpp

#Hardware specific configs
# Internal Modules
EXTERNAL_MODULE_DIRS += modules
USEMODULE += external_module

# External modules
USEMODULE += cpp11-compat
USEMODULE += ili9341
USEMODULE += ztimer
USEMODULE += ztimer_msec
USEMODULE += shell

# Lvgl Related Modules
DISABLE_MODULE += test_utils_interactive_sync

USEPKG += lvgl
USEMODULE += lvgl_contrib
USEMODULE += lvgl_extra_widget_chart
Expand All @@ -35,7 +40,7 @@ SHOULD_RUN_KCONFIG ?=
# Include "inc" directory for the header files
INCLUDES += -I$(CURDIR)/inc

CXXEXFLAGS +=
CXXEXFLAGS += -std=c++17 -Wall -Wextra

include $(RIOTBASE)/Makefile.include

Expand Down
3 changes: 2 additions & 1 deletion node/code/dispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

Dispatcher::Dispatcher() {
this->subscriptions = list<Subscription>();
this->setRespectTerminate(false); // We need to send the other classes a terminate event
}

void Dispatcher::subscribe(list<EVENTS> events, kernel_pid_t pid) {
Expand All @@ -16,7 +17,7 @@ void Dispatcher::subscribe(list<EVENTS> events, kernel_pid_t pid) {
void Dispatcher::handleEvent(msg_t *event) {
for (Subscription sub : this->subscriptions) {
for (EVENTS e : sub.event) {
if (e == event->type) {
if (e == event->type || e == EVENTS::WILDCARD || event->type == EVENTS::TERMINATE) {
cout << "👀 PID: " << sub.pid << " was interested in event " << event->type << " notifying them" << endl;

msg_t msg;
Expand Down
14 changes: 12 additions & 2 deletions node/code/inc/dispatch_handler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class DispatchHandler {
msg_t rcv_queue[QUEUE_SIZE];
char internal_thread_stack [THREAD_STACKSIZE_MAIN];
kernel_pid_t internal_thread_pid;
bool respect_terminate = true;

public:
/**
Expand All @@ -37,11 +38,15 @@ class DispatchHandler {
*/
DispatchHandler() { }

void setRespectTerminate(bool respect_terminate) {
this->respect_terminate = respect_terminate;
}

/**
* @brief Send an event to the dispatcher.
* @param event The event to send.
*/
void sendEvent(msg_t *event) {
static void sendEvent(msg_t *event) {
if (DISPATCHER_PID == -1) {
cout << "Dispatcher PID not set yet!" << endl;
return;
Expand Down Expand Up @@ -76,7 +81,12 @@ class DispatchHandler {
msg_receive(&message);

if (message.type == EVENTS::TERMINATE) {
cout << "Received TERMINATE event, exiting..." << endl;
cout << "💣 Received TERMINATE event, exiting..." << endl;
if (!this->respect_terminate) {
cout << "😎 Not respecting terminate, will handle event anyways" << endl;
this->handleEvent(&message);
cout << "🌃 Handled Terminate Event, now going offline fr ..." << endl;
}
return;
}

Expand Down
55 changes: 55 additions & 0 deletions node/code/inc/shell_commands.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#pragma once

#include "shell.h"
#include <stdio.h>

static kernel_pid_t DISPATCHER_THREAD_ID;

static int echo_command(int argc, char **argv)
{
/* check that the command is called correctly */
if (argc != 2) {
puts("usage: echo <message>");
puts("Note: to echo multiple words wrap the message in \"\"");
return 1;
}

/* print the first argument */
puts(argv[1]);

return 0;
}

/**
* @brief Sends an event to the dispatcher.
* @example send_event 1
*/
static int send_event(int argc, char **argv) {
if (argc != 2) {
puts("usage: send_event <event>");
return 1;
}

msg_t message;
message.type = atoi(argv[1]);

msg_try_send(&message, DISPATCHER_THREAD_ID);

return 0;
}

const shell_command_t SHELL_COMMANDS[] = {
{ "echo", "Prints the message to the console", echo_command },
{ "send_event", "Sends an event to the dispatcher. send_event 1", send_event },
{ NULL, NULL, NULL }
};

void shell_loop(void) {
/* buffer to read commands */
char line_buf[SHELL_DEFAULT_BUFSIZE];

cout << "Starting shell loop" << endl;

/* run the shell, this will block the thread waiting for incoming commands */
shell_run_forever(SHELL_COMMANDS, line_buf, SHELL_DEFAULT_BUFSIZE);
}
23 changes: 15 additions & 8 deletions node/code/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,16 @@
#include "architecture.h"
#include "dispatch_handler.hpp"
#include "dispatcher.hpp"
//#include "init_display.h"
#include "shell.h"
// #include "init_display.h"
#include "init_lvgl.h"
#include "ping.hpp"
#include "pong.hpp"
#include "riot/thread.hpp"
#include "shell_commands.hpp"

// Example Module Import
#include "external_module.h"

using namespace std;
using namespace riot;
Expand All @@ -24,10 +29,12 @@ kernel_pid_t DISPATCHER_PID;
int main() {
printf("\n************ We are in C++ 😎 ***********\n");
printf("\n");
init_lvgl();

puts("{\"result\": \"PASS\"}");

// Show the example module function
cout << "Example Module Init: " << external_module_initialized << endl;

cout << "Sleeping for 5 seconds...\n" << endl;
riot::this_thread::sleep_for(chrono::seconds(5));
cout << "Done sleeping.\n" << endl;
Expand All @@ -37,6 +44,7 @@ int main() {
dispatcher->startInternalThread();

DISPATCHER_PID = dispatcher->getPID();
DISPATCHER_THREAD_ID = DISPATCHER_PID;

// Create the ping class
Ping *ping = new Ping();
Expand All @@ -50,14 +58,13 @@ int main() {
dispatcher->subscribe({EVENTS::PING}, ping->getPID());
dispatcher->subscribe({EVENTS::PONG}, pong->getPID());

cout << "Sending initial ping event" << endl;
msg_t message;
message.type = EVENTS::PING;
// cout << "Sending initial ping event" << endl;
// msg_t message;
// message.type = EVENTS::PING;

msg_try_send(&message, dispatcher->getPID());
// msg_try_send(&message, dispatcher->getPID());

while (true) {
}
shell_loop();

return 0;
}
1 change: 1 addition & 0 deletions node/code/modules/external_module/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include $(RIOTBASE)/Makefile.base
3 changes: 3 additions & 0 deletions node/code/modules/external_module/Makefile.dep
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
USEMODULE += random
# Set a different prng than the default
USEMODULE += prng_xorshift
3 changes: 3 additions & 0 deletions node/code/modules/external_module/Makefile.include
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Use an immediate variable to evaluate `MAKEFILE_LIST` now
USEMODULE_INCLUDES_external_module := $(LAST_MAKEFILEDIR)/include
USEMODULE_INCLUDES += $(USEMODULE_INCLUDES_external_module)
36 changes: 36 additions & 0 deletions node/code/modules/external_module/external_module.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (C) 2018 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/

/**
* @ingroup tests
* @{
*
* @file
* @brief Test the EXTERNAL_MODULE_DIRS feature
* @note Define a shared variable
*
* @author Gaëtan Harter <gaetan.harter@fu-berlin.de>
*
* @}
*/

#include "external_module.h"
#include "auto_init_priorities.h"
#include "auto_init_utils.h"

#define PRIO AUTO_INIT_PRIORITY_AFTER(AUTO_INIT_PRIO_MOD_RANDOM)

AUTO_INIT(auto_init_external_module, PRIO);

bool external_module_initialized = false;
char *external_module_message = "Linking worked";

void auto_init_external_module(void)
{
external_module_initialized = true;
}
50 changes: 50 additions & 0 deletions node/code/modules/external_module/include/external_module.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (C) 2018 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/

/**
* @defgroup
* @ingroup
* @brief
* @{
*
* @file
* @brief
*
* @author Gaëtan Harter <gaetan.harter@fu-berlin.de>
*/
#ifndef EXTERNAL_MODULE_H
#define EXTERNAL_MODULE_H

#include <stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief true: this module hase been initialized
* false: this module has not been initialized
*/
extern bool external_module_initialized;

/**
* @brief A simple string message
*/
extern char *external_module_message;

/**
* @brief Auto-init function of this module to be called on system start up
*/
void auto_init_external_module(void);

#ifdef __cplusplus
}
#endif

/** @} */
#endif /* EXTERNAL_MODULE_H */
11 changes: 10 additions & 1 deletion node/code/tests/01-run.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,16 @@

def testfunc(child: pexpect.spawn):
child.expect("PASS")


# Test if the module is initialized correctly
child.expect("Example Module Init: 1")

# Test if the module is started correctly
child.expect("Starting shell loop")

# Test if shell commands work correctly
child.sendline("send_event 0")
child.expect("💣 Received TERMINATE event, exiting...")

if __name__ == "__main__":
sys.exit(run(testfunc))

0 comments on commit 8dcc9d2

Please sign in to comment.