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

Add Flipper platform #351

Merged
merged 2 commits into from
Feb 22, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
1 change: 1 addition & 0 deletions include/zenoh-pico/collections/list.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ void *_z_list_head(const _z_list_t *xs);
_z_list_t *_z_list_tail(const _z_list_t *xs);

_z_list_t *_z_list_push(_z_list_t *xs, void *x);
_z_list_t *_z_list_push_back(_z_list_t *xs, void *x);
_z_list_t *_z_list_pop(_z_list_t *xs, z_element_free_f f_f, void **x);

_z_list_t *_z_list_find(const _z_list_t *xs, z_element_eq_f f_f, void *e);
Expand Down
2 changes: 0 additions & 2 deletions include/zenoh-pico/protocol/keyexpr.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ static inline _z_keyexpr_t _z_keyexpr_null(void) {
_z_keyexpr_t keyexpr = {0, {0}, NULL};
return keyexpr;
}
_z_timestamp_t _z_timestamp_duplicate(const _z_timestamp_t *tstamp);
void _z_timestamp_clear(_z_timestamp_t *tstamp);
void _z_keyexpr_clear(_z_keyexpr_t *rk);
void _z_keyexpr_free(_z_keyexpr_t **rk);

Expand Down
2 changes: 2 additions & 0 deletions include/zenoh-pico/system/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
#include "zenoh-pico/system/platform/arduino/opencr.h"
#elif defined(ZENOH_EMSCRIPTEN)
#include "zenoh-pico/system/platform/emscripten.h"
#elif defined(ZENOH_FLIPPER)
#include "zenoh-pico/system/platform/flipper.h"
#elif defined(ZENOH_FREERTOS_PLUS_TCP)
#include "zenoh-pico/system/platform/freertos_plus_tcp.h"
#else
Expand Down
46 changes: 46 additions & 0 deletions include/zenoh-pico/system/platform/flipper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// Copyright (c) 2024 ZettaScale Technology
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
//
// Contributors:
// ZettaScale Zenoh Team, <[email protected]>
//

#ifndef ZENOH_PICO_SYSTEM_FLIPPER_TYPES_H
#define ZENOH_PICO_SYSTEM_FLIPPER_TYPES_H

#include <furi.h>

Check warning

Code scanning / Cppcheck (reported by Codacy)

Include file: <furi.h> not found. Please note: Cppcheck does not need standard library headers to get proper results. Warning

Include file: <furi.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <furi_hal.h>

Check warning

Code scanning / Cppcheck (reported by Codacy)

Include file: <furi_hal.h> not found. Please note: Cppcheck does not need standard library headers to get proper results. Warning

Include file: <furi_hal.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <sys/time.h>

Check warning

Code scanning / Cppcheck (reported by Codacy)

Include file: <sys/time.h> not found. Please note: Cppcheck does not need standard library headers to get proper results. Warning

Include file: <sys/time.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include "zenoh-pico/config.h"

#define FLIPPER_DEFAULT_THREAD_STACK_SIZE 2048
#define FLIPPER_SERIAL_STREAM_BUFFER_SIZE 512
#define FLIPPER_SERIAL_STREAM_TRIGGERED_LEVEL 10
#define FLIPPER_SERIAL_TIMEOUT_MS 200

#if Z_FEATURE_MULTI_THREAD == 1

Check warning

Code scanning / Cppcheck (reported by Codacy)

misra violation 2009 with no text in the supplied rule-texts-file Warning

misra violation 2009 with no text in the supplied rule-texts-file
typedef FuriThread* zp_task_t;
typedef uint32_t zp_task_attr_t;
typedef FuriMutex* zp_mutex_t;
typedef void* zp_condvar_t;
#endif // Z_FEATURE_MULTI_THREAD == 1

typedef struct timespec zp_clock_t;
typedef struct timeval zp_time_t;

typedef struct {
#if Z_FEATURE_LINK_SERIAL == 1

Check warning

Code scanning / Cppcheck (reported by Codacy)

misra violation 2009 with no text in the supplied rule-texts-file Warning

misra violation 2009 with no text in the supplied rule-texts-file
FuriStreamBuffer* _rx_stream;
FuriHalSerialHandle* _serial;
#endif
} _z_sys_net_socket_t;

#endif /* ZENOH_PICO_SYSTEM_FLIPPER_TYPES_H */
6 changes: 3 additions & 3 deletions include/zenoh-pico/utils/logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ static inline void __z_print_timestamp(void) {
if (ZENOH_DEBUG >= _Z_LOG_LVL_DEBUG) { \
_Z_LOG_PREFIX(DEBUG); \
printf(__VA_ARGS__); \
printf("\n"); \
printf("\r\n"); \
} \
} while (false)

Expand All @@ -56,7 +56,7 @@ static inline void __z_print_timestamp(void) {
if (ZENOH_DEBUG >= _Z_LOG_LVL_INFO) { \
_Z_LOG_PREFIX(INFO); \
printf(__VA_ARGS__); \
printf("\n"); \
printf("\r\n"); \
} \
} while (false)

Expand All @@ -65,7 +65,7 @@ static inline void __z_print_timestamp(void) {
if (ZENOH_DEBUG >= _Z_LOG_LVL_ERROR) { \
_Z_LOG_PREFIX(ERROR); \
printf(__VA_ARGS__); \
printf("\n"); \
printf("\r\n"); \
} \
} while (false)
#endif // ZENOH_DEBUG == 0 && !defined(Z_BUILD_DEBUG)
Expand Down
18 changes: 16 additions & 2 deletions src/collections/list.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
// ZettaScale Zenoh Team, <[email protected]>
//

#include "zenoh-pico/collections/list.h"

#include <stddef.h>

#include "zenoh-pico/collections/list.h"

/*-------- Inner single-linked list --------*/
_z_list_t *_z_list_of(void *x) {
_z_list_t *xs = (_z_list_t *)zp_malloc(sizeof(_z_list_t));
Expand All @@ -32,6 +32,20 @@ _z_list_t *_z_list_push(_z_list_t *xs, void *x) {
return lst;
}

_z_list_t *_z_list_push_back(_z_list_t *xs, void *x) {
_z_list_t *l = (_z_list_t *)xs;
while (l != NULL && l->_tail != NULL) {
l = l->_tail;
}
if (l == NULL) {
l = _z_list_of(x);
return l;
} else {
l->_tail = _z_list_of(x);
return xs;
}
}

void *_z_list_head(const _z_list_t *xs) { return xs->_val; }

_z_list_t *_z_list_tail(const _z_list_t *xs) { return xs->_tail; }
Expand Down
228 changes: 228 additions & 0 deletions src/system/flipper/network.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
//
// Copyright (c) 2024 ZettaScale Technology
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
//
// Contributors:
// ZettaScale Zenoh Team, <[email protected]>
//

#include "zenoh-pico/config.h"
#include "zenoh-pico/system/link/serial.h"
#include "zenoh-pico/system/platform.h"
#include "zenoh-pico/utils/logging.h"

#if Z_FEATURE_LINK_TCP == 1
#error "TCP is not supported on Flipper port of Zenoh-Pico"
#endif

#if Z_FEATURE_LINK_UDP_UNICAST == 1 || Z_FEATURE_LINK_UDP_MULTICAST == 1

Check warning

Code scanning / Cppcheck (reported by Codacy)

misra violation 2009 with no text in the supplied rule-texts-file Warning

misra violation 2009 with no text in the supplied rule-texts-file
#error "UDP is not supported on Flipper port of Zenoh-Pico"
#endif

#if Z_FEATURE_LINK_SERIAL == 1

/*------------------ Serial sockets ------------------*/

static void _z_serial_received_byte_callback(FuriHalSerialHandle* handle, FuriHalSerialRxEvent event, void* context) {
if (!context) {
return;
}
FuriStreamBuffer* buf = context;

if (event == FuriHalSerialRxEventData) {
uint8_t data = furi_hal_serial_async_rx(handle);
furi_stream_buffer_send(buf, (void*)&data, 1, FLIPPER_SERIAL_STREAM_TRIGGERED_LEVEL);
}
}

int8_t _z_open_serial_from_pins(_z_sys_net_socket_t* sock, uint32_t txpin, uint32_t rxpin, uint32_t baudrate) {

Check warning

Code scanning / Cppcheck (reported by Codacy)

misra violation 207 with no text in the supplied rule-texts-file Warning

misra violation 207 with no text in the supplied rule-texts-file
int8_t ret = _Z_ERR_GENERIC;

return ret;
}

int8_t _z_open_serial_from_dev(_z_sys_net_socket_t* sock, char* dev, uint32_t baudrate) {
if (furi_hal_serial_control_is_busy(FuriHalSerialIdUsart)) {
_Z_ERROR("Serial port is busy");
return _Z_ERR_TRANSPORT_OPEN_FAILED;
}

FuriHalSerialId sid;
if (!strcmp(dev, "usart")) {
sid = FuriHalSerialIdUsart;
} else if (!strcmp(dev, "lpuart")) {
sid = FuriHalSerialIdLpuart;
} else {
_Z_ERROR("Unknown serial port device: %s", dev);
return _Z_ERR_TRANSPORT_OPEN_FAILED;
}

sock->_serial = furi_hal_serial_control_acquire(sid);
if (!sock->_serial) {
_Z_ERROR("Serial port control acquire failed");
return _Z_ERR_TRANSPORT_OPEN_FAILED;
};
furi_hal_serial_init(sock->_serial, baudrate);

sock->_rx_stream =
furi_stream_buffer_alloc(FLIPPER_SERIAL_STREAM_BUFFER_SIZE, FLIPPER_SERIAL_STREAM_TRIGGERED_LEVEL);
if (!sock->_rx_stream) {
_Z_ERROR("Serial stream buffer allocation failed");
return _Z_ERR_TRANSPORT_NO_SPACE;
};
furi_hal_serial_async_rx_start(sock->_serial, _z_serial_received_byte_callback, sock->_rx_stream, false);

_Z_DEBUG("Serial port opened: %s (%li)", dev, baudrate);
return _Z_RES_OK;
}

int8_t _z_listen_serial_from_pins(_z_sys_net_socket_t* sock, uint32_t txpin, uint32_t rxpin, uint32_t baudrate) {
(void)(sock);
(void)(txpin);
(void)(rxpin);
(void)(baudrate);

return _Z_ERR_GENERIC;
}

int8_t _z_listen_serial_from_dev(_z_sys_net_socket_t* sock, char* dev, uint32_t baudrate) {
(void)(sock);
(void)(dev);
(void)(baudrate);

// @TODO: To be implemented

return _Z_ERR_GENERIC;
}

void _z_close_serial(_z_sys_net_socket_t* sock) {
if (sock->_serial) {
furi_hal_serial_async_rx_stop(sock->_serial);
furi_hal_serial_deinit(sock->_serial);
furi_hal_serial_control_release(sock->_serial);

// Wait until the serial read timeout ends
zp_sleep_ms(FLIPPER_SERIAL_TIMEOUT_MS * 2);

furi_stream_buffer_free(sock->_rx_stream);

sock->_serial = 0;
sock->_rx_stream = 0;
}
_Z_DEBUG("Serial port closed");
}

size_t _z_read_serial(const _z_sys_net_socket_t sock, uint8_t* ptr, size_t len) {

Check warning

Code scanning / Cppcheck (reported by Codacy)

misra violation 207 with no text in the supplied rule-texts-file Warning

misra violation 207 with no text in the supplied rule-texts-file
int8_t ret = _Z_RES_OK;

uint8_t* before_cobs = (uint8_t*)zp_malloc(_Z_SERIAL_MAX_COBS_BUF_SIZE);
size_t rb = 0;
for (size_t i = 0; i < _Z_SERIAL_MAX_COBS_BUF_SIZE; i++) {
size_t len = 0;
len = furi_stream_buffer_receive(sock._rx_stream, &before_cobs[i], 1, FLIPPER_SERIAL_TIMEOUT_MS);
if (!len) {
zp_free(before_cobs);
return SIZE_MAX;
}
rb += 1;

if (before_cobs[i] == (uint8_t)0x00) {
break;
}
}

uint8_t* after_cobs = (uint8_t*)zp_malloc(_Z_SERIAL_MFS_SIZE);
size_t trb = _z_cobs_decode(before_cobs, rb, after_cobs);

size_t i = 0;
uint16_t payload_len = 0;
for (i = 0; i < sizeof(payload_len); i++) {
payload_len |= (after_cobs[i] << ((uint8_t)i * (uint8_t)8));
}

if (trb == (size_t)(payload_len + (uint16_t)6)) {
(void)memcpy(ptr, &after_cobs[i], payload_len);
i += (size_t)payload_len;

uint32_t crc = 0;
for (uint8_t j = 0; j < sizeof(crc); j++) {
crc |= (uint32_t)(after_cobs[i] << (j * (uint8_t)8));
i += 1;
}

uint32_t c_crc = _z_crc32(ptr, payload_len);
if (c_crc != crc) {
ret = _Z_ERR_GENERIC;
}
} else {
ret = _Z_ERR_GENERIC;
}

zp_free(before_cobs);
zp_free(after_cobs);

rb = payload_len;
if (ret != _Z_RES_OK) {
rb = SIZE_MAX;
}

return rb;
}

size_t _z_read_exact_serial(const _z_sys_net_socket_t sock, uint8_t* ptr, size_t len) {

Check warning

Code scanning / Cppcheck (reported by Codacy)

misra violation 804 with no text in the supplied rule-texts-file Warning

misra violation 804 with no text in the supplied rule-texts-file
size_t n = len;
size_t rb = 0;

Check warning

Code scanning / Cppcheck (reported by Codacy)

Variable 'rb' is assigned a value that is never used. Warning

Variable 'rb' is assigned a value that is never used.

Check warning

Code scanning / Cppcheck (reported by Codacy)

The scope of the variable 'rb' can be reduced. Warning

The scope of the variable 'rb' can be reduced.

do {
rb = _z_read_serial(sock, ptr, n);
if (rb == SIZE_MAX) {
return rb;
}
n -= rb;
ptr += len - n;

Check warning

Code scanning / Cppcheck (reported by Codacy)

misra violation 1003 with no text in the supplied rule-texts-file Warning

misra violation 1003 with no text in the supplied rule-texts-file
} while (n > 0);

return len;
}

size_t _z_send_serial(const _z_sys_net_socket_t sock, const uint8_t* ptr, size_t len) {

Check warning

Code scanning / Cppcheck (reported by Codacy)

misra violation 804 with no text in the supplied rule-texts-file Warning

misra violation 804 with no text in the supplied rule-texts-file
int8_t ret = _Z_RES_OK;

Check warning

Code scanning / Cppcheck (reported by Codacy)

Variable 'ret' is assigned a value that is never used. Warning

Variable 'ret' is assigned a value that is never used.

uint8_t* before_cobs = (uint8_t*)zp_malloc(_Z_SERIAL_MFS_SIZE);
size_t i = 0;
for (i = 0; i < sizeof(uint16_t); ++i) {
before_cobs[i] = (len >> (i * (size_t)8)) & (size_t)0XFF;
}

(void)memcpy(&before_cobs[i], ptr, len);
i += len;

uint32_t crc = _z_crc32(ptr, len);
for (uint8_t j = 0; j < sizeof(crc); j++) {
before_cobs[i] = (crc >> (j * (uint8_t)8)) & (uint32_t)0XFF;

Check warning

Code scanning / Cppcheck (reported by Codacy)

misra violation 1007 with no text in the supplied rule-texts-file Warning

misra violation 1007 with no text in the supplied rule-texts-file
i++;
}

uint8_t* after_cobs = (uint8_t*)zp_malloc(_Z_SERIAL_MAX_COBS_BUF_SIZE);
ssize_t twb = _z_cobs_encode(before_cobs, i, after_cobs);
after_cobs[twb] = 0x00; // Manually add the COBS delimiter

furi_hal_serial_tx(sock._serial, after_cobs, twb + (ssize_t)1);
furi_hal_serial_tx_wait_complete(sock._serial);

zp_free(before_cobs);
zp_free(after_cobs);

return len;
}
#endif

#if Z_FEATURE_RAWETH_TRANSPORT == 1
#error "Raw ethernet transport not supported on Flipper port of Zenoh-Pico"
#endif
Loading
Loading