Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UARTChannel #191

Merged
merged 31 commits into from
Feb 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
45d4af0
uart channel
tanneberger Jan 5, 2025
266ba52
change includes of nanopb
tanneberger Jan 5, 2025
23e5954
adding UARTChannel implementation
tanneberger Jan 16, 2025
5223e8b
clean up
tanneberger Jan 16, 2025
b31bd3e
Sync and Async UART Implementation
tanneberger Jan 17, 2025
7a362f1
formatting with clang 19
tanneberger Jan 17, 2025
483ee51
adding uart device parameter
tanneberger Jan 22, 2025
c657fae
formatting
tanneberger Jan 22, 2025
b8d000c
feedback from erling
tanneberger Jan 22, 2025
beb4eec
properly renaming Coap Flag
tanneberger Jan 22, 2025
ae08f72
fix cod-gen
tanneberger Jan 22, 2025
acd82f9
renaming to UARTPollChannel
tanneberger Jan 23, 2025
64936b2
Set UART_CHANNEL_EXPECTED_CONNECT_DURATION to 0
erlingrj Jan 23, 2025
fc18a9e
Add break statement from poll loop
erlingrj Jan 23, 2025
e58f3d9
ADd LFC_GEN_COMPILE_DEFS to RIOT build
erlingrj Jan 23, 2025
c424944
updating constructor and protecting receive index
tanneberger Jan 24, 2025
2393ce1
clean
tanneberger Jan 24, 2025
abe53aa
adding abstraction for uart channel
tanneberger Jan 26, 2025
ab8b8cb
code-generation for UART devices and formatting
tanneberger Jan 27, 2025
2809b1b
formatting
tanneberger Jan 27, 2025
4627e84
fixing code gen
tanneberger Jan 27, 2025
8f9246d
adding missing function
tanneberger Jan 28, 2025
a2cbf52
add test for UARTChannel
tanneberger Feb 5, 2025
e894354
formatting
tanneberger Feb 5, 2025
9ca4e4c
Fix riot tests and examples
LasseRosenow Feb 6, 2025
ef8a24c
sync->polled
erlingrj Feb 6, 2025
164206e
Merge branch 'main' into uart
erlingrj Feb 6, 2025
f7670d0
UART -> Uart
erlingrj Feb 6, 2025
12b2667
Fix uart test and rename remaining UART -> Uart
LasseRosenow Feb 6, 2025
9ed1558
Fix test
LasseRosenow Feb 6, 2025
e108ae3
Remove unused include
LasseRosenow Feb 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/riot/coap_federated/receiver/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ DEVELHELP ?= 1
QUIET ?= 1

# Enable reactor-uc features
CFLAGS += -DNETWORK_CHANNEL_COAP_RIOT
CFLAGS += -DNETWORK_CHANNEL_COAP
REACTION_QUEUE_SIZE = 32
EVENT_QUEUE_SIZE = 32

Expand Down
2 changes: 1 addition & 1 deletion examples/riot/coap_federated/sender/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ DEVELHELP ?= 1
QUIET ?= 1

# Enable reactor-uc features
CFLAGS += -DNETWORK_CHANNEL_COAP_RIOT
CFLAGS += -DNETWORK_CHANNEL_COAP
REACTION_QUEUE_SIZE = 32
EVENT_QUEUE_SIZE = 32

Expand Down
2 changes: 1 addition & 1 deletion examples/riot/coap_federated/sender/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ typedef struct {
char msg[512];
} lf_msg_t;

size_t serialize_msg_t(const void *user_struct, size_t user_struct_size, unsigned char *msg_buf) {
int serialize_msg_t(const void *user_struct, size_t user_struct_size, unsigned char *msg_buf) {
(void)user_struct_size;
const lf_msg_t *msg = user_struct;

Expand Down
3 changes: 0 additions & 3 deletions examples/riot/coap_federated_lf/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@ DEVELHELP ?= 1
# Change this to 0 show compiler invocation lines by default:
QUIET ?= 1

# Enable reactor-uc features
CFLAGS += -DNETWORK_CHANNEL_COAP_RIOT

# Configure CoAP retransmission timeout
CFLAGS += -DCONFIG_GCOAP_NO_RETRANS_BACKOFF=1
CFLAGS += -DCONFIG_COAP_ACK_TIMEOUT_MS=400
Expand Down
2 changes: 1 addition & 1 deletion examples/riot/hello_lf/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ LF_MAIN ?= HelloLF

# Enable reactor-uc features
# CFLAGS += -DNETWORK_CHANNEL_TCP_POSIX
# CFLAGS += -DNETWORK_CHANNEL_COAP_RIOT
# CFLAGS += -DNETWORK_CHANNEL_COAP

# Execute the LF compiler if build target is "all"
ifeq ($(firstword $(MAKECMDGOALS)),all)
Expand Down
2 changes: 1 addition & 1 deletion include/reactor-uc/federated.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,4 @@ void FederatedInputConnection_ctor(FederatedInputConnection *self, Reactor *pare
bool *payload_used_buf, size_t payload_size, size_t payload_buf_capacity);

void Federated_distribute_start_tag(Environment *env, instant_t start_time);
#endif
#endif
32 changes: 31 additions & 1 deletion include/reactor-uc/network_channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,27 @@ typedef enum {
typedef enum {
NETWORK_CHANNEL_TYPE_TCP_IP,
NETWORK_CHANNEL_TYPE_COAP_UDP_IP,
NETWORK_CHANNEL_TYPE_UART
} NetworkChannelType;

typedef enum {
NETWORK_CHANNEL_MODE_ASYNC,
NETWORK_CHANNEL_MODE_POLLED,
} NetworkChannelMode;
erlingrj marked this conversation as resolved.
Show resolved Hide resolved

char *NetworkChannel_state_to_string(NetworkChannelState state);

typedef struct FederatedConnectionBundle FederatedConnectionBundle;
typedef struct NetworkChannel NetworkChannel;
typedef struct PolledNetworkChannel PolledNetworkChannel;
typedef struct AsyncNetworkChannel AsyncNetworkChannel;

struct NetworkChannel {
/**
* @brief Specifies if this NetworkChannel is a aync or async channel
*/
NetworkChannelMode mode;

/**
* @brief Expected time until a connection is established after calling @p open_connection.
*/
Expand Down Expand Up @@ -95,6 +108,19 @@ struct NetworkChannel {
void (*free)(NetworkChannel *self);
};

struct PolledNetworkChannel {
NetworkChannel super;

/**
* @brief Polls for new data and calls the callback handler if a message is successfully decoded
tanneberger marked this conversation as resolved.
Show resolved Hide resolved
*/
void (*poll)(NetworkChannel *self);
};

struct AsyncNetworkChannel {
NetworkChannel super;
LasseRosenow marked this conversation as resolved.
Show resolved Hide resolved
};

#if defined(PLATFORM_POSIX)
#ifdef NETWORK_CHANNEL_TCP_POSIX
#include "platform/posix/tcp_ip_channel.h"
Expand All @@ -109,9 +135,12 @@ struct NetworkChannel {
#ifdef NETWORK_CHANNEL_TCP_POSIX
#include "platform/posix/tcp_ip_channel.h"
#endif
#ifdef NETWORK_CHANNEL_COAP_RIOT
#ifdef NETWORK_CHANNEL_COAP
#include "platform/riot/coap_udp_ip_channel.h"
#endif
#ifdef NETWORK_CHANNEL_UART
#include "platform/riot/uart_channel.h"
#endif

#elif defined(PLATFORM_PICO)
#ifdef NETWORK_CHANNEL_TCP_POSIX
Expand All @@ -126,4 +155,5 @@ struct NetworkChannel {
#else
#error "Platform not supported"
#endif

#endif // REACTOR_UC_NETWORK_CHANNEL_H
20 changes: 20 additions & 0 deletions include/reactor-uc/network_channel/uart_channel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef REACTOR_UC_UART_CHANNEL_H
#define REACTOR_UC_UART_CHANNEL_H

typedef enum UartDataBits UartDataBits;
typedef enum UartParityBits UartParityBits;
typedef enum UartStopBits UartStopBits;

enum UartDataBits { UC_UART_DATA_BITS_5, UC_UART_DATA_BITS_6, UC_UART_DATA_BITS_7, UC_UART_DATA_BITS_8 };

enum UartParityBits {
UC_UART_PARITY_NONE,
UC_UART_PARITY_EVEN,
UC_UART_PARITY_ODD,
UC_UART_PARITY_MARK,
UC_UART_PARITY_SPACE
};

enum UartStopBits { UC_UART_STOP_BITS_1, UC_UART_STOP_BITS_2 };

#endif
48 changes: 48 additions & 0 deletions include/reactor-uc/platform/riot/uart_channel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#ifndef REACTOR_UC_RIOT_UART_CHANNEL_H
#define REACTOR_UC_RIOT_UART_CHANNEL_H

#include "reactor-uc/network_channel/uart_channel.h"
#include "reactor-uc/network_channel.h"
#include "reactor-uc/environment.h"

#include "periph/uart.h"
#include "cond.h"

typedef struct FederatedConnectionBundle FederatedConnectionBundle;
typedef struct UartPolledChannel UartPolledChannel;
typedef struct UartAsyncChannel UartAsyncChannel;

#define UART_CHANNEL_BUFFERSIZE 1024
// The UartChannel is not connection-oriented and will always appear as connected, so no need to wait.
#define UART_CHANNEL_EXPECTED_CONNECT_DURATION MSEC(0)

struct UartPolledChannel {
PolledNetworkChannel super;
NetworkChannelState state;

FederateMessage output;
unsigned char write_buffer[UART_CHANNEL_BUFFERSIZE];
unsigned char receive_buffer[UART_CHANNEL_BUFFERSIZE];
unsigned int receive_buffer_index;
uart_t uart_dev;

FederatedConnectionBundle *federated_connection;
void (*receive_callback)(FederatedConnectionBundle *conn, const FederateMessage *message);
};

struct UartAsyncChannel {
UartPolledChannel super;

char decode_thread_stack[THREAD_STACKSIZE_MAIN];
int decode_thread_pid;
mutex_t receive_lock;
cond_t receive_cv;
};

void UartPolledChannel_ctor(UartPolledChannel *self, uint32_t uart_device, uint32_t baud, UartDataBits data_bits,
UartParityBits parity, UartStopBits stop_bits);

void UartAsyncChannel_ctor(UartAsyncChannel *self, uint32_t uart_device, uint32_t baud, UartDataBits data_bits,
UartParityBits parity, UartStopBits stop_bits);

#endif
13 changes: 13 additions & 0 deletions lfc/core/src/main/java/org/lflang/validation/AttributeSpec.java
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,19 @@ enum AttrParamType {
new AttributeSpec(List.of(new AttrParamSpec(VALUE_ATTR, AttrParamType.INT, false))));
// @interface:tcp(name="string", address="string") e.g. @interface:tcp(name="if1",
// address="127.0.0.1")

ATTRIBUTE_SPECS_BY_NAME.put(
"interface_uart",
new AttributeSpec(
List.of(
new AttrParamSpec("name", AttrParamType.STRING, true),
new AttrParamSpec("uart_device", AttrParamType.INT, true),
new AttrParamSpec("baud_rate", AttrParamType.INT, true),
new AttrParamSpec("data_bits", AttrParamType.STRING, true),
tanneberger marked this conversation as resolved.
Show resolved Hide resolved
new AttrParamSpec("parity", AttrParamType.STRING, true),
new AttrParamSpec("stop_bits", AttrParamType.STRING, true),
tanneberger marked this conversation as resolved.
Show resolved Hide resolved
new AttrParamSpec("async", AttrParamType.BOOLEAN, true))));

ATTRIBUTE_SPECS_BY_NAME.put(
"interface_tcp",
new AttributeSpec(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ package org.lflang.generator.uc
import org.lflang.*
import org.lflang.generator.PrependOperator
import org.lflang.generator.orZero
import org.lflang.generator.uc.UcReactorGenerator.Companion.hasStartup
import org.lflang.generator.uc.UcReactorGenerator.Companion.hasShutdown
import org.lflang.generator.uc.UcReactorGenerator.Companion.codeType
import org.lflang.generator.uc.UcReactorGenerator.Companion.getEffects
import org.lflang.generator.uc.UcReactorGenerator.Companion.getObservers
import org.lflang.generator.uc.UcReactorGenerator.Companion.getSources
import org.lflang.AttributeUtils.getMaxNumberOfPendingEvents
import org.lflang.generator.uc.UcReactorGenerator.Companion.hasShutdown
import org.lflang.generator.uc.UcReactorGenerator.Companion.hasStartup
import org.lflang.lf.*

class UcActionGenerator(private val reactor: Reactor) {
Expand All @@ -22,61 +22,72 @@ class UcActionGenerator(private val reactor: Reactor) {
}
}

/** Returns the C Enum representing the type of action.*/
private val Action.actionType
get(): String = if (isPhysical) "PHYSICAL_ACTION" else "LOGICAL_ACTION"
/** Returns the C Enum representing the type of action. */
private val Action.actionType
get(): String = if (isPhysical) "PHYSICAL_ACTION" else "LOGICAL_ACTION"

private fun generateSelfStruct(action: Action) = with(PrependOperator) {
private fun generateSelfStruct(action: Action) =
with(PrependOperator) {
"""
|LF_DEFINE_ACTION_STRUCT${if (action.type == null) "_VOID" else ""}(${reactor.codeType}, ${action.name}, ${action.actionType}, ${reactor.getEffects(action).size}, ${reactor.getSources(action).size}, ${reactor.getObservers(action).size}, ${action.maxNumPendingEvents} ${if (action.type != null) ", ${action.type.toText()}" else ""});
|
""".trimMargin()
}
"""
.trimMargin()
}

private fun generateCtor(action: Action) = with(PrependOperator) {
private fun generateCtor(action: Action) =
with(PrependOperator) {
"""
|LF_DEFINE_ACTION_CTOR${if (action.type == null) "_VOID" else ""}(${reactor.codeType}, ${action.name}, ${action.actionType}, ${reactor.getEffects(action).size}, ${reactor.getSources(action).size}, ${reactor.getObservers(action).size}, ${action.maxNumPendingEvents} ${if (action.type != null) ", ${action.type.toText()}" else ""});
|
""".trimMargin()
}
"""
.trimMargin()
}

private fun generateCtor(builtin: BuiltinTrigger) =
(if (builtin == BuiltinTrigger.STARTUP) "LF_DEFINE_STARTUP_CTOR" else "LF_DEFINE_SHUTDOWN_CTOR") +
"(${reactor.codeType});\n"
private fun generateCtor(builtin: BuiltinTrigger) =
(if (builtin == BuiltinTrigger.STARTUP) "LF_DEFINE_STARTUP_CTOR"
else "LF_DEFINE_SHUTDOWN_CTOR") + "(${reactor.codeType});\n"

fun generateCtors(): String {
var code = reactor.allActions.joinToString(separator = "\n") { generateCtor(it) }
if (reactor.hasStartup) code += generateCtor(BuiltinTrigger.STARTUP)
if (reactor.hasShutdown) code += generateCtor(BuiltinTrigger.SHUTDOWN)
return code
}

fun generateCtors(): String {
var code = reactor.allActions.joinToString(separator = "\n") { generateCtor(it) }
if (reactor.hasStartup) code += generateCtor(BuiltinTrigger.STARTUP);
if (reactor.hasShutdown) code += generateCtor(BuiltinTrigger.SHUTDOWN);
return code;
private fun generateSelfStruct(builtin: BuiltinTrigger) =
(if (builtin == BuiltinTrigger.STARTUP) "LF_DEFINE_STARTUP_STRUCT"
else "LF_DEFINE_SHUTDOWN_STRUCT") +
"(${reactor.codeType}, ${reactor.getEffects(builtin).size}, ${reactor.getObservers(builtin).size});\n"

fun generateSelfStructs(): String {
var code = reactor.allActions.joinToString(separator = "\n") { generateSelfStruct(it) }
if (reactor.hasStartup) {
code += generateSelfStruct(BuiltinTrigger.STARTUP)
}
if (reactor.hasShutdown) {
code += generateSelfStruct(BuiltinTrigger.SHUTDOWN)
}
return code
}

private fun generateSelfStruct(builtin: BuiltinTrigger) =
(if (builtin == BuiltinTrigger.STARTUP) "LF_DEFINE_STARTUP_STRUCT" else "LF_DEFINE_SHUTDOWN_STRUCT") +
"(${reactor.codeType}, ${reactor.getEffects(builtin).size}, ${reactor.getObservers(builtin).size});\n"
fun generateReactorStructFields(): String {
var code =
reactor.allActions.joinToString(
prefix = "// Actions and builtin triggers\n", separator = "\n", postfix = "\n") {
"LF_ACTION_INSTANCE(${reactor.codeType}, ${it.name});"
}
if (reactor.hasStartup) code += "LF_STARTUP_INSTANCE(${reactor.codeType});"
if (reactor.hasShutdown) code += "LF_SHUTDOWN_INSTANCE(${reactor.codeType});"
return code
}

fun generateSelfStructs(): String {
var code = reactor.allActions.joinToString(separator = "\n") { generateSelfStruct(it) }
if (reactor.hasStartup) {
code += generateSelfStruct(BuiltinTrigger.STARTUP) ;
}
if (reactor.hasShutdown) {
code += generateSelfStruct(BuiltinTrigger.SHUTDOWN) ;
}
return code;
}
private fun generateReactorCtorCode(action: Action) =
"LF_INITIALIZE_ACTION(${reactor.codeType}, ${action.name}, ${action.minDelay.orZero().toCCode()}, ${action.minSpacing.orZero().toCCode()});"

fun generateReactorStructFields(): String {
var code = reactor.allActions.joinToString(prefix = "// Actions and builtin triggers\n", separator = "\n", postfix = "\n") { "LF_ACTION_INSTANCE(${reactor.codeType}, ${it.name});" }
if (reactor.hasStartup) code += "LF_STARTUP_INSTANCE(${reactor.codeType});"
if (reactor.hasShutdown) code += "LF_SHUTDOWN_INSTANCE(${reactor.codeType});"
return code;
}
private fun generateReactorCtorCodeStartup() = "LF_INITIALIZE_STARTUP(${reactor.codeType});"

private fun generateReactorCtorCode(action: Action) = "LF_INITIALIZE_ACTION(${reactor.codeType}, ${action.name}, ${action.minDelay.orZero().toCCode()}, ${action.minSpacing.orZero().toCCode()});"
private fun generateReactorCtorCodeStartup() = "LF_INITIALIZE_STARTUP(${reactor.codeType});"
private fun generateReactorCtorCodeShutdown() = "LF_INITIALIZE_SHUTDOWN(${reactor.codeType});"
private fun generateReactorCtorCodeShutdown() = "LF_INITIALIZE_SHUTDOWN(${reactor.codeType});"

fun generateReactorCtorCodes(): String {
var code = reactor.allActions.joinToString(prefix = "// Initialize actions and builtin triggers\n", separator = "\n", postfix = "\n") { generateReactorCtorCode(it)}
Expand Down
Loading
Loading