Skip to content

Commit

Permalink
Distribute the start tag within the federation (#81)
Browse files Browse the repository at this point in the history
* Update proto messages and have a  start_tag_signal that is handled and used to distribute start tags

* Fix examples

* Refactor a little

* Formatting

* Only schedule timers and startup after start tag has been acquired

* Remove unused proto messages

* Fix up tests

* Correctly initialize start_time

* Some refactoring

* Formatting

* Fix pico

* Try porting tcp_channel_test to new FederateMessage

* Final portings
  • Loading branch information
erlingrj authored Oct 25, 2024
1 parent 94366f8 commit 6eb74b1
Show file tree
Hide file tree
Showing 38 changed files with 375 additions and 159 deletions.
3 changes: 2 additions & 1 deletion .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ BasedOnStyle: LLVM
Language: Cpp
IndentWidth: 2
ColumnLimit: 120
AllowShortIfStatementsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: false
SortIncludes: false
7 changes: 2 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
.PHONY: clean test coverage asan format format-check ci lf-test lib proto examples

test: unit-test lf-test examples

test: unit-test examples

# Generate protobuf code
proto:
python external/nanopb/generator/nanopb_generator.py -Iexternal/nanopb/generator/proto/ -Iexternal/proto -L'#include "nanopb/%s"' -Dexternal/proto message.proto
python3 external/nanopb/generator/nanopb_generator.py -Iexternal/nanopb/generator/proto/ -Iexternal/proto -L'#include "nanopb/%s"' -Dexternal/proto message.proto

# Build reactor-uc as a static library
lib:
cmake -Bbuild
cmake --build build
make -C build


# Build examples
examples:
cmake -Bbuild -DBUILD_EXAMPLES=ON .
cmake --build build
make examples -C build


# Build and run the unit tests
unit-test:
cmake -Bbuild -DBUILD_TESTS=ON
Expand Down
5 changes: 2 additions & 3 deletions examples/pico/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ project(reactor-uc-pico)
pico_sdk_init()
add_subdirectory(../../ reactor-uc)

add_executable(hello_world
timer_ex.c
add_executable(blinky blinky.c
)

target_link_libraries(hello_world PRIVATE reactor-uc)
target_link_libraries(blinky PRIVATE reactor-uc)
87 changes: 87 additions & 0 deletions examples/pico/blinky.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#include "pico/stdlib.h"
#include "reactor-uc/reactor-uc.h"

#ifdef CYW43_WL_GPIO_LED_PIN
#include "pico/cyw43_arch.h"
#endif

// Perform initialisation
int pico_led_init(void) {
#if defined(PICO_DEFAULT_LED_PIN)
// A device like Pico that uses a GPIO for the LED will define PICO_DEFAULT_LED_PIN
// so we can use normal GPIO functionality to turn the led on and off
gpio_init(PICO_DEFAULT_LED_PIN);
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
return PICO_OK;
#elif defined(CYW43_WL_GPIO_LED_PIN)
// For Pico W devices we need to initialise the driver etc
return cyw43_arch_init();
#else
#error "No LED pin defined for Pico"
#endif
}

// Turn the led on or off
void pico_set_led(bool led_on) {
#if defined(PICO_DEFAULT_LED_PIN)
// Just set the GPIO on or off
gpio_put(PICO_DEFAULT_LED_PIN, led_on);
#elif defined(CYW43_WL_GPIO_LED_PIN)
// Ask the wifi "driver" to set the GPIO on or off
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, led_on);
#else
#error "No LED pin defined for Pico"
#endif
}

typedef struct {
Timer super;
Reaction *effects[0];
} MyTimer;

typedef struct {
Reaction super;
} MyReaction;

struct MyReactor {
Reactor super;
MyReaction my_reaction;
MyTimer timer;
bool led_on;
Reaction *_reactions[1];
Trigger *_triggers[1];
};

void timer_handler(Reaction *_self) {
struct MyReactor *self = (struct MyReactor *)_self->parent;
Environment *env = self->super.env;
printf("Hello World @ %lld\n", env->get_elapsed_logical_time(env));
pico_set_led(!self->led_on);
self->led_on = !self->led_on;
}

void MyReaction_ctor(MyReaction *self, Reactor *parent) {
Reaction_ctor(&self->super, parent, timer_handler, NULL, 0, 0);
}

void MyReactor_ctor(struct MyReactor *self, Environment *env) {
self->_reactions[0] = (Reaction *)&self->my_reaction;
self->_triggers[0] = (Trigger *)&self->timer;
Reactor_ctor(&self->super, "MyReactor", env, NULL, NULL, 0, self->_reactions, 1, self->_triggers, 1);
MyReaction_ctor(&self->my_reaction, &self->super);
Timer_ctor(&self->timer.super, &self->super, MSEC(0), MSEC(100), self->timer.effects, 1);
TIMER_REGISTER_EFFECT(self->timer, self->my_reaction);
self->led_on = false;
}

struct MyReactor my_reactor;
Environment env;
int main() {
Environment_ctor(&env, (Reactor *)&my_reactor);
pico_led_init();
env.scheduler.duration = FOREVER;
MyReactor_ctor(&my_reactor, &env);
env.assemble(&env);
env.start(&env);
return 0;
}
47 changes: 0 additions & 47 deletions examples/pico/timer_ex.c

This file was deleted.

2 changes: 1 addition & 1 deletion examples/posix/testing_fed_conn_receiver.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ void MainRecv_ctor(MainRecv *self, Environment *env) {
Reactor_ctor(&self->super, "MainRecv", env, NULL, self->_children, 1, NULL, 0, NULL, 0);
}

ENTRY_POINT_FEDERATED(MainRecv, SEC(1), true, true, 1)
ENTRY_POINT_FEDERATED(MainRecv, SEC(1), true, true, 1, false)

int main() {
lf_start();
Expand Down
2 changes: 1 addition & 1 deletion examples/posix/testing_fed_conn_sender.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ void MainSender_ctor(MainSender *self, Environment *env) {
CONN_REGISTER_UPSTREAM(self->bundle.conn, self->sender.out);
Reactor_ctor(&self->super, "MainSender", env, NULL, self->_children, 1, NULL, 0, NULL, 0);
}
ENTRY_POINT_FEDERATED(MainSender, SEC(1), true, false, 1)
ENTRY_POINT_FEDERATED(MainSender, SEC(1), true, false, 1, true)

int main() {
lf_start();
Expand Down
2 changes: 1 addition & 1 deletion examples/posix/timer_ex.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ int main() {
struct MyReactor my_reactor;
Environment env;
Environment_ctor(&env, (Reactor *)&my_reactor);
env.scheduler.set_timeout(&env.scheduler, SEC(1));
env.scheduler.duration = MSEC(100);
MyReactor_ctor(&my_reactor, &env);
env.assemble(&env);
env.start(&env);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ void MainRecv_ctor(MainRecv *self, Environment *env) {
self->_bundles[0] = &self->bundle.super;
}

ENTRY_POINT_FEDERATED(MainRecv, FOREVER, true, true, 1)
ENTRY_POINT_FEDERATED(MainRecv, FOREVER, true, true, 1, false)

int main() {
setup_led();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ void MainRecv_ctor(MainRecv *self, Environment *env) {
self->_bundles[0] = &self->bundle.super;
}

ENTRY_POINT_FEDERATED(MainRecv, FOREVER, true, true, 1)
ENTRY_POINT_FEDERATED(MainRecv, FOREVER, true, true, 1, false)

int main() {
setup_led();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ void MainSender_ctor(MainSender *self, Environment *env) {
self->_bundles[1] = &self->bundle2.super;
}

ENTRY_POINT_FEDERATED(MainSender, FOREVER, true, true, 2)
ENTRY_POINT_FEDERATED(MainSender, FOREVER, true, true, 2, true)

int main() {
setup_button();
Expand Down
8 changes: 8 additions & 0 deletions external/proto/message.pb.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,15 @@
PB_BIND(Tag, Tag, AUTO)


PB_BIND(StartTagSignal, StartTagSignal, AUTO)


PB_BIND(TaggedMessage, TaggedMessage, 2)


PB_BIND(FederateMessage, FederateMessage, 2)





61 changes: 60 additions & 1 deletion external/proto/message.pb.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,74 @@
#error Regenerate this file with the current version of nanopb generator.
#endif

/* Enum definitions */
typedef enum _MessageType {
MessageType_TAGGED_MESSAGE = 1,
MessageType_START_TAG_SIGNAL = 2
} MessageType;

/* Struct definitions */
typedef struct _Tag {
int64_t time;
uint32_t microstep;
} Tag;

typedef struct _StartTagSignal {
Tag tag;
} StartTagSignal;

typedef PB_BYTES_ARRAY_T(832) TaggedMessage_payload_t;
typedef struct _TaggedMessage {
Tag tag;
int32_t conn_id;
TaggedMessage_payload_t payload;
} TaggedMessage;

typedef struct _FederateMessage {
MessageType type;
pb_size_t which_message;
union {
TaggedMessage tagged_message;
StartTagSignal start_tag_signal;
} message;
} FederateMessage;


#ifdef __cplusplus
extern "C" {
#endif

/* Helper constants for enums */
#define _MessageType_MIN MessageType_TAGGED_MESSAGE
#define _MessageType_MAX MessageType_START_TAG_SIGNAL
#define _MessageType_ARRAYSIZE ((MessageType)(MessageType_START_TAG_SIGNAL+1))




#define FederateMessage_type_ENUMTYPE MessageType


/* Initializer values for message structs */
#define Tag_init_default {0, 0}
#define StartTagSignal_init_default {Tag_init_default}
#define TaggedMessage_init_default {Tag_init_default, 0, {0, {0}}}
#define FederateMessage_init_default {_MessageType_MIN, 0, {TaggedMessage_init_default}}
#define Tag_init_zero {0, 0}
#define StartTagSignal_init_zero {Tag_init_zero}
#define TaggedMessage_init_zero {Tag_init_zero, 0, {0, {0}}}
#define FederateMessage_init_zero {_MessageType_MIN, 0, {TaggedMessage_init_zero}}

/* Field tags (for use in manual encoding/decoding) */
#define Tag_time_tag 1
#define Tag_microstep_tag 2
#define StartTagSignal_tag_tag 1
#define TaggedMessage_tag_tag 1
#define TaggedMessage_conn_id_tag 2
#define TaggedMessage_payload_tag 3
#define FederateMessage_type_tag 1
#define FederateMessage_tagged_message_tag 2
#define FederateMessage_start_tag_signal_tag 3

/* Struct field encoding specification for nanopb */
#define Tag_FIELDLIST(X, a) \
Expand All @@ -47,6 +85,12 @@ X(a, STATIC, REQUIRED, UINT32, microstep, 2)
#define Tag_CALLBACK NULL
#define Tag_DEFAULT NULL

#define StartTagSignal_FIELDLIST(X, a) \
X(a, STATIC, REQUIRED, MESSAGE, tag, 1)
#define StartTagSignal_CALLBACK NULL
#define StartTagSignal_DEFAULT NULL
#define StartTagSignal_tag_MSGTYPE Tag

#define TaggedMessage_FIELDLIST(X, a) \
X(a, STATIC, REQUIRED, MESSAGE, tag, 1) \
X(a, STATIC, REQUIRED, INT32, conn_id, 2) \
Expand All @@ -55,15 +99,30 @@ X(a, STATIC, REQUIRED, BYTES, payload, 3)
#define TaggedMessage_DEFAULT NULL
#define TaggedMessage_tag_MSGTYPE Tag

#define FederateMessage_FIELDLIST(X, a) \
X(a, STATIC, REQUIRED, UENUM, type, 1) \
X(a, STATIC, ONEOF, MESSAGE, (message,tagged_message,message.tagged_message), 2) \
X(a, STATIC, ONEOF, MESSAGE, (message,start_tag_signal,message.start_tag_signal), 3)
#define FederateMessage_CALLBACK NULL
#define FederateMessage_DEFAULT (const pb_byte_t*)"\x08\x01\x00"
#define FederateMessage_message_tagged_message_MSGTYPE TaggedMessage
#define FederateMessage_message_start_tag_signal_MSGTYPE StartTagSignal

extern const pb_msgdesc_t Tag_msg;
extern const pb_msgdesc_t StartTagSignal_msg;
extern const pb_msgdesc_t TaggedMessage_msg;
extern const pb_msgdesc_t FederateMessage_msg;

/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
#define Tag_fields &Tag_msg
#define StartTagSignal_fields &StartTagSignal_msg
#define TaggedMessage_fields &TaggedMessage_msg
#define FederateMessage_fields &FederateMessage_msg

/* Maximum encoded size of messages (where known) */
#define MESSAGE_PB_H_MAX_SIZE TaggedMessage_size
#define FederateMessage_size 870
#define MESSAGE_PB_H_MAX_SIZE FederateMessage_size
#define StartTagSignal_size 19
#define Tag_size 17
#define TaggedMessage_size 865

Expand Down
Loading

0 comments on commit 6eb74b1

Please sign in to comment.