Skip to content

Commit

Permalink
Add NCodec example model.
Browse files Browse the repository at this point in the history
Signed-off-by: Rule Timothy (VM/EMT3) <[email protected]>
  • Loading branch information
timrulebosch committed Feb 6, 2024
1 parent 47f447a commit 6af4bcd
Show file tree
Hide file tree
Showing 13 changed files with 386 additions and 38 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export DSE_SCHEMA_URL ?= $(DSE_SCHEMA_REPO)/releases/download/v$(DSE_SCHEMA_VERS
###############
## DSE C Library.
DSE_CLIB_REPO ?= https://github.com/boschglobal/dse.clib
DSE_CLIB_VERSION ?= 1.0.8
DSE_CLIB_VERSION ?= 1.0.10
export DSE_CLIB_URL ?= $(DSE_CLIB_REPO)/archive/refs/tags/v$(DSE_CLIB_VERSION).zip


Expand Down
12 changes: 8 additions & 4 deletions dse/mocks/simmock.c
Original file line number Diff line number Diff line change
Expand Up @@ -385,8 +385,10 @@ int simmock_step(SimMock* mock, bool assert_rc)
int rc = 0;
for (ModelMock* model = mock->model; model->name; model++) {
/* Copy scalars from simmock->scalars. */
for (uint32_t i = 0; i < mock->sv_signal->count; i++) {
model->sv_signal->scalar[i] = mock->sv_signal->scalar[i];
if (mock->sv_signal) {
for (uint32_t i = 0; i < mock->sv_signal->count; i++) {
model->sv_signal->scalar[i] = mock->sv_signal->scalar[i];
}
}
/* Copy binary from simmock->binary_rx. */
if (mock->sv_network_rx && mock->sv_network_tx) {
Expand All @@ -405,8 +407,10 @@ int simmock_step(SimMock* mock, bool assert_rc)
}
}
/* Copy scalars to simmock->scalars. */
for (uint32_t i = 0; i < mock->sv_signal->count; i++) {
mock->sv_signal->scalar[i] = model->sv_signal->scalar[i];
if (mock->sv_signal) {
for (uint32_t i = 0; i < mock->sv_signal->count; i++) {
mock->sv_signal->scalar[i] = model->sv_signal->scalar[i];
}
}
/* Copy binary to simmock->binary_tx. */
if (mock->sv_network_rx && mock->sv_network_tx) {
Expand Down
2 changes: 1 addition & 1 deletion dse/modelc/examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
add_subdirectory(minimal)
add_subdirectory(extended)
add_subdirectory(binary)
# TODO add_subdirectory(ncodec)
add_subdirectory(ncodec)

add_subdirectory(gateway)
#add_subdirectory(benchmark)
Expand Down
27 changes: 19 additions & 8 deletions dse/modelc/examples/doc/docs/ncodec/ncodec_config.c
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
#include <string.h>
#include <dse/logger.h>
#include <dse/modelc/model.h>
#include <dse/ncodec/codec.h>

void _setup_node_id(SignalVector* sv, uint32_t idx)
void configure_codec(ModelDesc* m, SignalVector* sv, uint32_t idx)
{
const char* v = sv->annotation(sv, idx, "node_id");
if (v) {
NCODEC* nc = sv->codec(sv, idx);
NCODEC* nc = sv->codec(sv, idx);
const char* node_id = NULL;
for (int i = 0; i >= 0; i++) {
NCodecConfigItem nci = ncodec_stat(nc, &i);
if (strcmp(nci.name, "node_id") == 0) {
node_id = nci.value;
break;
}
}
if (node_id == NULL) {
node_id = model_instance_annotation(m, "node_id");
if (node_id == NULL) log_fatal("No node_id configuration found!");
ncodec_config(nc, (struct NCodecConfigItem){
.name = "node_id",
.value = v,
});
.name = "node_id",
.value = node_id,
});
}
}
}
39 changes: 19 additions & 20 deletions dse/modelc/examples/doc/docs/ncodec/ncodec_model.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,30 @@
extern int put_rx_frame_to_queue(uint32_t, uint8_t*, size_t);
extern int get_tx_frame_from_queue(uint32_t*, uint8_t**, size_t*);

void do_bus_rx(SignalVector* sv, uint32_t idx)
typedef struct {
ModelDesc model;
NCODEC* nc;
} ExtendedModelDesc;

int model_step(ModelDesc* model, double* model_time, double stop_time)
{
NCODEC* nc = sv->codec(sv, idx);
ExtendedModelDesc* m = (ExtendedModelDesc*)model;
NCodecCanMessage msg = {};

/* Message RX. */
while (1) {
NCodecCanMessage msg = {};
int len = ncodec_read(nc, &msg);
if (len < 0) break;
if (ncodec_read(m->nc, &msg) < 0) break;
put_rx_frame_to_queue(msg.frame_id, msg.buffer, msg.len);
}
}

void do_bus_tx(SignalVector* sv, uint32_t idx)
{
uint32_t id;
uint8_t* msg;
size_t len;
NCODEC* nc = sv->codec(sv, idx);

while (get_tx_frame_from_queue(&id, &msg, &len)) {
ncodec_write(nc, &(struct NCodecCanMessage){
.frame_id = id,
.buffer = msg,
.len = len,
});
/* Message TX. */
ncodec_truncate(m->nc); /* Clear the codec buffer (i.e. Rx data). */
while (get_tx_frame_from_queue(&msg.frame_id, &msg.buffer, &msg.len)) {
ncodec_write(m->nc, &msg);
}
ncodec_flush(nc);
ncodec_flush(m->nc);

/* Progress the Model time. */
*model_time = stop_time;
return 0;
}
47 changes: 47 additions & 0 deletions dse/modelc/examples/ncodec/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Copyright 2024 Robert Bosch GmbH
#
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.21)

project(NCodec)
set(MODEL_PATH "examples/ncodec")

include(FetchContent)
FetchContent_Declare(dse_clib
URL $ENV{DSE_CLIB_URL}
HTTP_USERNAME $ENV{GHE_USER}
HTTP_PASSWORD $ENV{GHE_TOKEN}
)
FetchContent_MakeAvailable(dse_clib)
set(DSE_CLIB_INCLUDE_DIR ${dse_clib_SOURCE_DIR})


add_library(ncodec SHARED
model.c
)
target_include_directories(ncodec
PRIVATE
${DSE_CLIB_INCLUDE_DIR}
${DSE_NCODEC_INCLUDE_DIR}
../../../..
)
target_link_libraries(ncodec
PRIVATE
$<$<BOOL:${WIN32}>:${modelc_link_lib}>
)
install(TARGETS ncodec
LIBRARY DESTINATION
${MODEL_PATH}/lib
COMPONENT
ncodec
)
install(
FILES
model.yaml
simulation.yaml
DESTINATION
${MODEL_PATH}/data
COMPONENT
ncodec
)
91 changes: 91 additions & 0 deletions dse/modelc/examples/ncodec/model.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// Copyright 2024 Robert Bosch GmbH
//
// SPDX-License-Identifier: Apache-2.0

#include <string.h>
#include <dse/logger.h>
#include <dse/modelc/model.h>
#include <dse/ncodec/codec.h>


typedef struct {
ModelDesc model;
/* Network Codec reference. */
NCODEC* nc;
/* Model Instance values. */
const char* node_id;
uint8_t counter;
} ExtendedModelDesc;


static inline NCODEC* _index(ExtendedModelDesc* m, const char* v, const char* s)
{
ModelSignalIndex idx = m->model.index((ModelDesc*)m, v, s);
if (idx.binary == NULL) log_fatal("Signal not found (%s:%s)", v, s);

NCODEC* nc = idx.sv->codec(idx.sv, idx.signal);
if (nc == NULL) log_fatal("NCodec object not available (%s:%s)", v, s);

return nc;
}


ModelDesc* model_create(ModelDesc* model)
{
/* Extend the ModelDesc object (using a shallow copy). */
ExtendedModelDesc* m = calloc(1, sizeof(ExtendedModelDesc));
memcpy(m, model, sizeof(ModelDesc));

/* Index the Network Codec. */
m->nc = _index(m, "binary", "can");

/* Configure the Network Codec. */
for (int i = 0; i >= 0; i++) {
NCodecConfigItem nci = ncodec_stat(m->nc, &i);
if (strcmp(nci.name, "node_id") == 0) {
m->node_id = nci.value;
break;
}
}
if (m->node_id == NULL) {
m->node_id = model_instance_annotation((ModelDesc*)m, "node_id");
if (m->node_id == NULL) log_fatal("No node_id configuration found!");
ncodec_config(m->nc, (struct NCodecConfigItem){
.name = "node_id",
.value = m->node_id,
});
}

/* Return the extended object. */
return (ModelDesc*)m;
}


int model_step(ModelDesc* model, double* model_time, double stop_time)
{
ExtendedModelDesc* m = (ExtendedModelDesc*)model;

/* Message RX. */
while (1) {
NCodecCanMessage msg = {};
int len = ncodec_read(m->nc, &msg);
if (len < 0) break;
log_info("RX (%04x): %s", msg.frame_id, msg.buffer);
}

/* Message TX. */
char msg[100] = "Hello World!";
snprintf(msg + strlen(msg), sizeof(msg), " from node_id=%s", m->node_id);
struct NCodecCanMessage tx_msg = {
.frame_id = ++m->counter + 1000, /* Simple frame_id: 1001, 1002 ... */
.frame_type = CAN_EXTENDED_FRAME,
.buffer = (uint8_t*)msg,
.len = strlen(msg) + 1, /* Capture the NULL terminator. */
};
ncodec_truncate(m->nc);
ncodec_write(m->nc, &tx_msg);
ncodec_flush(m->nc);

*model_time = stop_time;
return 0;
}
27 changes: 27 additions & 0 deletions dse/modelc/examples/ncodec/model.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Copyright 2024 Robert Bosch GmbH
#
# SPDX-License-Identifier: Apache-2.0

---
kind: Model
metadata:
name: NCodec
spec:
runtime:
dynlib:
- os: linux
arch: amd64
path: lib/libncodec.so
- os: linux
arch: x86
path: lib/libncodec.so
- os: windows
arch: x64
path: bin/ncodec.dll
- os: windows
arch: x86
path: bin/ncodec.dll
channels:
- alias: binary
selectors:
channel: binary_channel
48 changes: 48 additions & 0 deletions dse/modelc/examples/ncodec/simulation.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Copyright 2024 Robert Bosch GmbH
#
# SPDX-License-Identifier: Apache-2.0

---
kind: Stack
metadata:
name: ncodec_stack
spec:
connection:
transport:
redispubsub:
uri: redis://localhost:6379
timeout: 60
models:
- name: simbus
model:
name: simbus
channels:
- name: binary_channel
expectedModelCount: 1
- name: ncodec_inst
uid: 42
annotations:
node_id: 24
model:
name: NCodec
channels:
- name: binary_channel
alias: binary
---
kind: Model
metadata:
name: simbus
---
kind: SignalGroup
metadata:
name: binary_channel
labels:
channel: binary_channel
annotations:
vector_type: binary
spec:
signals:
- signal: can
annotations:
# Note that the mime_type may also include the node_id parameter.
mime_type: 'application/x-automotive-bus; interface=stream; type=frame; bus=can; schema=fbs; bus_id=1; interface_id=3'
4 changes: 3 additions & 1 deletion dse/modelc/model.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,11 @@ DLL_PUBLIC int model_step(ModelDesc* m, double* model_time, double stop_time);
DLL_PUBLIC void model_destroy(ModelDesc* m);


/* Provided by ModelC (via ModelIndex in ModelDesc and also ModelVTable). */
/* Provided by ModelC. */
DLL_PUBLIC ModelSignalIndex model_index_(
ModelDesc* model, const char* vname, const char* sname);
DLL_PUBLIC const char* model_annotation(ModelDesc* m, const char* name);
DLL_PUBLIC const char* model_instance_annotation(ModelDesc* m, const char* name);


/* Signal Interface. */
Expand Down
Loading

0 comments on commit 6af4bcd

Please sign in to comment.