1 /** 2 * CANopen trace interface. 3 * 4 * @file CO_trace.h 5 * @ingroup CO_trace 6 * @author Janez Paternoster 7 * @copyright 2016 - 2020 Janez Paternoster 8 * 9 * This file is part of CANopenNode, an opensource CANopen Stack. 10 * Project home page is <https://github.com/CANopenNode/CANopenNode>. 11 * For more information on CANopen see <http://www.can-cia.org/>. 12 * 13 * Licensed under the Apache License, Version 2.0 (the "License"); 14 * you may not use this file except in compliance with the License. 15 * You may obtain a copy of the License at 16 * 17 * http://www.apache.org/licenses/LICENSE-2.0 18 * 19 * Unless required by applicable law or agreed to in writing, software 20 * distributed under the License is distributed on an "AS IS" BASIS, 21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 * See the License for the specific language governing permissions and 23 * limitations under the License. 24 */ 25 26 27 #ifndef CO_TRACE_H 28 #define CO_TRACE_H 29 30 #ifdef __cplusplus 31 extern "C" { 32 #endif 33 34 #include "CO_driver.h" 35 #include "CO_SDO.h" 36 37 38 /** 39 * @defgroup CO_trace Trace 40 * @ingroup CO_CANopen 41 * @{ 42 * 43 * CANopen trace for recording variables over time. 44 * 45 * In embedded systems there is often a need to monitor some variables over time. 46 * Results are then displayed on graph, similar as in oscilloscope. 47 * 48 * CANopen trace is a configurable object, accessible via CANopen Object 49 * Dictionary, which records chosen variable over time. It generates a curve, 50 * which can be read via SDO and can then be displayed in a graph. 51 * 52 * CO_trace_process() runs in 1 ms intervals and monitors one variable. If it 53 * changes, it makes a record with timestamp into circular buffer. When trace is 54 * accessed by CANopen SDO object, it reads latest points from the the circular 55 * buffer, prints a SVG curve into string and sends it as a SDO response. If a 56 * SDO request was received from the same device, then no traffic occupies CAN 57 * network. 58 */ 59 60 61 /** 62 * Start index of traceConfig and Trace objects in Object Dictionary. 63 */ 64 #ifndef OD_INDEX_TRACE_CONFIG 65 #define OD_INDEX_TRACE_CONFIG 0x2301 66 #define OD_INDEX_TRACE 0x2401 67 #endif 68 69 70 /** 71 * structure for reading variables and printing points for specific data type. 72 */ 73 typedef struct { 74 /** Function pointer for getting the value from OD variable. **/ 75 int32_t (*pGetValue) (void *OD_variable); 76 /** Function pointer for printing the start point to trace.plot */ 77 uint32_t (*printPointStart)(char *s, uint32_t size, uint32_t timeStamp, int32_t value); 78 /** Function pointer for printing the point to trace.plot */ 79 uint32_t (*printPoint)(char *s, uint32_t size, uint32_t timeStamp, int32_t value); 80 /** Function pointer for printing the end point to trace.plot */ 81 uint32_t (*printPointEnd)(char *s, uint32_t size, uint32_t timeStamp, int32_t value); 82 } CO_trace_dataType_t; 83 84 85 /** 86 * Trace object. 87 */ 88 typedef struct { 89 bool_t enabled; /**< True, if trace is enabled. */ 90 CO_SDO_t *SDO; /**< From CO_trace_init(). */ 91 uint32_t *timeBuffer; /**< From CO_trace_init(). */ 92 int32_t *valueBuffer; /**< From CO_trace_init(). */ 93 uint32_t bufferSize; /**< From CO_trace_init(). */ 94 volatile uint32_t writePtr; /**< Location in buffer, which will be next written. */ 95 volatile uint32_t readPtr; /**< Location in buffer, which will be next read. */ 96 uint32_t lastTimeStamp; /**< Last time stamp. If zero, then last point contains last timestamp. */ 97 void *OD_variable; /**< Pointer to variable, which is monitored */ 98 const CO_trace_dataType_t *dt; /**< Data type specific function pointers. **/ 99 int32_t valuePrev; /**< Previous value of value. */ 100 uint32_t *map; /**< From CO_trace_init(). */ 101 uint8_t *format; /**< From CO_trace_init(). */ 102 int32_t *value; /**< From CO_trace_init(). */ 103 int32_t *minValue; /**< From CO_trace_init(). */ 104 int32_t *maxValue; /**< From CO_trace_init(). */ 105 uint32_t *triggerTime; /**< From CO_trace_init(). */ 106 uint8_t *trigger; /**< From CO_trace_init(). */ 107 int32_t *threshold; /**< From CO_trace_init(). */ 108 } CO_trace_t; 109 110 111 /** 112 * Initialize trace object. 113 * 114 * Function must be called in the communication reset section. 115 * 116 * @param trace This object will be initialized. 117 * @param SDO SDO server object. 118 * @param enabled Is trace enabled. 119 * @param timeBuffer Memory block for storing time records. 120 * @param valueBuffer Memory block for storing value records. 121 * @param bufferSize Size of the above buffers. 122 * @param map Map to variable in Object Dictionary, which will be monitored. Same structure as in PDO. 123 * @param Format Format of the plot. If first bit is 1, above variable is unsigned. For more info see Object Dictionary. 124 * @param trigger If different than zero, trigger time is recorded, when variable goes through threshold. 125 * @param threshold Used with trigger. 126 * @param value Pointer to variable, which will show last value of the variable. 127 * @param minValue Pointer to variable, which will show minimum value of the variable. 128 * @param maxValue Pointer to variable, which will show maximum value of the variable. 129 * @param triggerTime Pointer to variable, which will show last trigger time of the variable. 130 * @param idx_OD_traceConfig Index in Object Dictionary. 131 * @param idx_OD_trace Index in Object Dictionary. 132 * 133 * @return 0 on success, -1 on error. 134 */ 135 void CO_trace_init( 136 CO_trace_t *trace, 137 CO_SDO_t *SDO, 138 uint8_t enabled, 139 uint32_t *timeBuffer, 140 int32_t *valueBuffer, 141 uint32_t bufferSize, 142 uint32_t *map, 143 uint8_t *format, 144 uint8_t *trigger, 145 int32_t *threshold, 146 int32_t *value, 147 int32_t *minValue, 148 int32_t *maxValue, 149 uint32_t *triggerTime, 150 uint16_t idx_OD_traceConfig, 151 uint16_t idx_OD_trace); 152 153 154 /** 155 * Process trace object. 156 * 157 * Function must be called cyclically in 1ms intervals. 158 * 159 * @param trace This object. 160 * @param timestamp Timestamp (usually in millisecond resolution). 161 * 162 * @return 0 on success, -1 on error. 163 */ 164 void CO_trace_process(CO_trace_t *trace, uint32_t timestamp); 165 166 #ifdef __cplusplus 167 } 168 #endif /*__cplusplus*/ 169 170 /** @} */ 171 #endif 172