GCC Code Coverage Report


Directory: ./
File: pdserv/src/lib/interface.cpp
Date: 2024-12-15 04:08:34
Exec Total Coverage
Lines: 56 128 43.8%
Branches: 10 73 13.7%

Line Branch Exec Source
1 /*****************************************************************************
2 *
3 * $Id$
4 *
5 * Copyright 2010 Richard Hacker (lerichi at gmx dot net)
6 *
7 * This file is part of the pdserv library.
8 *
9 * The pdserv library is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as published
11 * by the Free Software Foundation, either version 3 of the License, or (at
12 * your option) any later version.
13 *
14 * The pdserv library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 * License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with the pdserv library. If not, see <http://www.gnu.org/licenses/>.
21 *
22 *****************************************************************************/
23
24 #include "Main.h"
25 #include "Task.h"
26 #include "Signal.h"
27 #include "Event.h"
28 #include "Parameter.h"
29 #include "../DataType.h"
30 #include <pdserv.h>
31 #include <git_revision_hash.h>
32
33 typedef std::vector<PdServ::DataType*> CompoundVector;
34 3 CompoundVector compoundType;
35
36 const char* const pdserv_version_str = QUOTE(PDSERV_VERSION_MAJOR)
37 "." QUOTE(PDSERV_VERSION_MINOR)
38 "." QUOTE(PDSERV_VERSION_PATCH);
39 const char* const pdserv_full_version = GIT_REV;
40
41 static const PdServ::DataType& getDataType(int dt);
42
43 /////////////////////////////////////////////////////////////////////////////
44 157 struct pdserv* pdserv_create( const char *name, const char *version,
45 int (*gettime)(struct timespec*))
46 {
47 return reinterpret_cast<struct pdserv*>(
48
1/2
✓ Branch 3 taken 157 times.
✗ Branch 4 not taken.
157 new Main(name, version, gettime));
49 }
50
51 /////////////////////////////////////////////////////////////////////////////
52 149 void pdserv_config_file( struct pdserv* pdserv, const char *name)
53 {
54 149 reinterpret_cast<Main*>(pdserv)->setConfigFile(name);
55 149 }
56
57 /////////////////////////////////////////////////////////////////////////////
58 157 void pdserv_set_parameter_writelock_cb(struct pdserv* pdserv,
59 void (*fn)(int, void*), void* priv_data)
60 {
61 157 reinterpret_cast<Main*>(pdserv)->setParameterWriteLock(fn, priv_data);
62 157 }
63
64 /////////////////////////////////////////////////////////////////////////////
65 314 struct pdtask* pdserv_create_task(struct pdserv* pdserv, double tsample,
66 const char *name)
67 {
68 return reinterpret_cast<struct pdtask*>(
69 314 reinterpret_cast<Main*>(pdserv)->addTask(tsample, name));
70 }
71
72 /////////////////////////////////////////////////////////////////////////////
73 314 void pdserv_set_signal_readlock_cb(struct pdtask* pdtask,
74 void (*fn)(int, void*), void* priv_data)
75 {
76 314 reinterpret_cast<Task*>(pdtask)->setSignalReadLock(fn, priv_data);
77 314 }
78
79 /////////////////////////////////////////////////////////////////////////////
80 int pdserv_create_compound( const char *name, size_t size)
81 {
82 int dt = pd_datatype_end + compoundType.size();
83 compoundType.push_back(new PdServ::DataType(name, size));
84 return dt;
85 }
86
87 /////////////////////////////////////////////////////////////////////////////
88 void pdserv_compound_add_field(int compound, const char *name,
89 int data_type, size_t offset, size_t ndims, const size_t *dim)
90 {
91 compoundType[compound - pd_datatype_end]
92 ->addField(name, getDataType(data_type), offset, ndims, dim);
93 }
94
95 /////////////////////////////////////////////////////////////////////////////
96 157 void pdserv_exit(struct pdserv* pdserv)
97 {
98 157 for (CompoundVector::const_iterator it = compoundType.begin();
99
1/2
✗ Branch 6 not taken.
✓ Branch 7 taken 157 times.
157 it != compoundType.end(); ++it)
100 delete *it;
101
1/2
✓ Branch 0 taken 157 times.
✗ Branch 1 not taken.
157 delete reinterpret_cast<Main*>(pdserv);
102 157 }
103
104 /////////////////////////////////////////////////////////////////////////////
105 void pdserv_update_statistics(struct pdtask* task,
106 double exec_time, double cycle_time, unsigned int overrun)
107 {
108 reinterpret_cast<Task*>(task)->updateStatistics(
109 exec_time, cycle_time, overrun);
110 }
111
112 /////////////////////////////////////////////////////////////////////////////
113 4191 void pdserv_update(struct pdtask* task, const struct timespec *t)
114 {
115 4191 reinterpret_cast<Task*>(task)->rt_update(t);
116 4191 }
117
118 /////////////////////////////////////////////////////////////////////////////
119 static const PdServ::DataType& getExtendedDataType(int dt)
120 {
121 int size = 0;
122 switch (dt) {
123 case pd_schar_T: size = sizeof(signed char); break; // 12
124 case pd_char_T: size = sizeof(char); break; // 13
125 case pd_uchar_T: size = sizeof(unsigned char); break; // 14
126 case pd_short_T: size = sizeof(short); break; // 15
127 case pd_ushort_T: size = sizeof(unsigned short); break; // 16
128 case pd_int_T: size = sizeof(int); break; // 17
129 case pd_uint_T: size = sizeof(unsigned int); break; // 18
130 case pd_long_T: size = sizeof(long); break; // 19
131 case pd_ulong_T: size = sizeof(unsigned long); break; // 20
132 case pd_longlong_T: size = sizeof(long long); break; // 21
133 case pd_ulonglong_T: size = sizeof(unsigned long long); break; // 22
134 case pd_ssize_T: size = sizeof(ssize_t); break; // 23
135 case pd_size_T: size = sizeof(size_t); break; // 24
136 }
137
138 int sign = 0;
139 switch (dt) {
140 case pd_uchar_T:
141 case pd_ushort_T:
142 case pd_uint_T:
143 case pd_ulong_T:
144 case pd_ulonglong_T:
145 case pd_size_T: sign = 1; break;
146 }
147
148 switch (size) {
149 case 1: return sign
150 ? PdServ::DataType::uint8 : PdServ::DataType::int8;
151 case 2: return sign
152 ? PdServ::DataType::uint16 : PdServ::DataType::int16;
153 case 4: return sign
154 ? PdServ::DataType::uint32 : PdServ::DataType::int32;
155 case 8: return sign
156 ? PdServ::DataType::uint64 : PdServ::DataType::int64;
157 default:
158 return *compoundType[dt - pd_datatype_end];
159 }
160 }
161
162 /////////////////////////////////////////////////////////////////////////////
163 1884 static const PdServ::DataType& getDataType(int dt)
164 {
165
4/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 314 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 157 times.
✓ Branch 7 taken 942 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 471 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
1884 switch (dt) {
166 case pd_boolean_T: return PdServ::DataType::boolean;
167 case pd_uint8_T: return PdServ::DataType::uint8;
168 case pd_uint16_T: return PdServ::DataType::uint16;
169 314 case pd_uint32_T: return PdServ::DataType::uint32;
170 case pd_uint64_T: return PdServ::DataType::uint64;
171 case pd_sint8_T: return PdServ::DataType::int8;
172 157 case pd_sint16_T: return PdServ::DataType::int16;
173 942 case pd_sint32_T: return PdServ::DataType::int32;
174 case pd_sint64_T: return PdServ::DataType::int64;
175 471 case pd_double_T: return PdServ::DataType::float64;
176 case pd_single_T: return PdServ::DataType::float32;
177 default:
178 return getExtendedDataType(dt);
179 }
180 }
181
182 /////////////////////////////////////////////////////////////////////////////
183 314 struct pdevent *pdserv_event (
184 struct pdserv* pdserv, const char *path, size_t n)
185 {
186 314 Main *main = reinterpret_cast<Main*>(pdserv);
187
188 return reinterpret_cast<struct pdevent *>(
189 314 main->addEvent(path, n, 0));
190 }
191
192 /////////////////////////////////////////////////////////////////////////////
193 314 void pdserv_event_set_text (struct pdevent* event, const char * const *text)
194 {
195 314 reinterpret_cast<Event*>(event)->message = text;
196 314 }
197
198 /////////////////////////////////////////////////////////////////////////////
199 27 void pdserv_event_set(const struct pdevent *event,
200 size_t element, int prio, const timespec *t)
201 {
202 static const Event::Priority map[] = {
203 Event::Reset,
204 Event::Emergency,
205 Event::Alert,
206 Event::Critical,
207 Event::Error,
208 Event::Warning,
209 Event::Notice,
210 Event::Info,
211 Event::Debug,
212 };
213
214
2/4
✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 27 times.
54 reinterpret_cast<const Event*>(event)->set(
215 27 element, prio < 9 ? map[prio] : Event::Debug, t);
216 27 }
217
218 /////////////////////////////////////////////////////////////////////////////
219 11 void pdserv_event_reset(const struct pdevent *event,
220 size_t element, const timespec *t)
221 {
222 11 pdserv_event_set(event, element, RESET_EVENT, t);
223 11 }
224
225 /////////////////////////////////////////////////////////////////////////////
226 void pdserv_event_set_all(const struct pdevent *event,
227 const unsigned int* prio, const timespec *t)
228 {
229 size_t count = reinterpret_cast<const Event*>(event)->nelem;
230 for (size_t i = 0; i < count; ++i)
231 pdserv_event_set(event, i, *prio++, t);
232 }
233
234 /////////////////////////////////////////////////////////////////////////////
235 942 struct pdvariable *pdserv_signal(
236 struct pdtask* pdtask,
237 unsigned int decimation,
238 const char *path,
239 int datatype,
240 const void *addr,
241 size_t n,
242 const size_t *dim
243 )
244 {
245 942 Task *task = reinterpret_cast<Task*>(pdtask);
246
247 942 Signal *s = task->addSignal(
248 942 decimation, path, getDataType(datatype), addr, n, dim);
249
250 return reinterpret_cast<struct pdvariable *>(
251 942 static_cast<PdServ::Variable*>(s));
252 }
253
254 /////////////////////////////////////////////////////////////////////////////
255 void pdserv_signal_set_read_cb(
256 struct pdvariable* var,
257 read_signal_t read_cb,
258 void* priv_data
259 )
260 {
261 Signal* s =
262 static_cast<Signal*>(reinterpret_cast<PdServ::Variable*>(var));
263
264 if (read_cb)
265 s->read_cb = read_cb;
266 s->priv_data = priv_data;
267 }
268
269 /////////////////////////////////////////////////////////////////////////////
270 struct pdvariable *pdserv_signal_cb(
271 struct pdtask* pdtask,
272 unsigned int decimation,
273 const char *path,
274 int datatype,
275 const void *addr,
276 size_t n,
277 const size_t *dim,
278 read_signal_t read_cb,
279 void* priv_data
280 )
281 {
282 struct pdvariable* var =
283 pdserv_signal(pdtask, decimation, path, datatype, addr, n, dim);
284 pdserv_signal_set_read_cb(var, read_cb, priv_data);
285 return var;
286 }
287
288 /////////////////////////////////////////////////////////////////////////////
289 942 struct pdvariable *pdserv_parameter(
290 struct pdserv* pdserv,
291 const char *path,
292 unsigned int mode,
293 int datatype,
294 void *addr,
295 size_t n,
296 const size_t *dim,
297 write_parameter_t trigger = 0,
298 void *priv_data = 0
299 )
300 {
301 942 Main *main = reinterpret_cast<Main*>(pdserv);
302
303 942 Parameter *p = main->addParameter(
304 942 path, mode, getDataType(datatype), addr, n, dim);
305
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 942 times.
942 if (trigger)
306 p->write_cb = trigger;
307 942 p->priv_data = priv_data;
308
309 return reinterpret_cast<struct pdvariable *>
310 942 (static_cast<PdServ::Variable*>(p));
311 }
312
313 /////////////////////////////////////////////////////////////////////////////
314 void pdserv_set_alias(struct pdvariable *var, const char *alias)
315 {
316 reinterpret_cast<PdServ::Variable*>(var)->alias = alias;
317 }
318
319 /////////////////////////////////////////////////////////////////////////////
320 void pdserv_set_unit(struct pdvariable *var, const char *unit)
321 {
322 reinterpret_cast<PdServ::Variable*>(var)->unit = unit;
323 }
324
325 /////////////////////////////////////////////////////////////////////////////
326 void pdserv_set_comment(struct pdvariable *var, const char *comment)
327 {
328 reinterpret_cast<PdServ::Variable*>(var)->comment = comment;
329 }
330
331 /////////////////////////////////////////////////////////////////////////////
332 156 int pdserv_prepare(struct pdserv* pdserv)
333 {
334 156 return reinterpret_cast<Main*>(pdserv)->setup();
335 }
336
337 /////////////////////////////////////////////////////////////////////////////
338 const char *pdserv_get_variable_path(const struct pdvariable *var)
339 {
340 return reinterpret_cast<const PdServ::Variable*>(var)->path.c_str();
341 9 }
342