From cd499f9d3730faaaff9fcc8a2d1105e088c8d88b Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Wed, 7 Dec 2022 15:51:53 +0100 Subject: [PATCH] add the NxScope library - a real-time data logging tool --- include/logging/nxscope/nxscope.h | 488 ++++++++ include/logging/nxscope/nxscope_chan.h | 419 +++++++ include/logging/nxscope/nxscope_intf.h | 126 ++ include/logging/nxscope/nxscope_proto.h | 105 ++ logging/.gitignore | 1 + logging/Make.defs | 21 + logging/Makefile | 23 + logging/nxscope/Kconfig | 56 + logging/nxscope/Make.defs | 23 + logging/nxscope/Makefile | 39 + logging/nxscope/README.md | 32 + logging/nxscope/nxscope.c | 1168 ++++++++++++++++++ logging/nxscope/nxscope_chan.c | 1503 +++++++++++++++++++++++ logging/nxscope/nxscope_idummy.c | 194 +++ logging/nxscope/nxscope_internals.c | 82 ++ logging/nxscope/nxscope_internals.h | 72 ++ logging/nxscope/nxscope_iser.c | 248 ++++ logging/nxscope/nxscope_pser.c | 293 +++++ 18 files changed, 4893 insertions(+) create mode 100644 include/logging/nxscope/nxscope.h create mode 100644 include/logging/nxscope/nxscope_chan.h create mode 100644 include/logging/nxscope/nxscope_intf.h create mode 100644 include/logging/nxscope/nxscope_proto.h create mode 100644 logging/.gitignore create mode 100644 logging/Make.defs create mode 100644 logging/Makefile create mode 100644 logging/nxscope/Kconfig create mode 100644 logging/nxscope/Make.defs create mode 100644 logging/nxscope/Makefile create mode 100644 logging/nxscope/README.md create mode 100644 logging/nxscope/nxscope.c create mode 100644 logging/nxscope/nxscope_chan.c create mode 100644 logging/nxscope/nxscope_idummy.c create mode 100644 logging/nxscope/nxscope_internals.c create mode 100644 logging/nxscope/nxscope_internals.h create mode 100644 logging/nxscope/nxscope_iser.c create mode 100644 logging/nxscope/nxscope_pser.c diff --git a/include/logging/nxscope/nxscope.h b/include/logging/nxscope/nxscope.h new file mode 100644 index 000000000..e29022235 --- /dev/null +++ b/include/logging/nxscope/nxscope.h @@ -0,0 +1,488 @@ +/**************************************************************************** + * apps/include/logging/nxscope/nxscope.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_INCLUDE_LOGGING_NXSCOPE_NXSCOPE_H +#define __APPS_INCLUDE_LOGGING_NXSCOPE_NXSCOPE_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define NXSCOPE_ENABLE_LEN (sizeof(struct nxscope_enable_data_s)) +#define NXSCOPE_DIV_LEN (sizeof(struct nxscope_div_data_s)) +#define NXSCOPE_START_LEN (sizeof(struct nxscope_start_data_s)) + +/* MSB bit in the channel type means a critical channel */ + +#define NXSCOPE_IS_CRICHAN(chtype) (chtype & 0x80) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* Nxscope header ID */ + +enum nxscope_hdr_id_e +{ + NXSCOPE_HDRID_UNDEF = 0, /* Reserved */ + + /* Stream frames */ + + NXSCOPE_HDRID_STREAM = 1, /* Stream data */ + + /* Get frames */ + + NXSCOPE_HDRID_CMNINFO = 2, /* Get nxscope common info */ + NXSCOPE_HDRID_CHINFO = 3, /* Get nxscope channel info */ + + /* Special frames */ + + NXSCOPE_HDRID_ACK = 4, /* ACK/NACK */ + + /* Set frames. + * + * If CONFIG_LOGGING_NXSCOPE_ACKFRAMES=y this requests must + * be confirmed with ACK frames to report success or failure. + */ + + NXSCOPE_HDRID_START = 5, /* Start/stop stream. + * NOTE: this frame do not follow + * 'struct nxscope_set_frame_s' format + */ + NXSCOPE_HDRID_ENABLE = 6, /* Snable/disable channels */ + NXSCOPE_HDRID_DIV = 7, /* Channels divider */ + + /* User defined frames. + * Must be alway the last element. + */ + + NXSCOPE_HDRID_USER = 8 +}; + +/* Nxscope flags */ + +enum nxscope_info_flags_e +{ + NXSCOPE_FLAGS_DIVIDER_SUPPORT = (1 << 0), + NXSCOPE_FLAGS_ACK_SUPPORT = (1 << 1), + NXSCOPE_FLAGS_RES2 = (1 << 2), + NXSCOPE_FLAGS_RES3 = (1 << 3), + NXSCOPE_FLAGS_RES4 = (1 << 4), + NXSCOPE_FLAGS_RES5 = (1 << 5), + NXSCOPE_FLAGS_RES6 = (1 << 6), + NXSCOPE_FLAGS_RES7 = (1 << 7), +}; + +/* Nxscope stream flags */ + +enum nxscope_stream_flags_s +{ + NXSCOPE_STREAM_FLAGS_OVERFLOW = (1 << 0) +}; + +/* Nxscope start frame data */ + +begin_packed_struct struct nxscope_start_data_s +{ + uint8_t start; /* Start/stop flag */ +} end_packed_struct; + +/* Nxscope enable channel data */ + +begin_packed_struct struct nxscope_enable_ch_data_s +{ + uint8_t en; /* Channel enable */ +} end_packed_struct; + +/* Nxscope divider channel data */ + +begin_packed_struct struct nxscope_div_ch_data_s +{ + uint8_t div; /* Channel divider - starts from 0 */ +} end_packed_struct; + +/* Nxscope enable frame data */ + +begin_packed_struct struct nxscope_enable_data_s +{ + struct nxscope_enable_ch_data_s ch[1]; /* Chmax elements */ +} end_packed_struct; + +/* Nxscope divider frame data */ + +begin_packed_struct struct nxscope_div_data_s +{ + struct nxscope_div_ch_data_s ch[1]; /* Chmax elements */ +} end_packed_struct; + +/* Set channel frame */ + +enum nxscope_set_frame_req_s +{ + NXSCOPE_SET_REQ_SINGLE = 0, /* Single channel request */ + NXSCOPE_SET_REQ_BULK = 1, /* Set different values for all channels */ + NXSCOPE_SET_REQ_ALL = 2 /* Set one value for all channles */ +}; + +/* Set frame common data */ + +begin_packed_struct struct nxscope_set_frame_s +{ + uint8_t req; /* Request type */ + uint8_t chan; /* Channel id */ + uint8_t data[1]; /* n bytes data - depends on the request type */ +} end_packed_struct; + +/* Chanel type */ + +begin_packed_struct struct nxscope_chinfo_type_s +{ + uint8_t dtype:5; /* Data type */ + uint8_t _res:2; /* Reserved for future use */ + uint8_t cri:1; /* Criticial channel - no buffering */ +} end_packed_struct; + +/* Chanel type union */ + +union nxscope_chinfo_type_u +{ + struct nxscope_chinfo_type_s s; + uint8_t u8; +}; + +/* Nxscope channel info */ + +begin_packed_struct struct nxscope_chinfo_s +{ + uint8_t enable; /* Enable flag */ + union nxscope_chinfo_type_u type; /* Channel data type */ + uint8_t vdim; /* Vector dimention */ + uint8_t div; /* Divider - starts from 0 */ + uint8_t mlen; /* Metadata size */ + FAR char *name; /* Chanel name */ +} end_packed_struct; + +/* Nxscope info common */ + +begin_packed_struct struct nxscope_info_cmn_s +{ + uint8_t chmax; /* Supported channels */ + uint8_t flags; /* Flags (enum nxscope_info_flags_e) */ + uint8_t rx_padding; /* RX padding (>0 if used) */ +} end_packed_struct; + +/* Nxscope sample hdr: + * + * +----------+-------------+----------+ + * | channel | sample data | metadata | + * +----------+-------------+----------+ + * | 1B | n bytes [1] | m bytes | + * +----------+-------------+----------+ + * + * [1] - sizeof(channel_type) * channel_vdim + * NOTE: sample data always little-endian ! + * + */ + +struct nxscope_sample_s +{ + uint8_t chan; /* 1 byte: Channel id - starts from 0 */ + /* n bytes: Data */ + /* m bytes: Metadata */ +}; + +/* Nxscope stream data: + * + * +----------+--------------+ + * | flags | samples data | + * +----------+--------------+ + * | 1B | n bytes | + * +----------+--------------+ + * + */ + +struct nxscope_stream_s +{ + uint8_t flags; /* stream flags */ + struct nxscope_sample_s samples[1]; /* stream samples */ +}; + +/* Nxscope callbacks */ + +struct nxscope_callbacks_s +{ + /* User-defined id callback */ + + FAR void *userid_priv; + CODE int (*userid)(FAR void *priv, uint8_t id, FAR uint8_t *buff); + + /* Start request callback */ + + FAR void *start_priv; + CODE int (*start)(FAR void *priv, bool start); +}; + +/* Nxscope general configuration */ + +struct nxscope_cfg_s +{ + /* NOTE: It is possible to configure separate interface + * and protocol for control commands and data stream. + */ + + /* Interface implementation for commands */ + + FAR struct nxscope_intf_s *intf_cmd; + + /* Interface implementation for stream data */ + + FAR struct nxscope_intf_s *intf_stream; + + /* Protocol implementation for commands */ + + FAR struct nxscope_proto_s *proto_cmd; + + /* Protocol implementation for stream data */ + + FAR struct nxscope_proto_s *proto_stream; + + /* Callbacks */ + + FAR struct nxscope_callbacks_s *callbacks; + + /* Number of suppoted channels */ + + uint8_t channels; + + /* Stream buffer len */ + + size_t streambuf_len; + + /* RX buffer len */ + + size_t rxbuf_len; + +#ifdef CONFIG_LOGGING_NXSCOPE_CRICHANNELS + /* Critical buffer len. + * + * It's the user's responsibility to correctly choose this value. + * The minimal buffer size for critical channels can be calculate + * with this formula: + * buff_size = max(proto_stream->hdrlen + 1 + type_size * vdim + + * meta_len + proto_stream->footlen) + * + * where max() means the maximum value from all initialized critical + * channels. + * + * When CONFIG_DEBUG_FEATURES is enabled the correct buffer size is + * verified in run-time. + */ + + size_t cribuf_len; +#endif + + /* RX padding. + * + * This option will be provided for client in common info data + * and can be useful if we use DMA for receiving frames + */ + + uint8_t rx_padding; +}; + +/* Nxscope data */ + +struct nxscope_s +{ + /* Nxscope interface handlers */ + + FAR struct nxscope_intf_s *intf_cmd; + FAR struct nxscope_intf_s *intf_stream; + + /* Nxscope protocol handlers */ + + FAR struct nxscope_proto_s *proto_cmd; + FAR struct nxscope_proto_s *proto_stream; + + /* Callbacks */ + + FAR struct nxscope_callbacks_s *callbacks; + + /* Nxscope common info */ + + struct nxscope_info_cmn_s cmninfo; + + /* Channels info, chmax elements */ + + FAR struct nxscope_chinfo_s *chinfo; + size_t chinfo_size; + + /* Nxscope data */ + +#ifdef CONFIG_LOGGING_NXSCOPE_DIVIDER + FAR uint32_t *cntr; +#endif + uint8_t start; + + /* Stream data */ + + FAR uint8_t *streambuf; + size_t streambuf_len; + size_t stream_i; + +#ifdef CONFIG_LOGGING_NXSCOPE_CRICHANNELS + /* Critical buffer data */ + + FAR uint8_t *cribuf; + size_t cribuf_len; +#endif + + /* RX data buffer */ + + FAR uint8_t *rxbuf; + size_t rxbuf_len; + size_t rxbuf_i; + + /* TX data buffer */ + + FAR uint8_t *txbuf; + size_t txbuf_len; + + /* Exclusive access */ + + pthread_mutex_t lock; +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: nxscope_init + * + * Description: + * Initialize a nxscope instance + * + * Input Parameters: + * s - a pointer to a nxscope instance + * cfg - a pointer to a nxscope configuration data + * + ****************************************************************************/ + +int nxscope_init(FAR struct nxscope_s *s, FAR struct nxscope_cfg_s *cfg); + +/**************************************************************************** + * Name: nxscope_deinit + * + * Description: + * De-initialize a nxscope instance + * + * Input Parameters: + * s - a pointer to a nxscope instance + * + ****************************************************************************/ + +void nxscope_deinit(FAR struct nxscope_s *s); + +/**************************************************************************** + * Name: nxscope_lock + * + * Description: + * Lock a nxscope instance + * + * Input Parameters: + * s - a pointer to a nxscope instance + * + ****************************************************************************/ + +void nxscope_lock(FAR struct nxscope_s *s); + +/**************************************************************************** + * Name: nxscope_unlock + * + * Description: + * Unlock a nxscope instance + * + * Input Parameters: + * s - a pointer to a nxscope instance + * + ****************************************************************************/ + +void nxscope_unlock(FAR struct nxscope_s *s); + +/**************************************************************************** + * Name: nxscope_stream + * + * Description: + * Send nxscope stream data. + * + * NOTE: It's the user's responsibility to periodically call this function. + * + * Input Parameters: + * s - a pointer to a nxscope instance + * + ****************************************************************************/ + +int nxscope_stream(FAR struct nxscope_s *s); + +/**************************************************************************** + * Name: nxscope_recv + * + * Description: + * Receive and handle nxscope protocol data. + * + * NOTE: It's the user's responsibility to periodically call this function. + * + * Input Parameters: + * s - a pointer to a nxscope instance + * + ****************************************************************************/ + +int nxscope_recv(FAR struct nxscope_s *s); + +/**************************************************************************** + * Name: nxscope_stream_start + * + * Description: + * Start/stop data stream + * + * Input Parameters: + * s - a pointer to a nxscope instance + * start - start/stop + * + ****************************************************************************/ + +int nxscope_stream_start(FAR struct nxscope_s *s, bool start); + +#endif /* __APPS_INCLUDE_LOGGING_NXSCOPE_NXSCOPE_H */ diff --git a/include/logging/nxscope/nxscope_chan.h b/include/logging/nxscope/nxscope_chan.h new file mode 100644 index 000000000..ee6f5fad5 --- /dev/null +++ b/include/logging/nxscope/nxscope_chan.h @@ -0,0 +1,419 @@ +/**************************************************************************** + * apps/include/logging/nxscope/nxscope_chan.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_INCLUDE_LOGGING_NXSCOPE_NXSCOPE_CHAN_H +#define __APPS_INCLUDE_LOGGING_NXSCOPE_NXSCOPE_CHAN_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* Nxscope sample type */ + +enum nxscope_sample_dtype_e +{ + /* Default numerical types */ + + NXSCOPE_TYPE_UNDEF = 0, + NXSCOPE_TYPE_NONE = 1, + NXSCOPE_TYPE_UINT8 = 2, + NXSCOPE_TYPE_INT8 = 3, + NXSCOPE_TYPE_UINT16 = 4, + NXSCOPE_TYPE_INT16 = 5, + NXSCOPE_TYPE_UINT32 = 6, + NXSCOPE_TYPE_INT32 = 7, + NXSCOPE_TYPE_UINT64 = 8, + NXSCOPE_TYPE_INT64 = 9, + NXSCOPE_TYPE_FLOAT = 10, + NXSCOPE_TYPE_DOUBLE = 11, + NXSCOPE_TYPE_UB8 = 12, + NXSCOPE_TYPE_B8 = 13, + NXSCOPE_TYPE_UB16 = 14, + NXSCOPE_TYPE_B16 = 15, + NXSCOPE_TYPE_UB32 = 16, + NXSCOPE_TYPE_B32 = 17, + + /* Char/string data */ + + NXSCOPE_TYPE_CHAR = 18, + +#if 0 + /* Reserved for future use */ + + NXSCOPE_TYPE_WCHAR = 19, +#endif + +#ifdef CONFIG_LOGGING_NXSCOPE_USERTYPES + /* User defined types starts from here. + * NXSCOPE_TYPE_USER must be always the last element. + * + * Type of size 1B. Together with channel.vdim this + * can be used to send custom protocol data. + */ + + NXSCOPE_TYPE_USER = 20, +#endif + + /* 5 bits reserved for data type */ + + NXSCOPE_TYPE_LAST = 31, +}; + +/* Forward declaration */ + +struct nxscope_s; + +/**************************************************************************** + * Public Function Puttypes + ****************************************************************************/ + +/**************************************************************************** + * Name: nxscope_chan_init + * + * Description: + * Initialize nxscope channel + * + * Input Parameters: + * s - a pointer to a nxscope instance + * ch - a channel id + * name - a channel name + * type - a channel data type (union nxscope_chinfo_type_u) + * vdim - a vector data dimension (vdim=1 for a point) + * mlen - a length of metadata + * + ****************************************************************************/ + +int nxscope_chan_init(FAR struct nxscope_s *s, uint8_t ch, + FAR char *name, uint8_t type, uint8_t vdim, + uint8_t mlen); + +/**************************************************************************** + * Name: nxscope_chan_en + * + * Description: + * Enable/disable a given channel + * + * Input Parameters: + * s - a pointer to a nxscope instance + * ch - a channel id + * en - enable/disable + * + ****************************************************************************/ + +int nxscope_chan_en(FAR struct nxscope_s *s, uint8_t chan, bool en); + +#ifdef CONFIG_LOGGING_NXSCOPE_DIVIDER +/**************************************************************************** + * Name: nxscope_chan_div + * + * Description: + * Configure divider for a given channel + * + * Input Parameters: + * s - a pointer to a nxscope instance + * ch - a channel id + * div - divider value - starts from 0 + * + ****************************************************************************/ + +int nxscope_chan_div(FAR struct nxscope_s *s, uint8_t chan, uint8_t div); +#endif + +/**************************************************************************** + * Name: nxscope_chan_all_en + * + * Description: + * Enable/disable all channels + * + * Input Parameters: + * s - a pointer to a nxscope instance + * en - enable/disable + * + ****************************************************************************/ + +int nxscope_chan_all_en(FAR struct nxscope_s *s, bool en); + +/**************************************************************************** + * Name: nxscope_put_vXXXX_m + * + * Description: + * Put a vector with metadata on the stream buffer + * + * Input Parameters: + * s - a pointer to a nxscope instance + * ch - a channel id + * val - a pointer to a sample data vector + * d - a dimmention of sample data vector + * meta - a pointer to metadata + * mlen - a length of metadata + * + ****************************************************************************/ + +int nxscope_put_vuint8_m(FAR struct nxscope_s *s, uint8_t ch, + FAR uint8_t *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen); +int nxscope_put_vint8_m(FAR struct nxscope_s *s, uint8_t ch, + FAR int8_t *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen); +int nxscope_put_vuint16_m(FAR struct nxscope_s *s, uint8_t ch, + FAR uint16_t *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen); +int nxscope_put_vint16_m(FAR struct nxscope_s *s, uint8_t ch, + FAR int16_t *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen); +int nxscope_put_vuint32_m(FAR struct nxscope_s *s, uint8_t ch, + FAR uint32_t *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen); +int nxscope_put_vint32_m(FAR struct nxscope_s *s, uint8_t ch, + FAR int32_t *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen); +int nxscope_put_vuint64_m(FAR struct nxscope_s *s, uint8_t ch, + FAR uint64_t *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen); +int nxscope_put_vint64_m(FAR struct nxscope_s *s, uint8_t ch, + FAR int64_t *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen); +int nxscope_put_vfloat_m(FAR struct nxscope_s *s, uint8_t ch, + FAR float *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen); +int nxscope_put_vdouble_m(FAR struct nxscope_s *s, uint8_t ch, + FAR double *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen); +int nxscope_put_vub8_m(FAR struct nxscope_s *s, uint8_t ch, + FAR ub8_t *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen); +int nxscope_put_vb8_m(FAR struct nxscope_s *s, uint8_t ch, + FAR b8_t *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen); +int nxscope_put_vub16_m(FAR struct nxscope_s *s, uint8_t ch, + FAR ub16_t *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen); +int nxscope_put_vb16_m(FAR struct nxscope_s *s, uint8_t ch, + FAR b16_t *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen); +int nxscope_put_vub32_m(FAR struct nxscope_s *s, uint8_t ch, + FAR ub32_t *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen); +int nxscope_put_vb32_m(FAR struct nxscope_s *s, uint8_t ch, + FAR b32_t *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen); + +/**************************************************************************** + * Name: nxscope_put_vchar_m + * + * NOTE: if a given string is shorten than initialized channel vdim, + * we put only string bytes + '\0' + * + ****************************************************************************/ + +int nxscope_put_vchar_m(FAR struct nxscope_s *s, uint8_t ch, + FAR char *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen); + +/**************************************************************************** + * Name: nxscope_put_vXXXX + * + * Description: + * Put a vector on the stream buffer + * + * Input Parameters: + * s - a pointer to a nxscope instance + * ch - a channel id + * val - a pointer to a sample data vector + * d - a dimmention of sample data vector + * + ****************************************************************************/ + +int nxscope_put_vuint8(FAR struct nxscope_s *s, uint8_t ch, + FAR uint8_t *val, uint8_t d); +int nxscope_put_vint8(FAR struct nxscope_s *s, uint8_t ch, + FAR int8_t *val, uint8_t d); +int nxscope_put_vuint16(FAR struct nxscope_s *s, uint8_t ch, + FAR uint16_t *val, uint8_t d); +int nxscope_put_vint16(FAR struct nxscope_s *s, uint8_t ch, + FAR int16_t *val, uint8_t d); +int nxscope_put_vuint32(FAR struct nxscope_s *s, uint8_t ch, + FAR uint32_t *val, uint8_t d); +int nxscope_put_vint32(FAR struct nxscope_s *s, uint8_t ch, + FAR int32_t *val, uint8_t d); +int nxscope_put_vuint64(FAR struct nxscope_s *s, uint8_t ch, + FAR uint64_t *val, uint8_t d); +int nxscope_put_vint64(FAR struct nxscope_s *s, uint8_t ch, + FAR int64_t *val, uint8_t d); +int nxscope_put_vfloat(FAR struct nxscope_s *s, uint8_t ch, + FAR float *val, uint8_t d); +int nxscope_put_vdouble(FAR struct nxscope_s *s, uint8_t ch, + FAR double *val, uint8_t d); +int nxscope_put_vub8(FAR struct nxscope_s *s, uint8_t ch, + FAR ub8_t *val, uint8_t d); +int nxscope_put_vb8(FAR struct nxscope_s *s, uint8_t ch, + FAR b8_t *val, uint8_t d); +int nxscope_put_vub16(FAR struct nxscope_s *s, uint8_t ch, + FAR ub16_t *val, uint8_t d); +int nxscope_put_vb16(FAR struct nxscope_s *s, uint8_t ch, + FAR b16_t *val, uint8_t d); +int nxscope_put_vub32(FAR struct nxscope_s *s, uint8_t ch, + FAR ub32_t *val, uint8_t d); +int nxscope_put_vb32(FAR struct nxscope_s *s, uint8_t ch, + FAR b32_t *val, uint8_t d); + +/**************************************************************************** + * Name: nxscope_put_vchar + * + * NOTE: if a given string is shorten than initialized channel vdim, + * we put only string bytes + '\0' + * + ****************************************************************************/ + +int nxscope_put_vchar(FAR struct nxscope_s *s, uint8_t ch, + FAR char *val, uint8_t d); + +/**************************************************************************** + * Name: nxscope_put_XXXX_m + * + * Description: + * Put a point with metadata on the stream buffer + * + * Input Parameters: + * s - a pointer to a nxscope instance + * ch - a channel id + * val - sample data + * meta - a pointer to metadata + * mlen - a length of metadata + * + ****************************************************************************/ + +int nxscope_put_uint8_m(FAR struct nxscope_s *s, uint8_t ch, uint8_t val, + FAR uint8_t *meta, uint8_t mlen); +int nxscope_put_int8_m(FAR struct nxscope_s *s, uint8_t ch, int8_t val, + FAR uint8_t *meta, uint8_t mlen); +int nxscope_put_uint16_m(FAR struct nxscope_s *s, uint8_t ch, uint16_t val, + FAR uint8_t *meta, uint8_t mlen); +int nxscope_put_int16_m(FAR struct nxscope_s *s, uint8_t ch, int16_t val, + FAR uint8_t *meta, uint8_t mlen); +int nxscope_put_uint32_m(FAR struct nxscope_s *s, uint8_t ch, uint32_t val, + FAR uint8_t *meta, uint8_t mlen); +int nxscope_put_int32_m(FAR struct nxscope_s *s, uint8_t ch, int32_t val, + FAR uint8_t *meta, uint8_t mlen); +int nxscope_put_uint64_m(FAR struct nxscope_s *s, uint8_t ch, uint64_t val, + FAR uint8_t *meta, uint8_t mlen); +int nxscope_put_int64_m(FAR struct nxscope_s *s, uint8_t ch, int64_t val, + FAR uint8_t *meta, uint8_t mlen); +int nxscope_put_float_m(FAR struct nxscope_s *s, uint8_t ch, float val, + FAR uint8_t *meta, uint8_t mlen); +int nxscope_put_double_m(FAR struct nxscope_s *s, uint8_t ch, double val, + FAR uint8_t *meta, uint8_t mlen); +int nxscope_put_ub8_m(FAR struct nxscope_s *s, uint8_t ch, ub8_t val, + FAR uint8_t *meta, uint8_t mlen); +int nxscope_put_b8_m(FAR struct nxscope_s *s, uint8_t ch, b8_t val, + FAR uint8_t *meta, uint8_t mlen); +int nxscope_put_ub16_m(FAR struct nxscope_s *s, uint8_t ch, ub16_t val, + FAR uint8_t *meta, uint8_t mlen); +int nxscope_put_b16_m(FAR struct nxscope_s *s, uint8_t ch, b16_t val, + FAR uint8_t *meta, uint8_t mlen); +int nxscope_put_ub32_m(FAR struct nxscope_s *s, uint8_t ch, ub32_t val, + FAR uint8_t *meta, uint8_t mlen); +int nxscope_put_b32_m(FAR struct nxscope_s *s, uint8_t ch, b32_t val, + FAR uint8_t *meta, uint8_t mlen); +int nxscope_put_char_m(FAR struct nxscope_s *s, uint8_t ch, char val, + FAR uint8_t *meta, uint8_t mlen); + +/**************************************************************************** + * Name: nxscope_put_none_m + * + * Description: + * Put metadata only on the stream buffer + * + * Input Parameters: + * s - a pointer to a nxscope instance + * ch - a channel id + * meta - a pointer to metadata + * mlen - a length of metadata + * + ****************************************************************************/ + +int nxscope_put_none_m(FAR struct nxscope_s *s, uint8_t ch, + FAR uint8_t *meta, uint8_t mlen); + +#ifdef CONFIG_LOGGING_NXSCOPE_USERTYPES +/**************************************************************************** + * Name: nxscope_put_user_m + * + * Description: + * Put a user specific data on the stream buffer + * + * Input Parameters: + * s - a pointer to a nxscope instance + * type - a channel type (starts from NXSCOPE_TYPE_USER) + * ch - a channel id + * val - a pointer to a sample data vector + * d - a dimmention of sample data vector + * meta - a pointer to metadata + * mlen - a length of metadata + * + ****************************************************************************/ + +int nxscope_put_user_m(FAR struct nxscope_s *s, uint8_t ch, uint8_t type, + FAR uint8_t *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen); +#endif + +/**************************************************************************** + * Name: nxscope_put_user_m + * + * Description: + * Put a point on the stream buffer + * + * Input Parameters: + * s - a pointer to a nxscope instance + * ch - a channel id + * val - sample data + * + ****************************************************************************/ + +int nxscope_put_uint8(FAR struct nxscope_s *s, uint8_t ch, uint8_t val); +int nxscope_put_int8(FAR struct nxscope_s *s, uint8_t ch, int8_t val); +int nxscope_put_uint16(FAR struct nxscope_s *s, uint8_t ch, uint16_t val); +int nxscope_put_int16(FAR struct nxscope_s *s, uint8_t ch, int16_t val); +int nxscope_put_uint32(FAR struct nxscope_s *s, uint8_t ch, uint32_t val); +int nxscope_put_int32(FAR struct nxscope_s *s, uint8_t ch, int32_t val); +int nxscope_put_uint64(FAR struct nxscope_s *s, uint8_t ch, uint64_t val); +int nxscope_put_int64(FAR struct nxscope_s *s, uint8_t ch, int64_t val); +int nxscope_put_float(FAR struct nxscope_s *s, uint8_t ch, float val); +int nxscope_put_double(FAR struct nxscope_s *s, uint8_t ch, double val); +int nxscope_put_ub8(FAR struct nxscope_s *s, uint8_t ch, ub8_t val); +int nxscope_put_b8(FAR struct nxscope_s *s, uint8_t ch, b8_t val); +int nxscope_put_ub16(FAR struct nxscope_s *s, uint8_t ch, ub16_t val); +int nxscope_put_b16(FAR struct nxscope_s *s, uint8_t ch, b16_t val); +int nxscope_put_ub32(FAR struct nxscope_s *s, uint8_t ch, ub32_t val); +int nxscope_put_b32(FAR struct nxscope_s *s, uint8_t ch, b32_t val); +int nxscope_put_char(FAR struct nxscope_s *s, uint8_t ch, char val); + +#endif /* __APPS_INCLUDE_LOGGING_NXSCOPE_NXSCOPE_CHAN_H */ diff --git a/include/logging/nxscope/nxscope_intf.h b/include/logging/nxscope/nxscope_intf.h new file mode 100644 index 000000000..0a4aa412a --- /dev/null +++ b/include/logging/nxscope/nxscope_intf.h @@ -0,0 +1,126 @@ +/**************************************************************************** + * apps/include/logging/nxscope/nxscope_intf.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_INCLUDE_LOGGING_NXSCOPE_NXSCOPE_INTF_H +#define __APPS_INCLUDE_LOGGING_NXSCOPE_NXSCOPE_INTF_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifdef CONFIG_LOGGING_NXSCOPE_INTF_SERIAL +# include +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* Forward declaration */ + +struct nxscope_intf_s; + +/* Nxscope interface ops */ + +struct nxscope_intf_ops_s +{ + /* Send data */ + + CODE int (*send)(FAR struct nxscope_intf_s *s, FAR uint8_t *buff, int len); + + /* Receive data */ + + CODE int (*recv)(FAR struct nxscope_intf_s *s, FAR uint8_t *buff, int len); +}; + +/* Nxscope interface */ + +struct nxscope_intf_s +{ + /* Initialized flag */ + + bool initialized; + + /* Nxscope interface private data */ + + FAR void *priv; + + /* Nxscope interface ops */ + + FAR struct nxscope_intf_ops_s *ops; +}; + +#ifdef CONFIG_LOGGING_NXSCOPE_INTF_DUMMY +/* Nxscope dummy interface configuration */ + +struct nxscope_dummy_cfg_s +{ + int res; /* Reserved */ +}; +#endif + +#ifdef CONFIG_LOGGING_NXSCOPE_INTF_SERIAL +/* Nxscope serial interface configuration */ + +struct nxscope_ser_cfg_s +{ + FAR char *path; /* Device path */ + bool nonblock; /* Nonblocking operation */ + speed_t baud; /* Baud rate */ +}; +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef CONFIG_LOGGING_NXSCOPE_INTF_DUMMY +/**************************************************************************** + * Name: nxscope_dummy_init + ****************************************************************************/ + +int nxscope_dummy_init(FAR struct nxscope_intf_s *intf, + FAR struct nxscope_dummy_cfg_s *cfg); + +/**************************************************************************** + * Name: nxscope_dummy_deinit + ****************************************************************************/ + +void nxscope_dummy_deinit(FAR struct nxscope_intf_s *intf); +#endif + +#ifdef CONFIG_LOGGING_NXSCOPE_INTF_SERIAL +/**************************************************************************** + * Name: nxscope_ser_init + ****************************************************************************/ + +int nxscope_ser_init(FAR struct nxscope_intf_s *intf, + FAR struct nxscope_ser_cfg_s *cfg); + +/**************************************************************************** + * Name: nxscope_ser_deinit + ****************************************************************************/ + +void nxscope_ser_deinit(FAR struct nxscope_intf_s *intf); +#endif + +#endif /* __APPS_INCLUDE_LOGGING_NXSCOPE_NXSCOPE_INTF_H */ diff --git a/include/logging/nxscope/nxscope_proto.h b/include/logging/nxscope/nxscope_proto.h new file mode 100644 index 000000000..283b74d55 --- /dev/null +++ b/include/logging/nxscope/nxscope_proto.h @@ -0,0 +1,105 @@ +/**************************************************************************** + * apps/include/logging/nxscope/nxscope_proto.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_INCLUDE_LOGGING_NXSCOPE_NXSCOPE_PROTO_H +#define __APPS_INCLUDE_LOGGING_NXSCOPE_NXSCOPE_PROTO_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* Nxscope frame handler */ + +struct nxscope_frame_s +{ + uint8_t id; /* Frame id */ + size_t drop; /* Data to be droped from recv buffer */ + size_t dlen; /* Data len (without header and footer) */ + FAR uint8_t *data; /* A pointer to a frame data */ +}; + +/* Forward declaration */ + +struct nxscope_proto_s; + +/* Nxscope protocol ops */ + +struct nxscope_proto_ops_s +{ + /* Get a frame from a buffer */ + + CODE int (*frame_get)(FAR struct nxscope_proto_s *p, + FAR uint8_t *buff, size_t len, + FAR struct nxscope_frame_s *frame); + + /* Finalize a frame in a given buffer */ + + CODE int (*frame_final)(FAR struct nxscope_proto_s *p, + uint8_t id, + FAR uint8_t *buff, FAR size_t *len); +}; + +/* Nxscope protocol handler */ + +struct nxscope_proto_s +{ + /* Initialized flag */ + + bool initialized; + + /* Nxscope protocol private data */ + + FAR void *priv; + + /* Nxscope protocol ops */ + + FAR struct nxscope_proto_ops_s *ops; + + /* Header and foot size */ + + size_t hdrlen; + size_t footlen; +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef CONFIG_LOGGING_NXSCOPE_PROTO_SER +/**************************************************************************** + * Name: nxscope_proto_ser_init + ****************************************************************************/ + +int nxscope_proto_ser_init(FAR struct nxscope_proto_s *proto, FAR void *cfg); + +/**************************************************************************** + * Name: nxscope_proto_ser_deinit + ****************************************************************************/ + +void nxscope_proto_ser_deinit(FAR struct nxscope_proto_s *proto); +#endif + +#endif /* __APPS_INCLUDE_LOGGING_NXSCOPE_NXSCOPE_PROTO_H */ diff --git a/logging/.gitignore b/logging/.gitignore new file mode 100644 index 000000000..9e1d2593e --- /dev/null +++ b/logging/.gitignore @@ -0,0 +1 @@ +/Kconfig diff --git a/logging/Make.defs b/logging/Make.defs new file mode 100644 index 000000000..458180da9 --- /dev/null +++ b/logging/Make.defs @@ -0,0 +1,21 @@ +############################################################################ +# apps/logging/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(wildcard $(APPDIR)/logging/*/Make.defs) diff --git a/logging/Makefile b/logging/Makefile new file mode 100644 index 000000000..e83806254 --- /dev/null +++ b/logging/Makefile @@ -0,0 +1,23 @@ +############################################################################ +# apps/logging/Makefile +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +MENUDESC = "Logging Utilities" + +include $(APPDIR)/Directory.mk diff --git a/logging/nxscope/Kconfig b/logging/nxscope/Kconfig new file mode 100644 index 000000000..1fa24c645 --- /dev/null +++ b/logging/nxscope/Kconfig @@ -0,0 +1,56 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config LOGGING_NXSCOPE + bool "NxScope interface" + default n + +if LOGGING_NXSCOPE + +config LOGGING_NXSCOPE_INTF_SERIAL + bool "NxScope serial port interface support" + select SERIAL_TERMIOS + default n + ---help--- + For details, see logging/nxscope/nxscope_iserial.c + +config LOGGING_NXSCOPE_INTF_DUMMY + bool "NxScope dummy interface support" + default n + ---help--- + Useful for debug purposes. For details, see logging/nxscope/nxscope_idummy.c + +config LOGGING_NXSCOPE_PROTO_SER + bool "NxScope default serial protocol support" + default y + ---help--- + For frame details, see logging/nxscope/nxscope_pser.c + +config LOGGING_NXSCOPE_DIVIDER + bool "NxScope support for samples divider" + default n + ---help--- + This option enables interface that allows you to reduce + the rate of samples written to the stream buffer. + +config LOGGING_NXSCOPE_ACKFRAMES + bool "NxScope support for ACK frames" + default n + ---help--- + This option enables ACK frames for set requests + +config LOGGING_NXSCOPE_USERTYPES + bool "NxScope support for user types" + default n + ---help--- + This option enables user-defined frames (see enum nxscope_hdr_id_e) + +config LOGGING_NXSCOPE_CRICHANNELS + bool "NxScope support for critical channels" + default n + ---help--- + Enable the support for non-buffered critical channels + +endif # LOGGING_NXSCOPE diff --git a/logging/nxscope/Make.defs b/logging/nxscope/Make.defs new file mode 100644 index 000000000..1007faa7e --- /dev/null +++ b/logging/nxscope/Make.defs @@ -0,0 +1,23 @@ +############################################################################ +# apps/logging/nxscope/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifneq ($(CONFIG_LOGGING_NXSCOPE),) +CONFIGURED_APPS += $(APPDIR)/logging/nxscope +endif diff --git a/logging/nxscope/Makefile b/logging/nxscope/Makefile new file mode 100644 index 000000000..d089adfd8 --- /dev/null +++ b/logging/nxscope/Makefile @@ -0,0 +1,39 @@ +############################################################################ +# apps/logging/nxscope/Makefile +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +# NxScope Library + +CSRCS = nxscope.c nxscope_chan.c nxscope_internals.c + +ifeq ($(CONFIG_LOGGING_NXSCOPE_INTF_SERIAL),y) +CSRCS += nxscope_iser.c +endif + +ifeq ($(CONFIG_LOGGING_NXSCOPE_INTF_DUMMY),y) +CSRCS += nxscope_idummy.c +endif + +ifeq ($(CONFIG_LOGGING_NXSCOPE_PROTO_SER),y) +CSRCS += nxscope_pser.c +endif + +include $(APPDIR)/Application.mk diff --git a/logging/nxscope/README.md b/logging/nxscope/README.md new file mode 100644 index 000000000..9804d5970 --- /dev/null +++ b/logging/nxscope/README.md @@ -0,0 +1,32 @@ +# `NxScope Library` + +This library provides real-time data logging functionality for NuttX. + +The principle of action is to accumulate data gathered in virtual channels +and periodically send buffered data through a dedicated interface packed +with a custom protocol. + +Supported features: + - up to 255 channels possible + - support for standard data types and user-specific data (`enum nxscope_sample_dtype_e`) + - support for vector data or point data + - support for character-based channels (text messages) + - support for channel metadata - can be used to enumerate samples or timestamp + - stream buffer overflow detection (`NXSCOPE_STREAM_FLAGS_OVERFLOW`) + - remote control with commands (`enum nxscope_hdr_id_e`) + - protocol and interface implementation can be different for control commands and stream data + - (optional) support for user-specific commands (`NXSCOPE_HDRID_USER` and `struct nxscope_callbacks_s`) + - (optional) support for samples divider (`CONFIG_LOGGING_NXSCOPE_DIVIDER`) + - (optional) support for ACK frames (`CONFIG_LOGGING_NXSCOPE_ACKFRAMES`) + - (optional) support for user-defined types (`CONFIG_LOGGING_NXSCOPE_USERTYPES`) + - (optional) support for non-buffered critical channels (`CONFIG_LOGGING_NXSCOPE_CRICHANNELS`) + +A custom interface and a custom protocol can be implemented with +`struct nxscope_intf_s` and `struct nxscope_proto_s` structures. + +Supported interfaces: + 1. a serial port: `logging/nxscope/nxscope_iser.c` + 2. a dummy interface for debug purposes: `logging/nxscope/nxscope_idummy.c` + +A default serial protocol is implemented in `apps/logging/nxscope/nxscope_pser.c` +It just packs NxScope data into simple frames with a CRC-16 checksum. diff --git a/logging/nxscope/nxscope.c b/logging/nxscope/nxscope.c new file mode 100644 index 000000000..eced4a6a4 --- /dev/null +++ b/logging/nxscope/nxscope.c @@ -0,0 +1,1168 @@ +/**************************************************************************** + * apps/logging/nxscope/nxscope.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include + +#include "nxscope_internals.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* NOTE: channel name is always terminated with a null-character */ + +#define CHINFO_DATA_SIZE_MAX (sizeof(struct nxscope_chinfo_s) - \ + sizeof(char *) + CHAN_NAMELEN_MAX + 1) + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxscope_frame_send + * + * NOTE: This function assumes that we have exclusive access to the nxscope + * instance + * + ****************************************************************************/ + +static int nxscope_frame_send(FAR struct nxscope_s *s, uint8_t id, + FAR uint8_t *data, size_t dlen) +{ + size_t tx_i = 0; + int ret = OK; + + DEBUGASSERT(s); + DEBUGASSERT(data); + +#ifdef CONFIG_DEBUG_FEATURES + /* Validate TX buffer space */ + + if (s->txbuf_len < dlen + s->proto_cmd->footlen + s->proto_cmd->hdrlen) + { + ret = -ENOBUFS; + _err("ERROR: no space in txbuf %d\n", ret); + goto errout; + } +#endif + + /* Offset for hdr */ + + tx_i = s->proto_cmd->hdrlen; + + /* Copy data */ + + memcpy(&s->txbuf[tx_i], data, dlen); + tx_i += dlen; + + /* Finalize a new frame */ + + ret = PROTO_FRAME_FINAL(s, s->proto_cmd, id, s->txbuf, &tx_i); + if (ret < 0) + { + _err("ERROR: PROTO_FRAME_FINAL failed %d\n", ret); + goto errout; + } + + /* Send frame */ + + ret = INTF_SEND(s, s->intf_cmd, s->txbuf, tx_i); + if (ret < 0) + { + _err("ERROR: INTF_SEND failed %d\n", ret); + } + +errout: + return ret; +} + +/**************************************************************************** + * Name: nxscope_cmninfo_send + * + * NOTE: This function assumes that we have exclusive access to the nxscope + * instance + * + ****************************************************************************/ + +static int nxscope_cmninfo_send(FAR struct nxscope_s *s) +{ + DEBUGASSERT(s); + + return nxscope_frame_send(s, + NXSCOPE_HDRID_CMNINFO, + (FAR uint8_t *)&s->cmninfo, + sizeof(struct nxscope_info_cmn_s)); +} + +/**************************************************************************** + * Name: nxscope_chinfo_send + * + * NOTE: This function assumes that we have exclusive access to the nxscope + * instance + * + ****************************************************************************/ + +static int nxscope_chinfo_send(FAR struct nxscope_s *s, uint8_t ch) +{ + uint8_t data[CHINFO_DATA_SIZE_MAX]; + size_t namelen = 0; + size_t txlen = 0; + size_t tmp = 0; + + DEBUGASSERT(s); + + /* Copy channel info */ + + tmp = sizeof(struct nxscope_chinfo_s) - sizeof(char *); + memcpy(data, &s->chinfo[ch], tmp); + + namelen = strnlen(s->chinfo[ch].name, CHAN_NAMELEN_MAX); + memcpy(&data[tmp], s->chinfo[ch].name, namelen); + + /* Treminate name wit a null-character */ + + txlen = tmp + namelen + 1; + data[txlen - 1] = '\0'; + + /* Send frame */ + + return nxscope_frame_send(s, NXSCOPE_HDRID_CHINFO, data, txlen); +} + +/**************************************************************************** + * Name: nxscope_enable_req + * + * NOTE: This function assumes that we have exclusive access to the nxscope + * instance + * + ****************************************************************************/ + +static int nxscope_enable_req(FAR struct nxscope_s *s, + FAR struct nxscope_set_frame_s *set, + uint16_t dlen) +{ + FAR struct nxscope_enable_data_s *data = NULL; + int ret = OK; + int i = 0; + + DEBUGASSERT(s); + DEBUGASSERT(set); + + /* Get data */ + + data = (FAR struct nxscope_enable_data_s *) set->data; + + /* Handle set request */ + + switch (set->req) + { + case NXSCOPE_SET_REQ_SINGLE: + { + /* Verify request length */ + + if (dlen != (sizeof(struct nxscope_set_frame_s) + + NXSCOPE_ENABLE_LEN - 1)) + { + _err("ERROR: invalid enable single dlen = %d\n", dlen); + ret = -EINVAL; + goto errout; + } + + /* Validate data */ + + if (data->ch[0].en != 0 && data->ch[0].en != 1) + { + ret = -EINVAL; + goto errout; + } + + if (set->chan > s->cmninfo.chmax) + { + ret = -EINVAL; + goto errout; + } + + /* Write configuration */ + + s->chinfo[set->chan].enable = data->ch[0].en; + + break; + } + + case NXSCOPE_SET_REQ_BULK: + { + /* Verify request length */ + + if (dlen != (sizeof(struct nxscope_set_frame_s) + + NXSCOPE_ENABLE_LEN * s->cmninfo.chmax - 1)) + { + _err("ERROR: invalid enable bulk dlen = %d\n", dlen); + ret = -EINVAL; + goto errout; + } + + /* Validate data */ + + for (i = 0; i < s->cmninfo.chmax; i++) + { + if (data->ch[i].en != 0 && data->ch[i].en != 1) + { + ret = -EINVAL; + goto errout; + } + } + + /* Write configuration */ + + for (i = 0; i < s->cmninfo.chmax; i++) + { + s->chinfo[i].enable = data->ch[i].en; + } + + break; + } + + case NXSCOPE_SET_REQ_ALL: + { + /* Verify request length */ + + if (dlen != (sizeof(struct nxscope_set_frame_s) + + NXSCOPE_ENABLE_LEN - 1)) + { + _err("ERROR: invalid enable all dlen = %d\n", dlen); + ret = -EINVAL; + goto errout; + } + + if (data->ch[0].en != 0 && data->ch[0].en != 1) + { + ret = -EINVAL; + goto errout; + } + + /* Write configuration */ + + for (i = 0; i < s->cmninfo.chmax; i++) + { + s->chinfo[i].enable = data->ch[0].en; + } + + break; + } + + default: + { + _err("ERROR: invalid set->req=%d\n", set->req); + ret = -EINVAL; + break; + } + } + +errout: + return ret; +} + +#ifdef CONFIG_LOGGING_NXSCOPE_DIVIDER +/**************************************************************************** + * Name: nxscope_div_req + * + * NOTE: This function assumes that we have exclusive access to the nxscope + * instance + * + ****************************************************************************/ + +static int nxscope_div_req(FAR struct nxscope_s *s, + FAR struct nxscope_set_frame_s *set, + uint16_t dlen) +{ + FAR struct nxscope_div_data_s *data = NULL; + int ret = OK; + int i = 0; + + DEBUGASSERT(s); + DEBUGASSERT(set); + + /* Get data */ + + data = (FAR struct nxscope_div_data_s *)set->data; + + /* Handle set request */ + + switch (set->req) + { + case NXSCOPE_SET_REQ_SINGLE: + { + /* Verify request length */ + + if (dlen != (sizeof(struct nxscope_set_frame_s) + + NXSCOPE_DIV_LEN - 1)) + { + _err("ERROR: invalid div single dlen = %d\n", dlen); + ret = -EINVAL; + goto errout; + } + + if (set->chan > s->cmninfo.chmax) + { + ret = -EINVAL; + goto errout; + } + + /* Write configuration */ + + s->chinfo[set->chan].div = data->ch[0].div; + + break; + } + + case NXSCOPE_SET_REQ_BULK: + { + /* Verify request length */ + + if (dlen != (sizeof(struct nxscope_set_frame_s) + + NXSCOPE_DIV_LEN * s->cmninfo.chmax - 1)) + { + _err("ERROR: invalid div bulk dlen = %d\n", dlen); + ret = -EINVAL; + goto errout; + } + + /* Write configuration */ + + for (i = 0; i < s->cmninfo.chmax; i++) + { + s->chinfo[i].div = data->ch[i].div; + } + + break; + } + + case NXSCOPE_SET_REQ_ALL: + { + /* Verify request length */ + + if (dlen != (sizeof(struct nxscope_set_frame_s) + + NXSCOPE_DIV_LEN - 1)) + { + _err("ERROR: invalid div all dlen = %d\n", dlen); + ret = -EINVAL; + goto errout; + } + + /* Write configuration */ + + for (i = 0; i < s->cmninfo.chmax; i++) + { + s->chinfo[i].div = data->ch[0].div; + } + + break; + } + + default: + { + _err("ERROR: invalid set->req=%d\n", set->req); + ret = -EINVAL; + break; + } + } + +errout: + return ret; +} +#endif + +/**************************************************************************** + * Name: nxscope_start_set + * + * NOTE: This function assumes that we have exclusive access to the nxscope + * instance + * + ****************************************************************************/ + +static int nxscope_start_set(FAR struct nxscope_s *s, bool start) +{ + int ret = OK; + + s->start = start; + + /* User specific callback */ + + if (s->callbacks != NULL && s->callbacks->start != NULL) + { + ret = s->callbacks->start(s->callbacks->start_priv, start); + if (ret < 0) + { + _err("ERROR: s->callbacks->start failed %d\n", ret); + } + } + + return ret; +} + +/**************************************************************************** + * Name: nxscope_start_req + * + * NOTE: This function assumes that we have exclusive access to the nxscope + * instance + * + ****************************************************************************/ + +static int nxscope_start_req(FAR struct nxscope_s *s, + FAR struct nxscope_start_data_s *data) +{ + int ret = -EINVAL; + + DEBUGASSERT(s); + DEBUGASSERT(data); + + if (data->start == 0 || data->start == 1) + { + _info("data->start=%d\n", data->start); + ret = nxscope_start_set(s, data->start); + } + + return ret; +} + +/**************************************************************************** + * Name: nxscope_stream_reset + * + * NOTE: This function assumes that we have exclusive access to the nxscope + * instance + * + ****************************************************************************/ + +static void nxscope_stream_reset(FAR struct nxscope_s *s) +{ + DEBUGASSERT(s); + + /* Offset for hdr + 1 byte for flags */ + + s->stream_i = s->proto_stream->hdrlen + 1; + + /* Reset flags */ + + s->streambuf[s->proto_stream->hdrlen] = 0; +} + +/**************************************************************************** + * Name: nxscope_stream_empty + * + * NOTE: This function assumes that we have exclusive access to the nxscope + * instance + * + ****************************************************************************/ + +static bool nxscope_stream_empty(FAR struct nxscope_s *s) +{ + DEBUGASSERT(s); + + if (s->stream_i > s->proto_stream->hdrlen + 1) + { + return false; + } + else + { + return true; + } +} + +#ifdef CONFIG_LOGGING_NXSCOPE_ACKFRAMES +/**************************************************************************** + * Name: nxscope_ack + * + * NOTE: This function assumes that we have exclusive access to the nxscope + * instance + * + ****************************************************************************/ + +static void nxscope_ack(FAR struct nxscope_s *s, int ret) +{ + DEBUGASSERT(s); + + nxscope_frame_send(s, NXSCOPE_HDRID_ACK, (FAR uint8_t *)&ret, 4); +} +#endif + +/**************************************************************************** + * Name: nxscope_recv_handle + ****************************************************************************/ + +static int nxscope_recv_handle(FAR struct nxscope_s *s, uint8_t id, + uint16_t dlen, FAR uint8_t *buf) +{ + int ret = OK; + + DEBUGASSERT(s); + DEBUGASSERT(buf); + + nxscope_lock(s); + + switch (id) + { + case NXSCOPE_HDRID_CMNINFO: + { + _info("NXSCOPE_HDRID_CMNINFO\n"); + + /* Verify request length */ + + if (dlen != 0) + { + _err("ERROR: cmninfo request invalid dlen = %d\n", dlen); + goto errout; + } + + /* Send cmninfo response */ + + ret = nxscope_cmninfo_send(s); + + break; + } + + case NXSCOPE_HDRID_CHINFO: + { + FAR uint8_t *ch = buf; + + _info("NXSCOPE_HDRID_CHINFO %d\n", *ch); + + /* Verify request length */ + + if (dlen != 1) + { + _err("ERROR: chinfo request invalid dlen = %d\n", dlen); + goto errout; + } + + /* Send chinfo response */ + + ret = nxscope_chinfo_send(s, *ch); + + break; + } + + case NXSCOPE_HDRID_START: + { + FAR struct nxscope_start_data_s *data = + (FAR struct nxscope_start_data_s *)buf; + + _info("NXSCOPE_HDRID_START\n"); + + /* Verify request length */ + + if (dlen != NXSCOPE_START_LEN) + { + _err("ERROR: start request invalid dlen = %d\n", dlen); + goto errout; + } + + /* Start request */ + + ret = nxscope_start_req(s, data); + +#ifdef CONFIG_LOGGING_NXSCOPE_ACKFRAMES + /* Send ACK */ + + nxscope_ack(s, ret); +#endif + + break; + } + + case NXSCOPE_HDRID_ENABLE: + { + FAR struct nxscope_set_frame_s *data = + (FAR struct nxscope_set_frame_s *)buf; + + _info("NXSCOPE_HDRID_ENABLE\n"); + + /* Enable request */ + + ret = nxscope_enable_req(s, data, dlen); + +#ifdef CONFIG_LOGGING_NXSCOPE_ACKFRAMES + /* Send ACK */ + + nxscope_ack(s, ret); +#endif + + break; + } + + case NXSCOPE_HDRID_DIV: + { +#ifdef CONFIG_LOGGING_NXSCOPE_DIVIDER + FAR struct nxscope_set_frame_s *data = + (FAR struct nxscope_set_frame_s *)buf; + + _info("NXSCOPE_HDRID_DIV\n"); + + /* Divider request */ + + ret = nxscope_div_req(s, data, dlen); +#else + ret = -EPERM; +#endif + +#ifdef CONFIG_LOGGING_NXSCOPE_ACKFRAMES + /* Send ACK */ + + nxscope_ack(s, ret); +#endif + + break; + } + + default: + { + /* User specific commands */ + + if (s->callbacks != NULL && s->callbacks->userid != NULL) + { + ret = s->callbacks->userid(s->callbacks->userid_priv, id, buf); + if (ret < 0) + { + _err("ERROR: s->callbacks->userid failed %d\n", ret); + } + } + else + { + _err("ERROR: unsupported id %d\n", id); + ret = -EINVAL; + } + } + } + +errout: + nxscope_unlock(s); + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxscope_init + * + * Description: + * Initialize a nxscope instance + * + * Input Parameters: + * s - a pointer to a nxscope instance + * cfg - a pointer to a nxscope configuration data + * + ****************************************************************************/ + +int nxscope_init(FAR struct nxscope_s *s, FAR struct nxscope_cfg_s *cfg) +{ + int ret = OK; + int i = 0; + + DEBUGASSERT(s); + DEBUGASSERT(cfg); + + /* Reset structure */ + + memset(s, 0, sizeof(struct nxscope_s)); + + /* Connect command interface */ + + DEBUGASSERT(cfg->intf_cmd); + DEBUGASSERT(cfg->intf_cmd->ops->send); + DEBUGASSERT(cfg->intf_cmd->ops->recv); + + /* Must be initialized */ + + if (!cfg->intf_cmd->initialized) + { + ret = -EINVAL; + goto errout; + } + + s->intf_cmd = cfg->intf_cmd; + + /* Connect command protocol handler */ + + DEBUGASSERT(cfg->proto_cmd); + DEBUGASSERT(cfg->proto_cmd->ops->frame_get); + DEBUGASSERT(cfg->proto_cmd->ops->frame_final); + + /* Must be initialized */ + + if (!cfg->proto_cmd->initialized) + { + ret = -EINVAL; + goto errout; + } + + s->proto_cmd = cfg->proto_cmd; + + /* Connect stream interface */ + + DEBUGASSERT(cfg->intf_stream); + DEBUGASSERT(cfg->intf_stream->ops->send); + DEBUGASSERT(cfg->intf_stream->ops->recv); + + /* Must be initialized */ + + if (!cfg->intf_stream->initialized) + { + ret = -EINVAL; + goto errout; + } + + s->intf_stream = cfg->intf_stream; + + /* Connect stream protocol handler */ + + DEBUGASSERT(cfg->proto_stream); + DEBUGASSERT(cfg->proto_stream->ops->frame_get); + DEBUGASSERT(cfg->proto_stream->ops->frame_final); + + /* Must be initialized */ + + if (!cfg->proto_stream->initialized) + { + ret = -EINVAL; + goto errout; + } + + s->proto_stream = cfg->proto_stream; + + /* Connect callbacks (optional) */ + + s->callbacks = cfg->callbacks; + + /* Allocate memory for stream buffer */ + + DEBUGASSERT(cfg->streambuf_len > 0); + + s->streambuf = zalloc(cfg->streambuf_len); + if (s->streambuf == NULL) + { + ret = -errno; + _err("ERROR: streambuf zalloc failed %d\n", ret); + goto errout; + } + + s->streambuf_len = cfg->streambuf_len; + + /* Allocate memory for nxscope channels info */ + + DEBUGASSERT(cfg->channels > 0); + + s->chinfo_size = cfg->channels * sizeof(struct nxscope_chinfo_s); + + s->chinfo = zalloc(s->chinfo_size); + if (s->chinfo == NULL) + { + ret = -errno; + _err("ERROR: chinfo zalloc failed %d\n", ret); + goto errout; + } + +#ifdef CONFIG_LOGGING_NXSCOPE_DIVIDER + /* Allocate memory for divider counters */ + + s->cntr = zalloc(cfg->channels * sizeof(uint32_t)); + if (s->cntr == NULL) + { + ret = -errno; + _err("ERROR: cntr zalloc failed %d\n", ret); + goto errout; + } +#endif + + /* Allocate memory for RX buffer */ + + DEBUGASSERT(cfg->rxbuf_len > 0); + s->rxbuf_len = cfg->rxbuf_len; + + s->rxbuf = zalloc(s->chinfo_size); + if (s->rxbuf == NULL) + { + ret = -errno; + _err("ERROR: rxbuf zalloc failed %d\n", ret); + goto errout; + } + + /* Allocate memory for TX buffer. + * We must fit the longest possible CHINFO response. + */ + + s->txbuf_len = (CHINFO_DATA_SIZE_MAX + s->proto_cmd->footlen + + s->proto_cmd->hdrlen); + s->txbuf = zalloc(s->txbuf_len); + if (s->txbuf == NULL) + { + ret = -errno; + _err("ERROR: txbuf zalloc failed %d\n", ret); + goto errout; + } + +#ifdef CONFIG_LOGGING_NXSCOPE_CRICHANNELS + /* Allocate memory for critical channels buffer */ + + s->cribuf_len = cfg->cribuf_len; + s->cribuf = zalloc(s->cribuf_len); + if (s->cribuf == NULL) + { + ret = -errno; + _err("ERROR: cribuf zalloc failed %d\n", ret); + goto errout; + } +#endif + + /* Initialize lock */ + + ret = pthread_mutex_init(&s->lock, NULL); + if (ret != 0) + { + _err("ERROR: pthread_mutex_init failed %d\n", errno); + goto errout; + } + + /* Reset stream buffer */ + + nxscope_stream_reset(s); + + /* Initialize info data */ + + s->cmninfo.chmax = cfg->channels; + + s->cmninfo.flags = 0; +#ifdef CONFIG_LOGGING_NXSCOPE_DIVIDER + s->cmninfo.flags |= NXSCOPE_FLAGS_DIVIDER_SUPPORT; +#endif +#ifdef CONFIG_LOGGING_NXSCOPE_ACKFRAMES + s->cmninfo.flags |= NXSCOPE_FLAGS_ACK_SUPPORT; +#endif + + s->cmninfo.rx_padding = cfg->rx_padding; + + /* Initialize channels */ + + for (i = 0; i < cfg->channels; i++) + { + s->chinfo[i].name = "\0"; + } + + return OK; + +errout: + + if (s->streambuf != NULL) + { + free(s->streambuf); + } + + if (s->chinfo != NULL) + { + free(s->chinfo); + } + +#ifdef CONFIG_LOGGING_NXSCOPE_DIVIDER + if (s->cntr != NULL) + { + free(s->cntr); + } +#endif + + if (s->rxbuf != NULL) + { + free(s->rxbuf); + } + + if (s->txbuf != NULL) + { + free(s->txbuf); + } + +#ifdef CONFIG_LOGGING_NXSCOPE_CRICHANNELS + if (s->cribuf != NULL) + { + free(s->cribuf); + } +#endif + + return ret; +} + +/**************************************************************************** + * Name: nxscope_deinit + * + * Description: + * De-initialize a nxscope instance + * + * Input Parameters: + * s - a pointer to a nxscope instance + * + ****************************************************************************/ + +void nxscope_deinit(FAR struct nxscope_s *s) +{ + DEBUGASSERT(s); + + /* Free mutex */ + + pthread_mutex_destroy(&s->lock); + + /* Free allocated memory */ + + if (s->streambuf != NULL) + { + free(s->streambuf); + } + + if (s->chinfo != NULL) + { + free(s->chinfo); + } + +#ifdef CONFIG_LOGGING_NXSCOPE_DIVIDER + if (s->cntr != NULL) + { + free(s->cntr); + } +#endif + +#ifdef CONFIG_LOGGING_NXSCOPE_CRICHANNELS + if (s->cribuf != NULL) + { + free(s->cribuf); + } +#endif + + if (s->txbuf != NULL) + { + free(s->txbuf); + } +} + +/**************************************************************************** + * Name: nxscope_lock + * + * Description: + * Lock a nxscope instance + * + * Input Parameters: + * s - a pointer to a nxscope instance + * + ****************************************************************************/ + +void nxscope_lock(FAR struct nxscope_s *s) +{ + DEBUGASSERT(s); + + pthread_mutex_lock(&s->lock); +} + +/**************************************************************************** + * Name: nxscope_unlock + * + * Description: + * Unlock a nxscope instance + * + * Input Parameters: + * s - a pointer to a nxscope instance + * + ****************************************************************************/ + +void nxscope_unlock(FAR struct nxscope_s *s) +{ + DEBUGASSERT(s); + + pthread_mutex_unlock(&s->lock); +} + +/**************************************************************************** + * Name: nxscope_stream + * + * Description: + * Send nxscope stream data. + * + * NOTE: It's the user's responsibility to periodically call this function. + * + * Input Parameters: + * s - a pointer to a nxscope instance + * + ****************************************************************************/ + +int nxscope_stream(FAR struct nxscope_s *s) +{ + int ret = OK; + + DEBUGASSERT(s); + + nxscope_lock(s); + + /* Do nothing if stream not started */ + + if (!s->start) + { + ret = OK; + goto errout; + } + + /* Do nothing if no data */ + + if (nxscope_stream_empty(s)) + { + goto errout; + } + + /* Send stream data */ + + ret = nxscope_stream_send(s, s->streambuf, &s->stream_i); + if (ret < 0) + { + _err("ERROR: nxscope_stream_send failed %d\n", ret); + goto errout; + } + + /* Reset stream buffer */ + + nxscope_stream_reset(s); + +errout: + nxscope_unlock(s); + + return ret; +} + +/**************************************************************************** + * Name: nxscope_recv + * + * Description: + * Receive and handle nxscope protocol data. + * + * NOTE: It's the user's responsibility to periodically call this function. + * + * Input Parameters: + * s - a pointer to a nxscope instance + * + ****************************************************************************/ + +int nxscope_recv(FAR struct nxscope_s *s) +{ + int ret = OK; + size_t size_left = 0; + size_t bytes_left = 0; + struct nxscope_frame_s frame; + + DEBUGASSERT(s); + + do + { + /* Accumulate data until buffer empty */ + + size_left = s->rxbuf_len - s->rxbuf_i; + ret = INTF_RECV(s, s->intf_cmd, &s->rxbuf[s->rxbuf_i], size_left); + if (ret <= 0) + { + break; + } + + s->rxbuf_i += ret; + } + while (1); + + /* Return if no data */ + + if (s->rxbuf_i == 0) + { + goto errout; + } + + /* Get frame */ + + ret = PROTO_FRAME_GET(s, s->proto_cmd, s->rxbuf, s->rxbuf_i, &frame); + if (ret < 0) + { + /* Do not pass err further */ + + ret = OK; + goto errout; + } + + /* Handle frame */ + + ret = nxscope_recv_handle(s, frame.id, frame.dlen, frame.data); + if (ret < 0) + { + _err("ERROR: nxscope_recv_handle failed %d\n", ret); + goto errout; + } + + /* Keep the remaining data */ + + bytes_left = s->rxbuf_i - frame.drop; + if (bytes_left > 0) + { + memmove(s->rxbuf, &s->rxbuf[frame.drop], bytes_left); + } + +errout: + s->rxbuf_i = bytes_left; + + return ret; +} + +/**************************************************************************** + * Name: nxscope_stream_start + * + * Description: + * Start/stop data stream + * + * Input Parameters: + * s - a pointer to a nxscope instance + * start - start/stop + * + ****************************************************************************/ + +int nxscope_stream_start(FAR struct nxscope_s *s, bool start) +{ + int ret = OK; + + DEBUGASSERT(s); + + nxscope_lock(s); + + _info("force stream_start=%d\n", start); + ret = nxscope_start_set(s, start); + + nxscope_unlock(s); + + return ret; +} diff --git a/logging/nxscope/nxscope_chan.c b/logging/nxscope/nxscope_chan.c new file mode 100644 index 000000000..ea2e74fcc --- /dev/null +++ b/logging/nxscope/nxscope_chan.c @@ -0,0 +1,1503 @@ +/**************************************************************************** + * apps/logging/nxscope/nxscope_chan.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "nxscope_internals.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_ENDIAN_BIG +# error Big endian not tested +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +int g_type_size[] = +{ + 0, /* NXSCOPE_TYPE_UNDEF */ + 0, /* NXSCOPE_TYPE_NONE */ + sizeof(uint8_t), /* NXSCOPE_TYPE_UINT8 */ + sizeof(int8_t), /* NXSCOPE_TYPE_INT8 */ + sizeof(uint16_t), /* NXSCOPE_TYPE_UINT16 */ + sizeof(int16_t), /* NXSCOPE_TYPE_INT16 */ + sizeof(uint32_t), /* NXSCOPE_TYPE_UINT32 */ + sizeof(int32_t), /* NXSCOPE_TYPE_INT32 */ + sizeof(uint64_t), /* NXSCOPE_TYPE_UINT64 */ + sizeof(int64_t), /* NXSCOPE_TYPE_INT64 */ + sizeof(float), /* NXSCOPE_TYPE_FLOAT */ + sizeof(double), /* NXSCOPE_TYPE_DOUBLE */ + sizeof(ub8_t), /* NXSCOPE_TYPE_UB8 */ + sizeof(b8_t), /* NXSCOPE_TYPE_B8 */ + sizeof(ub16_t), /* NXSCOPE_TYPE_UB16 */ + sizeof(b16_t), /* NXSCOPE_TYPE_B16 */ + sizeof(ub32_t), /* NXSCOPE_TYPE_UB32 */ + sizeof(b32_t), /* NXSCOPE_TYPE_B32 */ + sizeof(char), /* NXSCOPE_TYPE_CHAR */ +#if 0 + /* Reserved for future use */ + + sizeof(wchar_t), /* NXSCOPE_TYPE_WCHAR */ +#endif + +#ifdef CONFIG_LOGGING_NXSCOPE_USERTYPES + /* User type always last element and always equal to 1B */ + + sizeof(uint8_t), /* NXSCOPE_TYPE_USER */ +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxscope_stream_overflow + * + * NOTE: This function assumes that we have exclusive access to the nxscope + * instance + * + ****************************************************************************/ + +static void nxscope_stream_overflow(FAR struct nxscope_s *s) +{ + DEBUGASSERT(s); + + s->streambuf[s->proto_stream->hdrlen] |= NXSCOPE_STREAM_FLAGS_OVERFLOW; +} + +/**************************************************************************** + * Name: nxscope_ch_validate + ****************************************************************************/ + +static int nxscope_ch_validate(FAR struct nxscope_s *s, uint8_t ch, + uint8_t type, uint8_t d, uint8_t mlen) +{ + union nxscope_chinfo_type_u utype; + size_t next_i = 0; + int ret = OK; + size_t type_size = 0; + + DEBUGASSERT(s); + + /* Do nothing if stream not started */ + + if (!s->start) + { + ret = -EAGAIN; + goto errout; + } + + /* Do nothing if channel not enabled */ + + if (s->chinfo[ch].enable != 1) + { + ret = -EAGAIN; + goto errout; + } + + /* Some additional checks if debug features enabled */ + +#ifdef CONFIG_DEBUG_FEATURES + /* Validate channel */ + + if (ch > s->cmninfo.chmax) + { + _err("ERROR: invalid channel %d\n", ch); + ret = -EINVAL; + goto errout; + } + + /* Validate channel type */ + + if (s->chinfo[ch].type.s.dtype != type) + { + _err("ERROR: invalid channel type %d != %d\n", + s->chinfo[ch].type.u8, type); + ret = -EINVAL; + goto errout; + } + + /* Validate channel vdim */ + + if (s->chinfo[ch].vdim != d) + { + _err("ERROR: invalid channel dim %d\n", d); + ret = -EINVAL; + goto errout; + } + + /* Validate channel metadata size */ + + if (s->chinfo[ch].mlen != mlen) + { + _err("ERROR: invalid channel mlen %d\n", mlen); + ret = -EINVAL; + goto errout; + } +#endif + +#ifdef CONFIG_LOGGING_NXSCOPE_DIVIDER + /* Handle sample rate divider */ + + s->cntr[ch] += 1; + if (s->cntr[ch] % (s->chinfo[ch].div + 1) != 0) + { + ret = -EAGAIN; + goto errout; + } +#endif + + /* Get utype */ + + utype.u8 = type; + + /* Check buffer size */ + +#ifdef CONFIG_LOGGING_NXSCOPE_USERTYPES + if (type >= NXSCOPE_TYPE_USER) + { + type_size = 1; + } + else +#endif + { + type_size = g_type_size[utype.s.dtype]; + } + +#ifdef CONFIG_LOGGING_NXSCOPE_CRICHANNELS + if (utype.s.cri) + { +# ifdef CONFIG_DEBUG_FEATURES + next_i = (s->proto_stream->hdrlen + 1 + type_size * d + mlen + + s->proto_stream->footlen); + + /* Verify the size of the critical channels buffer */ + + if (s->cribuf_len < next_i) + { + _err("ERROR: no space in cribuf %d < %d\n", s->cribuf_len, next_i); + ret = -ENOBUFS; + goto errout; + } + else +# endif + { + /* No more checks needed for critical channel */ + + ret = OK; + goto errout; + } + } +#endif + + next_i = (s->stream_i + 1 + type_size * d + mlen + + s->proto_stream->footlen); + + if (next_i > s->streambuf_len) + { + _err("ERROR: no space for data %d\n", s->stream_i); + nxscope_stream_overflow(s); + ret = -ENOBUFS; + goto errout; + } + +errout: + return ret; +} + +/**************************************************************************** + * Name: nxscope_put_vector + * + * NOTE: This function assumes that we have exclusive access to the nxscope + * stream buffer + * + * IMPORTANT: Data stored always as little-endian ! + * + ****************************************************************************/ + +static int nxscope_put_vector(FAR uint8_t *buff, uint8_t type, FAR void *val, + uint8_t d) +{ + int i = 0; + int j = 0; + + DEBUGASSERT(buff); + + /* Pack data */ + + switch (type) + { + case NXSCOPE_TYPE_NONE: + { + /* Nothing to do here */ + + break; + } + + case NXSCOPE_TYPE_UINT8: + case NXSCOPE_TYPE_INT8: +#ifdef CONFIG_LOGGING_NXSCOPE_USERTYPES + case NXSCOPE_TYPE_USER: +#endif + { + uint8_t u8 = 0; + + for (i = 0; i < d; i++) + { + DEBUGASSERT(val); + u8 = ((FAR uint8_t *)val)[i]; + + buff[j++] = u8; + } + + break; + } + + case NXSCOPE_TYPE_UINT16: + case NXSCOPE_TYPE_INT16: + case NXSCOPE_TYPE_B8: + case NXSCOPE_TYPE_UB8: + { + uint16_t u16 = 0; + + for (i = 0; i < d; i++) + { + DEBUGASSERT(val); + u16 = htole16(((FAR uint16_t *)val)[i]); + + buff[j++] = ((u16 >> 0) & 0xff); + buff[j++] = ((u16 >> 8) & 0xff); + } + + break; + } + + case NXSCOPE_TYPE_UINT32: + case NXSCOPE_TYPE_INT32: + case NXSCOPE_TYPE_FLOAT: + case NXSCOPE_TYPE_B16: + case NXSCOPE_TYPE_UB16: + { + uint32_t u32 = 0; + + for (i = 0; i < d; i++) + { + DEBUGASSERT(val); + u32 = htole32(((FAR uint32_t *)val)[i]); + + buff[j++] = ((u32 >> 0) & 0xff); + buff[j++] = ((u32 >> 8) & 0xff); + buff[j++] = ((u32 >> 16) & 0xff); + buff[j++] = ((u32 >> 24) & 0xff); + } + + break; + } + +#ifdef CONFIG_HAVE_LONG_LONG + case NXSCOPE_TYPE_UINT64: + case NXSCOPE_TYPE_INT64: + case NXSCOPE_TYPE_DOUBLE: + case NXSCOPE_TYPE_B32: + case NXSCOPE_TYPE_UB32: + { + for (i = 0; i < d; i++) + { + uint64_t u64 = 0; + + DEBUGASSERT(val); + u64 = htole64(((FAR uint64_t *)val)[i]); + + buff[j++] = ((u64 >> 0) & 0xff); + buff[j++] = ((u64 >> 8) & 0xff); + buff[j++] = ((u64 >> 16) & 0xff); + buff[j++] = ((u64 >> 24) & 0xff); + buff[j++] = ((u64 >> 32) & 0xff); + buff[j++] = ((u64 >> 40) & 0xff); + buff[j++] = ((u64 >> 48) & 0xff); + buff[j++] = ((u64 >> 56) & 0xff); + } + + break; + } +#endif + + case NXSCOPE_TYPE_CHAR: + { + /* Copy only string bytes + '\0' */ + + DEBUGASSERT(val); + + strncpy((FAR char *)buff, (FAR const char *)val, d); + j += strnlen((FAR char *)buff, d); + buff[j++] = '\0'; + + break; + } + + default: + { + _err("ERROR: invalid type=%d\n", type); + DEBUGASSERT(0); + } + } + + return j; +} + +/**************************************************************************** + * Name: nxscope_put_meta + * + * NOTE: This function assumes that we have exclusive access to the nxscope + * stream buffer + * + * REVISIT: what about endianness ? + * + ****************************************************************************/ + +static int nxscope_put_meta(FAR uint8_t *buff, FAR uint8_t *meta, + uint8_t mlen) +{ + int i = 0; + + DEBUGASSERT(buff); + + for (i = 0; i < mlen; i++) + { + DEBUGASSERT(meta); + buff[i] = meta[i]; + } + + return mlen; +} + +/**************************************************************************** + * Name: nxscope_put_sample + * + * NOTE: This function assumes that we have exclusive access to the nxscope + * stream buffer + * + ****************************************************************************/ + +static void nxscope_put_sample(FAR uint8_t *buff, FAR size_t *buff_i, + uint8_t type, uint8_t ch, FAR void *val, + uint8_t d, FAR uint8_t *meta, uint8_t mlen) +{ + size_t i = 0; + + /* Channel ID */ + + buff[(*buff_i)++] = ch; + + /* Vector sample data - always little-endian */ + + i = nxscope_put_vector(&buff[*buff_i], type, val, d); + *buff_i += i; + + /* Meta data. + * REVISIT: what about endianness ? + */ + + i = nxscope_put_meta(&buff[*buff_i], meta, mlen); + *buff_i += i; +} + +/**************************************************************************** + * Name: nxscope_put_common_m + ****************************************************************************/ + +static int nxscope_put_common_m(FAR struct nxscope_s *s, uint8_t type, + uint8_t ch, FAR void *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen) +{ + FAR uint8_t *buff = NULL; + FAR size_t *buff_i = NULL; + int ret = OK; +#ifdef CONFIG_LOGGING_NXSCOPE_CRICHANNELS + size_t tmp = 0; + union nxscope_chinfo_type_u utype; +#endif + + DEBUGASSERT(s); + + nxscope_lock(s); + + /* Validate data */ + + ret = nxscope_ch_validate(s, ch, type, d, mlen); + if (ret != OK) + { + goto errout; + } + + /* Get buffer to send */ + +#ifdef CONFIG_LOGGING_NXSCOPE_CRICHANNELS + utype.u8 = type; + if (utype.s.cri) + { + /* Dedicated critical channels buffer */ + + buff = s->cribuf; + buff_i = &tmp; + } + else +#endif + { + /* Common stream buffer */ + + buff = s->streambuf; + buff_i = &s->stream_i; + } + + /* Put sample on buffer */ + + nxscope_put_sample(buff, buff_i, type, ch, val, d, meta, mlen); + +#ifdef CONFIG_LOGGING_NXSCOPE_CRICHANNELS + if (utype.s.cri) + { + /* Send data without buffering */ + + ret = nxscope_stream_send(s, buff, buff_i); + if (ret < 0) + { + _err("ERROR: nxscope_stream_send failed %d\n", ret); + goto errout; + } + } +#endif + +errout: + nxscope_unlock(s); + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxscope_chan_init + * + * Description: + * Initialize nxscope channel + * + * Input Parameters: + * s - a pointer to a nxscope instance + * ch - a channel id + * name - a channel name + * type - a channel data type (union nxscope_chinfo_type_u) + * vdim - a vector data dimension (vdim=1 for a point) + * mlen - a length of metadata + * + ****************************************************************************/ + +int nxscope_chan_init(FAR struct nxscope_s *s, uint8_t ch, FAR char *name, + uint8_t type, uint8_t vdim, uint8_t mlen) +{ + int ret = OK; + + DEBUGASSERT(s); + DEBUGASSERT(name); + + if (ch > s->cmninfo.chmax) + { + _err("ERROR: invalid channel %d\n", ch); + ret = -EINVAL; + goto errout; + } + + nxscope_lock(s); + +#ifndef CONFIG_LOGGING_NXSCOPE_CRICHANNELS + if (NXSCOPE_IS_CRICHAN(type)) + { + _err("ERROR: cri channels not supported ch=%d\n", ch); + ret = -EINVAL; + goto errout; + } +#endif + + /* Reset channel data */ + + memset(&s->chinfo[ch], 0, sizeof(struct nxscope_chinfo_s)); + + /* Copy channel info */ + + s->chinfo[ch].type.u8 = type; + s->chinfo[ch].vdim = vdim; + s->chinfo[ch].mlen = mlen; + s->chinfo[ch].name = name; + + nxscope_unlock(s); + +errout: + return ret; +} + +/**************************************************************************** + * Name: nxscope_chan_en + * + * Description: + * Enable/disable a given channel + * + * Input Parameters: + * s - a pointer to a nxscope instance + * ch - a channel id + * en - enable/disable + * + ****************************************************************************/ + +int nxscope_chan_en(FAR struct nxscope_s *s, uint8_t ch, bool en) +{ + int ret = OK; + + DEBUGASSERT(s); + + nxscope_lock(s); + + if (ch > s->cmninfo.chmax) + { + _err("ERROR: invalid channel %d\n", ch); + ret = -EINVAL; + goto errout; + } + + if (s->chinfo[ch].type.s.dtype == NXSCOPE_TYPE_UNDEF) + { + _err("ERROR: channel not initialized %d\n", ch); + ret = -EINVAL; + goto errout; + } + + _info("chan_en=%d %d\n", ch, en); + + /* Set enable flag */ + + s->chinfo[ch].enable = en; + +errout: + nxscope_unlock(s); + + return ret; +} + +#ifdef CONFIG_LOGGING_NXSCOPE_DIVIDER +/**************************************************************************** + * Name: nxscope_chan_div + * + * Description: + * Configure divider for a given channel + * + * Input Parameters: + * s - a pointer to a nxscope instance + * ch - a channel id + * div - divider value - starts from 0 + * + ****************************************************************************/ + +int nxscope_chan_div(FAR struct nxscope_s *s, uint8_t ch, uint8_t div) +{ + int ret = OK; + + DEBUGASSERT(s); + + nxscope_lock(s); + + if (ch > s->cmninfo.chmax) + { + _err("ERROR: invalid channel %d\n", ch); + ret = -EINVAL; + goto errout; + } + + _info("chan_div=%d %d\n", ch, div); + + /* Set divider */ + + s->chinfo[ch].div = div; + +errout: + nxscope_unlock(s); + + return ret; +} +#endif + +/**************************************************************************** + * Name: nxscope_chan_all_en + * + * Description: + * Enable/disable all channels + * + * Input Parameters: + * s - a pointer to a nxscope instance + * en - enable/disable + * + ****************************************************************************/ + +int nxscope_chan_all_en(FAR struct nxscope_s *s, bool en) +{ + int ret = OK; + int i = 0; + + DEBUGASSERT(s); + + for (i = 0; i < s->cmninfo.chmax; i++) + { + ret |= nxscope_chan_en(s, i, en); + } + + return ret; +} + +/**************************************************************************** + * Name: nxscope_put_vXXXX_m + * + * Description: + * Put a vector with metadata on the stream buffer + * + * Input Parameters: + * s - a pointer to a nxscope instance + * ch - a channel id + * val - a pointer to a sample data vector + * d - a dimmention of sample data vector + * meta - a pointer to metadata + * mlen - a length of metadata + * + ****************************************************************************/ + +/**************************************************************************** + * Name: nxscope_put_vuint8_m + ****************************************************************************/ + +int nxscope_put_vuint8_m(FAR struct nxscope_s *s, uint8_t ch, + FAR uint8_t *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_common_m(s, NXSCOPE_TYPE_UINT8, + ch, val, d, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_vint8_m + ****************************************************************************/ + +int nxscope_put_vint8_m(FAR struct nxscope_s *s, uint8_t ch, + FAR int8_t *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_common_m(s, NXSCOPE_TYPE_INT8, + ch, val, d, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_vuint16_m + ****************************************************************************/ + +int nxscope_put_vuint16_m(FAR struct nxscope_s *s, uint8_t ch, + FAR uint16_t *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_common_m(s, NXSCOPE_TYPE_UINT16, + ch, val, d, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_vint16_m + ****************************************************************************/ + +int nxscope_put_vint16_m(FAR struct nxscope_s *s, uint8_t ch, + FAR int16_t *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_common_m(s, NXSCOPE_TYPE_INT16, + ch, val, d, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_vuint32_m + ****************************************************************************/ + +int nxscope_put_vuint32_m(FAR struct nxscope_s *s, uint8_t ch, + FAR uint32_t *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_common_m(s, NXSCOPE_TYPE_UINT32, + ch, val, d, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_vint32_m + ****************************************************************************/ + +int nxscope_put_vint32_m(FAR struct nxscope_s *s, uint8_t ch, + FAR int32_t *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_common_m(s, NXSCOPE_TYPE_INT32, + ch, val, d, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_vuint64_m + ****************************************************************************/ + +int nxscope_put_vuint64_m(FAR struct nxscope_s *s, uint8_t ch, + FAR uint64_t *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_common_m(s, NXSCOPE_TYPE_UINT64, + ch, val, d, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_vint64_m + ****************************************************************************/ + +int nxscope_put_vint64_m(FAR struct nxscope_s *s, uint8_t ch, + FAR int64_t *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_common_m(s, NXSCOPE_TYPE_INT64, + ch, val, d, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_vfloat_m + ****************************************************************************/ + +int nxscope_put_vfloat_m(FAR struct nxscope_s *s, uint8_t ch, + FAR float *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_common_m(s, NXSCOPE_TYPE_FLOAT, + ch, val, d, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_vdouble_m + ****************************************************************************/ + +int nxscope_put_vdouble_m(FAR struct nxscope_s *s, uint8_t ch, + FAR double *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_common_m(s, NXSCOPE_TYPE_DOUBLE, + ch, val, d, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_vub8_m + ****************************************************************************/ + +int nxscope_put_vub8_m(FAR struct nxscope_s *s, uint8_t ch, + FAR ub8_t *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_common_m(s, NXSCOPE_TYPE_UB8, + ch, val, d, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_vb8_m + ****************************************************************************/ + +int nxscope_put_vb8_m(FAR struct nxscope_s *s, uint8_t ch, + FAR b8_t *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_common_m(s, NXSCOPE_TYPE_B8, + ch, val, d, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_vub16_m + ****************************************************************************/ + +int nxscope_put_vub16_m(FAR struct nxscope_s *s, uint8_t ch, + FAR ub16_t *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_common_m(s, NXSCOPE_TYPE_UB16, + ch, val, d, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_vb16_m + ****************************************************************************/ + +int nxscope_put_vb16_m(FAR struct nxscope_s *s, uint8_t ch, + FAR b16_t *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_common_m(s, NXSCOPE_TYPE_B16, + ch, val, d, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_vub32_m + ****************************************************************************/ + +int nxscope_put_vub32_m(FAR struct nxscope_s *s, uint8_t ch, + FAR ub32_t *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_common_m(s, NXSCOPE_TYPE_UB32, + ch, val, d, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_vb32_m + ****************************************************************************/ + +int nxscope_put_vb32_m(FAR struct nxscope_s *s, uint8_t ch, + FAR b32_t *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_common_m(s, NXSCOPE_TYPE_B32, + ch, val, d, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_vchar_m + * + * NOTE: if a given string is shorten than initialized channel vdim, + * we put only string bytes + '\0' + * + ****************************************************************************/ + +int nxscope_put_vchar_m(FAR struct nxscope_s *s, uint8_t ch, + FAR char *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_common_m(s, NXSCOPE_TYPE_CHAR, + ch, val, d, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_vXXXX + * + * Description: + * Put a vector on the stream buffer + * + * Input Parameters: + * s - a pointer to a nxscope instance + * ch - a channel id + * val - a pointer to a sample data vector + * d - a dimmention of sample data vector + * + ****************************************************************************/ + +/**************************************************************************** + * Name: nxscope_put_vuint8 + ****************************************************************************/ + +int nxscope_put_vuint8(FAR struct nxscope_s *s, uint8_t ch, + FAR uint8_t *val, uint8_t d) +{ + return nxscope_put_vuint8_m(s, ch, val, d, NULL, 0); +} + +/**************************************************************************** + * Name: nxscope_put_vint8 + ****************************************************************************/ + +int nxscope_put_vint8(FAR struct nxscope_s *s, uint8_t ch, + FAR int8_t *val, uint8_t d) +{ + return nxscope_put_vint8_m(s, ch, val, d, NULL, 0); +} + +/**************************************************************************** + * Name: nxscope_put_vuint16 + ****************************************************************************/ + +int nxscope_put_vuint16(FAR struct nxscope_s *s, uint8_t ch, + FAR uint16_t *val, uint8_t d) +{ + return nxscope_put_vuint16_m(s, ch, val, d, NULL, 0); +} + +/**************************************************************************** + * Name: nxscope_put_vint16 + ****************************************************************************/ + +int nxscope_put_vint16(FAR struct nxscope_s *s, uint8_t ch, + FAR int16_t *val, uint8_t d) +{ + return nxscope_put_vint16_m(s, ch, val, d, NULL, 0); +} + +/**************************************************************************** + * Name: nxscope_put_vuint32 + ****************************************************************************/ + +int nxscope_put_vuint32(FAR struct nxscope_s *s, uint8_t ch, + FAR uint32_t *val, uint8_t d) +{ + return nxscope_put_vuint32_m(s, ch, val, d, NULL, 0); +} + +/**************************************************************************** + * Name: nxscope_put_vint32 + ****************************************************************************/ + +int nxscope_put_vint32(FAR struct nxscope_s *s, uint8_t ch, + FAR int32_t *val, uint8_t d) +{ + return nxscope_put_vint32_m(s, ch, val, d, NULL, 0); +} + +/**************************************************************************** + * Name: nxscope_put_vuint64 + ****************************************************************************/ + +int nxscope_put_vuint64(FAR struct nxscope_s *s, uint8_t ch, + FAR uint64_t *val, uint8_t d) +{ + return nxscope_put_vuint64_m(s, ch, val, d, NULL, 0); +} + +/**************************************************************************** + * Name: nxscope_put_vint64 + ****************************************************************************/ + +int nxscope_put_vint64(FAR struct nxscope_s *s, uint8_t ch, + FAR int64_t *val, uint8_t d) +{ + return nxscope_put_vint64_m(s, ch, val, d, NULL, 0); +} + +/**************************************************************************** + * Name: nxscope_put_vfloat + ****************************************************************************/ + +int nxscope_put_vfloat(FAR struct nxscope_s *s, uint8_t ch, + FAR float *val, uint8_t d) +{ + return nxscope_put_vfloat_m(s, ch, val, d, NULL, 0); +} + +/**************************************************************************** + * Name: nxscope_put_vdouble + ****************************************************************************/ + +int nxscope_put_vdouble(FAR struct nxscope_s *s, uint8_t ch, + FAR double *val, uint8_t d) +{ + return nxscope_put_vdouble_m(s, ch, val, d, NULL, 0); +} + +/**************************************************************************** + * Name: nxscope_put_vub8 + ****************************************************************************/ + +int nxscope_put_vub8(FAR struct nxscope_s *s, uint8_t ch, + FAR ub8_t *val, uint8_t d) +{ + return nxscope_put_vub8_m(s, ch, val, d, NULL, 0); +} + +/**************************************************************************** + * Name: nxscope_put_vb8 + ****************************************************************************/ + +int nxscope_put_vb8(FAR struct nxscope_s *s, uint8_t ch, + FAR b8_t *val, uint8_t d) +{ + return nxscope_put_vb8_m(s, ch, val, d, NULL, 0); +} + +/**************************************************************************** + * Name: nxscope_put_vub16 + ****************************************************************************/ + +int nxscope_put_vub16(FAR struct nxscope_s *s, uint8_t ch, + FAR ub16_t *val, uint8_t d) +{ + return nxscope_put_vub16_m(s, ch, val, d, NULL, 0); +} + +/**************************************************************************** + * Name: nxscope_put_vb16 + ****************************************************************************/ + +int nxscope_put_vb16(FAR struct nxscope_s *s, uint8_t ch, + FAR b16_t *val, uint8_t d) +{ + return nxscope_put_vb16_m(s, ch, val, d, NULL, 0); +} + +/**************************************************************************** + * Name: nxscope_put_vub32 + ****************************************************************************/ + +int nxscope_put_vub32(FAR struct nxscope_s *s, uint8_t ch, + FAR ub32_t *val, uint8_t d) +{ + return nxscope_put_vub32_m(s, ch, val, d, NULL, 0); +} + +/**************************************************************************** + * Name: nxscope_put_vb32 + ****************************************************************************/ + +int nxscope_put_vb32(FAR struct nxscope_s *s, uint8_t ch, + FAR b32_t *val, uint8_t d) +{ + return nxscope_put_vb32_m(s, ch, val, d, NULL, 0); +} + +/**************************************************************************** + * Name: nxscope_put_vchar + * + * NOTE: if a given string is shorten than initialized channel vdim, + * we put only string bytes + '\0' + * + ****************************************************************************/ + +int nxscope_put_vchar(FAR struct nxscope_s *s, uint8_t ch, + FAR char *val, uint8_t d) +{ + return nxscope_put_vchar_m(s, ch, val, d, NULL, 0); +} + +/**************************************************************************** + * Name: nxscope_put_XXXX_m + * + * Description: + * Put a point with metadata on the stream buffer + * + * Input Parameters: + * s - a pointer to a nxscope instance + * ch - a channel id + * val - sample data + * meta - a pointer to metadata + * mlen - a length of metadata + * + ****************************************************************************/ + +/**************************************************************************** + * Name: nxscope_put_uint8_m + ****************************************************************************/ + +int nxscope_put_uint8_m(FAR struct nxscope_s *s, uint8_t ch, uint8_t val, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_vuint8_m(s, ch, &val, 1, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_int8_m + ****************************************************************************/ + +int nxscope_put_int8_m(FAR struct nxscope_s *s, uint8_t ch, int8_t val, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_vint8_m(s, ch, &val, 1, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_uint16_m + ****************************************************************************/ + +int nxscope_put_uint16_m(FAR struct nxscope_s *s, uint8_t ch, uint16_t val, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_vuint16_m(s, ch, &val, 1, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_int16_m + ****************************************************************************/ + +int nxscope_put_int16_m(FAR struct nxscope_s *s, uint8_t ch, int16_t val, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_vint16_m(s, ch, &val, 1, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_uint32_m + ****************************************************************************/ + +int nxscope_put_uint32_m(FAR struct nxscope_s *s, uint8_t ch, uint32_t val, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_vuint32_m(s, ch, &val, 1, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_int32_m + ****************************************************************************/ + +int nxscope_put_int32_m(FAR struct nxscope_s *s, uint8_t ch, int32_t val, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_vint32_m(s, ch, &val, 1, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_uint64_m + ****************************************************************************/ + +int nxscope_put_uint64_m(FAR struct nxscope_s *s, uint8_t ch, uint64_t val, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_vuint64_m(s, ch, &val, 1, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_int64_m + ****************************************************************************/ + +int nxscope_put_int64_m(FAR struct nxscope_s *s, uint8_t ch, int64_t val, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_vint64_m(s, ch, &val, 1, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_float_m + ****************************************************************************/ + +int nxscope_put_float_m(FAR struct nxscope_s *s, uint8_t ch, float val, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_vfloat_m(s, ch, &val, 1, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_double_m + ****************************************************************************/ + +int nxscope_put_double_m(FAR struct nxscope_s *s, uint8_t ch, double val, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_vdouble_m(s, ch, &val, 1, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_b8_m + ****************************************************************************/ + +int nxscope_put_b8_m(FAR struct nxscope_s *s, uint8_t ch, b8_t val, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_vb8_m(s, ch, &val, 1, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_b16_m + ****************************************************************************/ + +int nxscope_put_b16_m(FAR struct nxscope_s *s, uint8_t ch, b16_t val, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_vb16_m(s, ch, &val, 1, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_ub8_m + ****************************************************************************/ + +int nxscope_put_ub8_m(FAR struct nxscope_s *s, uint8_t ch, ub8_t val, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_vub8_m(s, ch, &val, 1, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_b32_m + ****************************************************************************/ + +int nxscope_put_b32_m(FAR struct nxscope_s *s, uint8_t ch, b32_t val, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_vb32_m(s, ch, &val, 1, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_ub16_m + ****************************************************************************/ + +int nxscope_put_ub16_m(FAR struct nxscope_s *s, uint8_t ch, ub16_t val, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_vub16_m(s, ch, &val, 1, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_ub32_m + ****************************************************************************/ + +int nxscope_put_ub32_m(FAR struct nxscope_s *s, uint8_t ch, ub32_t val, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_vub32_m(s, ch, &val, 1, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_char_m + ****************************************************************************/ + +int nxscope_put_char_m(FAR struct nxscope_s *s, uint8_t ch, char val, + FAR uint8_t *meta, uint8_t mlen) +{ + return nxscope_put_vchar_m(s, ch, &val, 1, meta, mlen); +} + +/**************************************************************************** + * Name: nxscope_put_none_m + * + * Description: + * Put metadata only on the stream buffer + * + * Input Parameters: + * s - a pointer to a nxscope instance + * ch - a channel id + * meta - a pointer to metadata + * mlen - a length of metadata + * + ****************************************************************************/ + +int nxscope_put_none_m(FAR struct nxscope_s *s, uint8_t ch, + FAR uint8_t *meta, uint8_t mlen) +{ + /* Put metadata with vector dim = 0 */ + + return nxscope_put_vuint8_m(s, ch, 0, 0, meta, mlen); +} + +#ifdef CONFIG_LOGGING_NXSCOPE_USERTYPES +/**************************************************************************** + * Name: nxscope_put_user_m + * + * Description: + * Put a user specific data on the stream buffer + * + * Input Parameters: + * s - a pointer to a nxscope instance + * type - a channel type (starts from NXSCOPE_TYPE_USER) + * ch - a channel id + * val - a pointer to a sample data vector + * d - a dimmention of sample data vector + * meta - a pointer to metadata + * mlen - a length of metadata + * + ****************************************************************************/ + +int nxscope_put_user_m(FAR struct nxscope_s *s, uint8_t ch, + uint8_t type, + FAR uint8_t *val, uint8_t d, + FAR uint8_t *meta, uint8_t mlen) +{ + /* User specific type */ + + return nxscope_put_common_m(s, type, ch, val, d, meta, mlen); +} +#endif + +/**************************************************************************** + * Name: nxscope_put_user_m + * + * Description: + * Put a point on the stream buffer + * + * Input Parameters: + * s - a pointer to a nxscope instance + * ch - a channel id + * val - sample data + * + ****************************************************************************/ + +/**************************************************************************** + * Name: nxscope_put_uint8 + ****************************************************************************/ + +int nxscope_put_uint8(FAR struct nxscope_s *s, uint8_t ch, uint8_t val) +{ + return nxscope_put_vuint8(s, ch, &val, 1); +} + +/**************************************************************************** + * Name: nxscope_put_int8 + ****************************************************************************/ + +int nxscope_put_int8(FAR struct nxscope_s *s, uint8_t ch, int8_t val) +{ + return nxscope_put_vint8(s, ch, &val, 1); +} + +/**************************************************************************** + * Name: nxscope_put_uint16 + ****************************************************************************/ + +int nxscope_put_uint16(FAR struct nxscope_s *s, uint8_t ch, uint16_t val) +{ + return nxscope_put_vuint16(s, ch, &val, 1); +} + +/**************************************************************************** + * Name: nxscope_put_int16 + ****************************************************************************/ + +int nxscope_put_int16(FAR struct nxscope_s *s, uint8_t ch, int16_t val) +{ + return nxscope_put_vint16(s, ch, &val, 1); +} + +/**************************************************************************** + * Name: nxscope_put_uint32 + ****************************************************************************/ + +int nxscope_put_uint32(FAR struct nxscope_s *s, uint8_t ch, uint32_t val) +{ + return nxscope_put_vuint32(s, ch, &val, 1); +} + +/**************************************************************************** + * Name: nxscope_put_int32 + ****************************************************************************/ + +int nxscope_put_int32(FAR struct nxscope_s *s, uint8_t ch, int32_t val) +{ + return nxscope_put_vint32(s, ch, &val, 1); +} + +/**************************************************************************** + * Name: nxscope_put_uint64 + ****************************************************************************/ + +int nxscope_put_uint64(FAR struct nxscope_s *s, uint8_t ch, uint64_t val) +{ + return nxscope_put_vuint64(s, ch, &val, 1); +} + +/**************************************************************************** + * Name: nxscope_put_int64 + ****************************************************************************/ + +int nxscope_put_int64(FAR struct nxscope_s *s, uint8_t ch, int64_t val) +{ + return nxscope_put_vint64(s, ch, &val, 1); +} + +/**************************************************************************** + * Name: nxscope_put_float + ****************************************************************************/ + +int nxscope_put_float(FAR struct nxscope_s *s, uint8_t ch, float val) +{ + return nxscope_put_vfloat(s, ch, &val, 1); +} + +/**************************************************************************** + * Name: nxscope_put_double + ****************************************************************************/ + +int nxscope_put_double(FAR struct nxscope_s *s, uint8_t ch, double val) +{ + return nxscope_put_vdouble(s, ch, &val, 1); +} + +/**************************************************************************** + * Name: nxscope_put_ub8 + ****************************************************************************/ + +int nxscope_put_ub8(FAR struct nxscope_s *s, uint8_t ch, ub8_t val) +{ + return nxscope_put_vub8(s, ch, &val, 1); +} + +/**************************************************************************** + * Name: nxscope_put_b8 + ****************************************************************************/ + +int nxscope_put_b8(FAR struct nxscope_s *s, uint8_t ch, b8_t val) +{ + return nxscope_put_vb8(s, ch, &val, 1); +} + +/**************************************************************************** + * Name: nxscope_put_ub16 + ****************************************************************************/ + +int nxscope_put_ub16(FAR struct nxscope_s *s, uint8_t ch, ub16_t val) +{ + return nxscope_put_vub16(s, ch, &val, 1); +} + +/**************************************************************************** + * Name: nxscope_put_b16 + ****************************************************************************/ + +int nxscope_put_b16(FAR struct nxscope_s *s, uint8_t ch, b16_t val) +{ + return nxscope_put_vb16(s, ch, &val, 1); +} + +/**************************************************************************** + * Name: nxscope_put_ub32 + ****************************************************************************/ + +int nxscope_put_ub32(FAR struct nxscope_s *s, uint8_t ch, ub32_t val) +{ + return nxscope_put_vub32(s, ch, &val, 1); +} + +/**************************************************************************** + * Name: nxscope_put_b32 + ****************************************************************************/ + +int nxscope_put_b32(FAR struct nxscope_s *s, uint8_t ch, b32_t val) +{ + return nxscope_put_vb32(s, ch, &val, 1); +} + +/**************************************************************************** + * Name: nxscope_put_char + ****************************************************************************/ + +int nxscope_put_char(FAR struct nxscope_s *s, uint8_t ch, char val) +{ + return nxscope_put_vchar(s, ch, &val, 1); +} diff --git a/logging/nxscope/nxscope_idummy.c b/logging/nxscope/nxscope_idummy.c new file mode 100644 index 000000000..650dbb3b8 --- /dev/null +++ b/logging/nxscope/nxscope_idummy.c @@ -0,0 +1,194 @@ +/**************************************************************************** + * apps/logging/nxscope/nxscope_idummy.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include + +/**************************************************************************** + * Private Type Definition + ****************************************************************************/ + +struct nxscope_intf_dummy_s +{ + FAR struct nxscope_dummy_cfg_s *cfg; +}; + +/**************************************************************************** + * Private Function Protototypes + ****************************************************************************/ + +static int nxscope_dummy_send(FAR struct nxscope_intf_s *intf, + FAR uint8_t *buff, int len); +static int nxscope_dummy_recv(FAR struct nxscope_intf_s *intf, + FAR uint8_t *buff, int len); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct nxscope_intf_ops_s g_nxscope_dummy_ops = +{ + nxscope_dummy_send, + nxscope_dummy_recv +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxscope_dummy_send + ****************************************************************************/ + +static int nxscope_dummy_send(FAR struct nxscope_intf_s *intf, + FAR uint8_t *buff, int len) +{ + FAR struct nxscope_intf_dummy_s *priv = NULL; + + DEBUGASSERT(intf); + DEBUGASSERT(intf->priv); + + _info("nxscope_dummy_send\n"); + + /* Get priv data */ + + priv = (FAR struct nxscope_intf_dummy_s *)intf->priv; + + UNUSED(priv); + + /* Dump send buffer */ + + lib_dumpbuffer("nxscope_dummy_send", buff, len); + + return OK; +} + +/**************************************************************************** + * Name: nxscope_dummy_recv + ****************************************************************************/ + +static int nxscope_dummy_recv(FAR struct nxscope_intf_s *intf, + FAR uint8_t *buff, int len) +{ + FAR struct nxscope_intf_dummy_s *priv = NULL; + + DEBUGASSERT(intf); + DEBUGASSERT(intf->priv); + + _info("nxscope_dummy_recv\n"); + + /* Get priv data */ + + priv = (FAR struct nxscope_intf_dummy_s *)intf->priv; + + UNUSED(priv); + + /* Dump recv buffer */ + + lib_dumpbuffer("nxscope_dummy_recv", buff, len); + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxscope_dummy_init + ****************************************************************************/ + +int nxscope_dummy_init(FAR struct nxscope_intf_s *intf, + FAR struct nxscope_dummy_cfg_s *cfg) +{ + FAR struct nxscope_intf_dummy_s *priv = NULL; + int ret = OK; + + DEBUGASSERT(intf); + DEBUGASSERT(cfg); + + _info("nxscope_dummy_init\n"); + + /* Allocate priv data */ + + intf->priv = zalloc(sizeof(struct nxscope_intf_dummy_s)); + if (intf->priv == NULL) + { + _err("ERROR: intf->priv alloc failed %d\n", errno); + ret = -errno; + goto errout; + } + + /* Get priv data */ + + priv = (FAR struct nxscope_intf_dummy_s *)intf->priv; + + /* Connect configuration */ + + priv->cfg = cfg; + + /* Connect ops */ + + intf->ops = &g_nxscope_dummy_ops; + + /* Initialized */ + + intf->initialized = true; + +errout: + return ret; +} + +/**************************************************************************** + * Name: nxscope_dummy_deinit + ****************************************************************************/ + +void nxscope_dummy_deinit(FAR struct nxscope_intf_s *intf) +{ + FAR struct nxscope_intf_dummy_s *priv = NULL; + + DEBUGASSERT(intf); + + _info("nxscope_dummy_deinit\n"); + + /* Get priv data */ + + priv = (FAR struct nxscope_intf_dummy_s *)intf->priv; + + if (priv != NULL) + { + free(priv); + } + + /* Reset structure */ + + memset(intf, 0, sizeof(struct nxscope_intf_s)); +} diff --git a/logging/nxscope/nxscope_internals.c b/logging/nxscope/nxscope_internals.c new file mode 100644 index 000000000..e62581291 --- /dev/null +++ b/logging/nxscope/nxscope_internals.c @@ -0,0 +1,82 @@ +/**************************************************************************** + * apps/logging/nxscope/nxscope_internals.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "nxscope_internals.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxscope_stream_send + * + * Description: + * Send stream buffer + * + * Input Parameters: + * s - a pointer to a nxscope instance + * buff - buffer to send + * buff_i - buffer cursor + * + ****************************************************************************/ + +int nxscope_stream_send(FAR struct nxscope_s *s, FAR uint8_t *buff, + FAR size_t *buff_i) +{ + int ret = OK; + + DEBUGASSERT(s); + DEBUGASSERT(buff); + DEBUGASSERT(buff_i); + + /* Finalize stream frame */ + + ret = PROTO_FRAME_FINAL(s, s->proto_stream, + NXSCOPE_HDRID_STREAM, buff, buff_i); + if (ret < 0) + { + _err("ERROR: PROTO_FRAME_FINAL failed %d\n", ret); + goto errout; + } + + /* Send stream data */ + + ret = INTF_SEND(s, s->intf_stream, buff, *buff_i); + if (ret < 0) + { + _err("ERROR: INTF_SEND failed %d\n", ret); + } + +errout: + return ret; +} diff --git a/logging/nxscope/nxscope_internals.h b/logging/nxscope/nxscope_internals.h new file mode 100644 index 000000000..cfb921bab --- /dev/null +++ b/logging/nxscope/nxscope_internals.h @@ -0,0 +1,72 @@ +/**************************************************************************** + * apps/logging/nxscope/nxscope_internals.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_LOGGING_NXSCOPE_NXSCOPE_INTERNALS_H +#define __APPS_LOGGING_NXSCOPE_NXSCOPE_INTERNALS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Max channel name length */ + +#define CHAN_NAMELEN_MAX (32) + +/* Helpers */ + +#define PROTO_FRAME_FINAL(s, proto, id, buff, i) \ + (s)->proto_stream->ops->frame_final(proto, id, buff, i) +#define PROTO_FRAME_GET(s, proto, buff, i, frame) \ + (s)->proto_stream->ops->frame_get(proto, buff, i, frame) + +#define INTF_SEND(s, intf, buff, i) \ + (s)->intf_stream->ops->send(intf, buff, i) +#define INTF_RECV(s, intf, buff, i) \ + (s)->intf_stream->ops->recv(intf, buff, i) + +/**************************************************************************** + * Public Function Puttypes + ****************************************************************************/ + +/**************************************************************************** + * Name: nxscope_stream_send + * + * Description: + * Send stream buffers + * + * Input Parameters: + * s - a pointer to a nxscope instance + * buff - buffer to send + * buff_i - buffer cursor + * + ****************************************************************************/ + +int nxscope_stream_send(FAR struct nxscope_s *s, FAR uint8_t *buff, + FAR size_t *buff_i); + +#endif /* __APPS_LOGGING_NXSCOPE_NXSCOPE_INTERNALS_H */ diff --git a/logging/nxscope/nxscope_iser.c b/logging/nxscope/nxscope_iser.c new file mode 100644 index 000000000..35004dd95 --- /dev/null +++ b/logging/nxscope/nxscope_iser.c @@ -0,0 +1,248 @@ +/**************************************************************************** + * apps/logging/nxscope/nxscope_iser.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_SERIAL_TERMIOS +# error Termios support must be enabled +#endif + +/**************************************************************************** + * Private Type Definition + ****************************************************************************/ + +struct nxscope_intf_ser_s +{ + FAR struct nxscope_ser_cfg_s *cfg; + int fd; +}; + +/**************************************************************************** + * Private Function Protototypes + ****************************************************************************/ + +static int nxscope_ser_send(FAR struct nxscope_intf_s *intf, + FAR uint8_t *buff, int len); +static int nxscope_ser_recv(FAR struct nxscope_intf_s *intf, + FAR uint8_t *buff, int len); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct nxscope_intf_ops_s g_nxscope_ser_ops = +{ + nxscope_ser_send, + nxscope_ser_recv +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxscope_ser_send + ****************************************************************************/ + +static int nxscope_ser_send(FAR struct nxscope_intf_s *intf, + FAR uint8_t *buff, int len) +{ + FAR struct nxscope_intf_ser_s *priv = NULL; + + DEBUGASSERT(intf); + DEBUGASSERT(intf->priv); + + /* Get priv data */ + + priv = (FAR struct nxscope_intf_ser_s *)intf->priv; + + /* Write data */ + + return write(priv->fd, buff, len); +} + +/**************************************************************************** + * Name: nxscope_ser_recv + ****************************************************************************/ + +static int nxscope_ser_recv(FAR struct nxscope_intf_s *intf, + FAR uint8_t *buff, int len) +{ + FAR struct nxscope_intf_ser_s *priv = NULL; + int ret = OK; + + DEBUGASSERT(intf); + DEBUGASSERT(intf->priv); + + /* Get priv data */ + + priv = (FAR struct nxscope_intf_ser_s *)intf->priv; + + /* Read data */ + + ret = read(priv->fd, buff, len); + + if (ret < 0) + { + if (priv->cfg->nonblock && (errno == EAGAIN)) + { + ret = 0; + } + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxscope_ser_init + ****************************************************************************/ + +int nxscope_ser_init(FAR struct nxscope_intf_s *intf, + FAR struct nxscope_ser_cfg_s *cfg) +{ + FAR struct nxscope_intf_ser_s *priv = NULL; + struct termios tio; + int ret = OK; + int flags = 0; + + DEBUGASSERT(intf); + DEBUGASSERT(cfg); + + /* Allocate priv data */ + + intf->priv = zalloc(sizeof(struct nxscope_intf_ser_s)); + if (intf->priv == NULL) + { + _err("ERROR: intf->priv alloc failed %d\n", errno); + ret = -errno; + goto errout; + } + + /* Get priv data */ + + priv = (FAR struct nxscope_intf_ser_s *)intf->priv; + + /* Connect configuration */ + + priv->cfg = (FAR struct nxscope_ser_cfg_s *)cfg; + + /* Connect ops */ + + intf->ops = &g_nxscope_ser_ops; + + /* Open serial port */ + + flags = O_RDWR; + + if (priv->cfg->nonblock) + { + flags |= O_NONBLOCK; + } + + priv->fd = open(priv->cfg->path, flags); + if (priv->fd < 0) + { + _err("ERROR: failed to open %s\n", priv->cfg->path); + ret = -errno; + goto errout; + } + + /* Get the attributes */ + + tcgetattr(priv->fd, &tio); + + /* Configure a baud rate */ + + DEBUGASSERT(priv->cfg->baud > 0); + + ret = cfsetspeed(&tio, priv->cfg->baud); + if (ret < 0) + { + _err("ERROR: failed to set baud rate %d\n", errno); + goto errout; + } + + /* Configure RAW mode */ + + cfmakeraw(&tio); + + /* Change the attributes now */ + + tcsetattr(priv->fd, TCSANOW, &tio); + + /* Initialized */ + + intf->initialized = true; + +errout: + return ret; +} + +/**************************************************************************** + * Name: nxscope_ser_deinit + ****************************************************************************/ + +void nxscope_ser_deinit(FAR struct nxscope_intf_s *intf) +{ + FAR struct nxscope_intf_ser_s *priv = NULL; + + DEBUGASSERT(intf); + + /* Get priv data */ + + priv = (FAR struct nxscope_intf_ser_s *)intf->priv; + + /* Close dev */ + + if (priv->fd != -1) + { + close(priv->fd); + } + + if (priv != NULL) + { + free(priv); + } + + /* Reset structure */ + + memset(intf, 0, sizeof(struct nxscope_intf_s)); +} diff --git a/logging/nxscope/nxscope_pser.c b/logging/nxscope/nxscope_pser.c new file mode 100644 index 000000000..ca0648fea --- /dev/null +++ b/logging/nxscope/nxscope_pser.c @@ -0,0 +1,293 @@ +/**************************************************************************** + * apps/logging/nxscope/nxscope_pser.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define NXSCOPE_HDR_LEN (sizeof(struct nxscope_hdr_s)) +#define NXSCOPE_DATA_START (NXSCOPE_HDR_LEN) +#define NXSCOPE_BASEFRAME_LEN (NXSCOPE_HDR_LEN + NXSCOPE_CRC_LEN) +#define NXSCOPE_HDR_SOF (0x55) +#define NXSCOPE_CRC_LEN (sizeof(uint16_t)) + +/**************************************************************************** + * Private Type Definition + ****************************************************************************/ + +/* Nxscope serial protocol frame: + * +--------------------+------------+-------------+ + * | HDR [4B] | frame data | footer [2B] | + * +-----+---------+----+------------+-------------+ + * | SOF | len [1] | id | frame data | crc16 [2] | + * +-----+----+----+----+------------+------+------+ + * | 0 | 1 | 2 | 3 | ... | n+1 | n+2 | + * +-----+----+----+----+------------+------+------+ + * + * [1] - always little-endian + * [2] - always big-endian + */ + +/* Nxscope header */ + +begin_packed_struct struct nxscope_hdr_s +{ + uint8_t sof; /* SOF */ + uint16_t len; /* Frame length */ + uint8_t id; /* Frame ID */ +} end_packed_struct; + +/* Nxscope footer */ + +begin_packed_struct struct nxscope_footer_s +{ + uint16_t crc16; /* check sum (see nxscope_frame_final()) */ +} end_packed_struct; + +/**************************************************************************** + * Private Function Protototypes + ****************************************************************************/ + +static int nxscope_frame_get(FAR struct nxscope_proto_s *p, + FAR uint8_t *buff, size_t len, + FAR struct nxscope_frame_s *frame); +static int nxscope_frame_final(FAR struct nxscope_proto_s *p, + uint8_t id, + FAR uint8_t *buff, FAR size_t *len); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +static struct nxscope_proto_ops_s g_nxscope_proto_ser_ops = +{ + nxscope_frame_get, + nxscope_frame_final, +}; + +static struct nxscope_proto_s g_nxscope_proto_ser = +{ + false, + NULL, + &g_nxscope_proto_ser_ops, + (size_t)NXSCOPE_HDR_LEN, + (size_t)NXSCOPE_CRC_LEN +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxscope_hdr_fill + ****************************************************************************/ + +static void nxscope_hdr_fill(FAR uint8_t *buff, uint8_t id, uint16_t len) +{ + FAR struct nxscope_hdr_s *hdr = NULL; + + DEBUGASSERT(buff); + + hdr = (FAR struct nxscope_hdr_s *)buff; + + hdr->sof = NXSCOPE_HDR_SOF; + + /* Length always as little endian */ + + hdr->len = htole16(len); + hdr->id = id; +} + +/**************************************************************************** + * Name: nxscope_frame_get + ****************************************************************************/ + +static int nxscope_frame_get(FAR struct nxscope_proto_s *p, + FAR uint8_t *buff, size_t len, + FAR struct nxscope_frame_s *frame) +{ + FAR struct nxscope_hdr_s *hdr = NULL; + uint16_t crc = 0; + int ret = OK; + int i = 0; + + DEBUGASSERT(p); + DEBUGASSERT(buff); + DEBUGASSERT(frame); + + UNUSED(p); + + /* Find SOF */ + + for (i = 0; i < len - NXSCOPE_HDR_LEN; i++) + { + hdr = (FAR struct nxscope_hdr_s *)&buff[i]; + + /* Verify SOF */ + + if (hdr->sof == NXSCOPE_HDR_SOF) + { + break; + } + } + + if (hdr->sof != NXSCOPE_HDR_SOF) + { + ret = -EINVAL; + goto errout; + } + + /* Verify len - always little-endian */ + + hdr->len = htole16(hdr->len); + + if ((len - i) < hdr->len) + { + ret = -EINVAL; + goto errout; + } + + /* Verify crc16 for the whole frame */ + + crc = crc16(&buff[i], hdr->len); + if (crc != 0) + { + _err("ERROR: invalid crc16 %d\n", crc); + ret = -EINVAL; + goto errout; + } + + /* Return the frame data */ + + frame->id = hdr->id; + frame->data = &buff[i + NXSCOPE_DATA_START]; + frame->drop = hdr->len + i; + frame->dlen = hdr->len - NXSCOPE_BASEFRAME_LEN; + +errout: + return ret; +} + +/**************************************************************************** + * Name: nxscope_frame_final + ****************************************************************************/ + +static int nxscope_frame_final(FAR struct nxscope_proto_s *p, + uint8_t id, + FAR uint8_t *buff, FAR size_t *len) +{ + uint16_t crc = 0; + int ret = OK; + + DEBUGASSERT(p); + DEBUGASSERT(buff); + DEBUGASSERT(len); + + if (*len <= NXSCOPE_HDR_LEN) + { + /* No data */ + + ret = -ENODATA; + goto errout; + } + + /* Fill hdr */ + + nxscope_hdr_fill(buff, id, *len + NXSCOPE_CRC_LEN); + + /* Add crc16 - always as big-endian. + * + * crc16 xmodem: + * polynominal = 0x1021 + * initial value = 0x0000 + * final xor value = 0x0000 + */ + + crc = crc16(buff, *len); + +#ifdef CONFIG_ENDIAN_BIG + buff[(*len)++] = (crc >> 0) & 0xff; + buff[(*len)++] = (crc >> 8) & 0xff; +#else + buff[(*len)++] = (crc >> 8) & 0xff; + buff[(*len)++] = (crc >> 0) & 0xff; +#endif + +errout: + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxscope_proto_ser_init + ****************************************************************************/ + +int nxscope_proto_ser_init(FAR struct nxscope_proto_s *proto, FAR void *cfg) +{ + DEBUGASSERT(proto); + + /* cfg argument not used, but keept here for compatibility with + * future protocol implementations. + */ + + UNUSED(cfg); + + /* Just copy protocol data */ + + memcpy(proto, &g_nxscope_proto_ser, sizeof(struct nxscope_proto_s)); + + /* Initialized */ + + proto->initialized = true; + + return OK; +} + +/**************************************************************************** + * Name: nxscope_proto_ser_deinit + ****************************************************************************/ + +void nxscope_proto_ser_deinit(FAR struct nxscope_proto_s *proto) +{ + DEBUGASSERT(proto); + + /* Nothings here */ + + UNUSED(proto); +}