Skip to content

Commit

Permalink
Add a custom Gate example
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolas-rabault committed Jan 26, 2024
1 parent 157b99b commit 857623b
Show file tree
Hide file tree
Showing 9 changed files with 396 additions and 0 deletions.
Empty file.
4 changes: 4 additions & 0 deletions examples/projects/product/custom_gate/.docker/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.pio/
.vscode/
.gitignore
README.md
19 changes: 19 additions & 0 deletions examples/projects/product/custom_gate/.docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
FROM python:3 as builder

LABEL maintainer="Benjamin Christau <benjamin.christau@luos.io>" \
app_name="gate_wscom"

ENV PLATFORMIO_CORE_DIR="/home"

WORKDIR /home/app

COPY . .

RUN pip install --upgrade pip setuptools wheel platformio && \
rm -rf /root/.cache/pip

RUN platformio run \
--environment native \
-d ./examples/projects/native/gate_wscom

CMD [ "./examples/projects/native/gate_wscom/.pio/build/native/program"]
22 changes: 22 additions & 0 deletions examples/projects/product/custom_gate/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<a href="https://luos.io"><img src="https://uploads-ssl.webflow.com/601a78a2b5d030260a40b7ad/603e0cc45afbb50963aa85f2_Gif%20noir%20rect.gif" alt="Luos logo" title="Luos" align="right" height="100" /></a>

![](https://github.com/Luos-io/luos_engine/actions/workflows/build.yml/badge.svg)
[![](https://img.shields.io/github/license/Luos-io/luos_engine)](https://github.com/Luos-io/luos_engine/blob/master/LICENSE)

[![](https://img.shields.io/badge/Luos-Documentation-34A3B4)](https://www.luos.io/docs/)
[![PlatformIO Registry](https://badges.registry.platformio.org/packages/luos/library/luos_engine.svg)](https://registry.platformio.org/libraries/luos_engine/luos_engine)

[![](https://img.shields.io/discord/902486791658041364?label=Discord&logo=discord&style=social)](http://bit.ly/JoinLuosDiscord)
[![](https://img.shields.io/badge/LinkedIn-Share-0077B5?style=social&logo=linkedin)](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fgithub.com%2Fluos-io)

# Custom Gate project example :bulb:

This project demonstrate how to make a custom gate with custom Json conversion.

## How to compile the code :computer:

1. Download and install [Platformio](https://platformio.org/platformio-ide)
2. Open this folder into Platformio
3. Build (Platformio will do the rest)

## Don't hesitate to read [our documentation](https://www.luos.io/docs/), or to post your questions/issues on the [Luos' Discord](http://bit.ly/JoinLuosDiscord). :books:
118 changes: 118 additions & 0 deletions examples/projects/product/custom_gate/node_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@


/******************************************************************************
* @file node_config.h
* @brief This file allow you to use standard preprocessor definitions to
* configure your project, Luos and Luos HAL libraries
*
* # Introduction
* This file is for the luos user. You may here configure your project and
* define your custom Luos service and custom Luos command for your product
*
* Luos libraries offer a minimal standard configuration to optimize
* memory usage. In some case you have to modify standard value to fit
* with your need concerning among of data transiting through the network
* or network speed for example
*
* Luos libraries can be use with a lot a MCU family. Luos compagny give you
* a default configuration, for specific MCU family, in robus_hal_config.h.
* This configuration can be modify here to fit with you design by
* preprocessor definitions of MCU Hardware needs
*
* # Usage
* This file should be place a the root folder of your project and include
* where build flag preprocessor definitions are define in your IDE
* -include node_config.h
*
* @author Luos
* @version 0.0.0
******************************************************************************/
#ifndef _NODE_CONFIG_H_
#define _NODE_CONFIG_H_

/*******************************************************************************
* PROJECT DEFINITION
*******************************************************************************/

/*******************************************************************************
* LUOS LIBRARY DEFINITION
*******************************************************************************
* Define | Default Value | Description
* :---------------------|------------------------------------------------------
* MAX_LOCAL_SERVICE_NUMBER | 5 | Service number in the node
* MAX_NODE_NUMBER | 20 | Node number in the device
* MAX_SERVICE_NUMBER | 20 | Service number in the device
* MSG_BUFFER_SIZE | 3*SIZE_MSG_MAX (405 Bytes) | Size in byte of the Luos buffer TX and RX
* MAX_MSG_NB | 2*MAX_LOCAL_SERVICE_NUMBER | Message number in Luos buffer
* NBR_PORT | 2 | PTP Branch number Max 8
* NBR_RETRY | 10 | Send Retry number in case of NACK or collision
******************************************************************************/
#define MAX_LOCAL_SERVICE_NUMBER 2
#define MAX_LOCAL_PROFILE_NUMBER 1
#define MAX_MSG_NB 200
#define MSG_BUFFER_SIZE 8192

/*******************************************************************************
* LUOS HAL LIBRARY DEFINITION
*******************************************************************************
* Define | Description
* :-----------------------|-----------------------------------------------
* MCUFREQ | Put your the MCU frequency (value in Hz)
* TIMERDIV | Timer divider clock (see your clock configuration)
* USE_CRC_HW | define to 0 if there is no Module CRC in your MCU
* USE_TX_IT | define to 1 to not use DMA transfers for Luos Tx
*
* PORT_CLOCK_ENABLE | Enable clock for port
* PTPx | A,B,C,D etc. PTP Branch Pin/Port/IRQ
* TX_LOCK_DETECT | Disable by default use if not busy flag in USART Pin/Port/IRQ
* RX_EN | Rx enable for driver RS485 always on Pin/Port
* TX_EN | Tx enable for driver RS485 Pin/Port
* COM_TX | Tx USART Com Pin/Port/Alternate
* COM_RX | Rx USART Com Pin/Port/Alternate
* PINOUT_IRQHANDLER | Callback function for Pin IRQ handler
* ROBUS_COM_CLOCK_ENABLE | Enable clock for USART
* ROBUS_COM | USART number
* ROBUS_COM_IRQ | USART IRQ number
* ROBUS_COM_IRQHANDLER | Callback function for USART IRQ handler
* ROBUS_DMA_CLOCK_ENABLE | Enable clock for DMA
* ROBUS_DMA | DMA number
* ROBUS_DMA_CHANNEL | DMA channel (depending on MCU DMA may need special config)
* ROBUS_TIMER_CLOCK_ENABLE | Enable clock for Timer
* ROBUS_TIMER | Timer number
* ROBUS_TIMER_IRQ | Timer IRQ number
* ROBUS_TIMER_IRQHANDLER | Callback function for Timer IRQ handler
******************************************************************************/

/*******************************************************************************
* FLASH CONFIGURATION FOR APP WITH BOOTLOADER
********************************************************************************
* Define | Default Value | Description
* :---------------------|------------------------------------------------------
* BOOT_START_ADDRESS | FLASH_BASE = 0x8000000 | Start address of Bootloader in flash
* SHARED_MEMORY_ADDRESS | 0x0800C000 | Start address of shared memory to save boot flag
* APP_START_ADDRESS | 0x0800C800 | Start address of application with bootloader
* APP_END_ADDRESS | FLASH_BANK1_END=0x0801FFFF | End address of application with bootloader
******************************************************************************/

/*******************************************************************************
* GATE SERIAL COM DEFINITION
*******************************************************************************
* Define | Default Value | Description
* :-------------------------|------------------------------------------------------
* GATE_BUFF_SIZE | 1024 | Json receive buffer size
* PIPE_RX_BUFFER_SIZE | 1024 | Receive pipe buffer size
* PIPE_TX_BUFFER_SIZE | 2048 | Transmit pipe buffer size
* INIT_TIME | 150 | Wait init time before first detection
******************************************************************************/
#define GATE_BUFF_SIZE 65000
#define PIPE_RX_BUFFER_SIZE 65000
#define PIPE_TX_BUFFER_SIZE 65000
#define SERIAL_RX_BUFFER_SIZE 65000
#define INIT_TIME 150
#define GATE_REFRESH_TIME_S 0.05f
#define SERIAL_PORT "/dev/cu.usbmodem1202" // "/dev/cu.usbserial-D308N897"

#endif /* _NODE_CONFIG_H_ */
38 changes: 38 additions & 0 deletions examples/projects/product/custom_gate/platformio.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
default_envs = native_serial

[env:native_serial]
lib_ldf_mode =off
lib_extra_dirs =
$PROJECT_DIR/../../../../tool_services/
$PROJECT_DIR/../../../../../
$PROJECT_DIR/../../../../network/
platform = native
lib_deps =
luos_engine@^3.1.0
serial_network
Pipe
Gate
build_unflags = -Os
build_flags =
-I inc
-I ../
-include node_config.h
-O1
-lpthread
-lm
-D LUOSHAL=NATIVE
-D GATEFORMAT=TinyJSON
-D PIPEMODE=WS
-D PIPEHAL=native
-D PIPE_WS_SERVER_ADDR=\"ws://localhost:9342\" ; Watch out you need to escape the " using \
build_type = debug
98 changes: 98 additions & 0 deletions examples/projects/product/custom_gate/src/custom_json_conversion.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#include "custom-json.h"
#include "product_config.h"
#include <stdio.h>

// This function are called by the gate conversion functions in case of an unknown type.
// This functions allow you to easily add and manage your custom type and commands.

// This function is called by the gate to convert a service type into a string.
// This is typically used in the end of detection to create a Json representing the device routing table.
// The name of the type will be used by pyluos to create the right object.
const char *Convert_CustomStringFromType(luos_type_t type)
{
if (type == POINT_2D)
{
return "point_2D";
}
return NULL;
}

// This function is called by the gate to convert a piece of Json into a message.
// This is typically used when a Json is received by the gate with an unknown property.
// You can use it to compose your own message out of the Json data and send it to the right service.
void Convert_CustomJsonToMsg(service_t *service, uint16_t target_id, char *property, const json_t *jobj, char *json_str)
{
msg_t msg;
msg.header.target_mode = IDACK;
msg.header.target = target_id;
// Target linear position 2D
if (property && !strcmp(property, "linear_pos_2D"))
{
// Check the size of the array. If we have more than one data, this mean that this data is a binary size of a trajectory. If we have 2 data, this is an unique point.
json_t const *item = json_getChild(jobj);
if (json_getSibling(item) != NULL)
{
// We only have one point in this data
pos_2d_t pos;
pos.x = (uint16_t)json_getInteger(item);
item = json_getSibling(item);
pos.y = (uint16_t)json_getInteger(item);
// Create the message
msg.header.cmd = LINEAR_POSITION_2D;
msg.header.size = sizeof(pos_2d_t);
memcpy(msg.data, &pos, sizeof(pos_2d_t));
// Send the message
Luos_SendMsg(service, &msg);
}
else
{
int i = 0;
// This is a binary
int size = (int)json_getInteger(item);
// Find the first \r of the current json_str
for (i = 0; i < GATE_BUFF_SIZE; i++)
{
if (json_str[i] == '\n')
{
i++;
break;
}
}
if (i < GATE_BUFF_SIZE - 1)
{
// Create the message
msg.header.cmd = LINEAR_POSITION_2D;
Luos_SendData(service, &msg, &json_str[i], (unsigned int)size);
}
}
return;
}
if (property && !strcmp(property, "buffer_mode"))
{
msg.data[0] = (char)json_getInteger(jobj);
msg.header.cmd = BUFFER_MODE;
msg.header.size = sizeof(char);
Luos_SendMsg(service, &msg);
return;
}
}

// This function is called by the gate to convert a message into a piece of Json.
// This is typically used when a message is received by the gate with an unknown command.
// You can use it to compose your own piece of Json out of the message data.
void Convert_CustomMsgToJson(msg_t *msg, char *data)
{
if (msg->header.cmd == LINEAR_POSITION_2D)
{
// This is our custom message, so we can convert it to JSON
// In this case we will don't need it but I did the code for the sake of the example.
if (msg->header.size == sizeof(pos_2d_t))
{
// Size ok, now fill the struct from msg data
pos_2d_t pos;
memcpy(&pos, msg->data, msg->header.size);
// create the Json content
sprintf(data, "\"linear_pos_2D\":[%2d,%2d],", pos.x, pos.y);
}
}
}
59 changes: 59 additions & 0 deletions examples/projects/product/custom_gate/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#include "luos_engine.h"
#include "serial_network.h"
#include "pipe.h"
#include "gate.h"
#include <pthread.h>

#ifndef WIN32
#include <execinfo.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#endif

void *Gate_Pipe_LoopThread(void *vargp)
{
while (1)
{
Pipe_Loop();
Gate_Loop();
}
return NULL;
}
#ifndef _WIN32
void handler(int sig)
{
void *array[10];
size_t size;

// get void*'s for all entries on the stack
size = backtrace(array, 10);

// print out all the frames to stderr
fprintf(stderr, "Error: signal %d:\n", sig);
backtrace_symbols_fd(array, size, STDERR_FILENO);
exit(1);
}
#endif

int main(void)
{
#ifndef _WIN32
signal(SIGSEGV, handler); // install our handler
#endif
Luos_Init();
Serial_Init();
Pipe_Init();
Gate_Init();
// Create a thread to convert messages into Json and steam them using Websocket
// pthread_t thread_id;
// pthread_create(&thread_id, NULL, Gate_Pipe_LoopThread, NULL);
while (1)
{
Luos_Loop();
Serial_Loop();
Pipe_Loop();
Gate_Loop();
}
}
Loading

0 comments on commit 857623b

Please sign in to comment.