1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176 | /* File: KL_extensions.cpp
* This file is part of the program ethercatcpp-core
* Program description : EtherCAT driver libraries for UNIX
* Copyright (C) 2017-2024 - Robin Passama (LIRMM / CNRS) Arnaud Meline (LIRMM / CNRS) Benjamin Navarro (LIRMM / CNRS). All Right reserved.
*
* This software is free software: you can redistribute it and/or modify
* it under the terms of the CeCILL-C license as published by
* the CEA CNRS INRIA, either version 1
* of the License, or (at your option) any later version.
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* CeCILL-C License for more details.
*
* You should have received a copy of the CeCILL-C License
* along with this software. If not, it can be found on the official website
* of the CeCILL licenses family (http://www.cecill.info/index.en.html).
*/
/**
* @file beckhoff_terminals/KL_extensions.cpp
* @author Robin Passama
* @brief source file for KLExtensionCard class
*/
#include <ethercatcpp/beckhoff_terminals/BK1150.h>
#include <ethercatcpp/beckhoff_terminals/KL_extensions.h>
using namespace ethercatcpp;
KLExtensionCard::KLExtensionCard() = default;
KLExtensionCard::~KLExtensionCard() = default;
KLExtensionCard::KLExtensionCard(const KLExtensionCard&) = default;
KLExtensionCard::KLExtensionCard(KLExtensionCard&&) = default;
KLExtensionCard& KLExtensionCard::operator=(const KLExtensionCard&) = default;
KLExtensionCard& KLExtensionCard::operator=(KLExtensionCard&&) = default;
void KLExtensionCard::set_holder(BK1150* holder, uint8_t index) {
holder_ = holder;
k_bus_index_ = index;
}
void KLExtensionCard::update_command_buffer() {
}
void KLExtensionCard::unpack_status_buffer() {
}
uint16_t KLExtensionCard::size_in() { // by default it is 0 bytes or bits
return (0);
}
uint16_t KLExtensionCard::size_out() { // by default it is 0 bytes or bits
return (0);
}
uint8_t* KLExtensionCard::output(uint8_t& bit_shift) {
return (holder_->output(k_bus_index_, bit_shift));
}
uint8_t* KLExtensionCard::input(uint8_t& bit_shift) {
return (holder_->input(k_bus_index_, bit_shift));
}
void KLExtensionCard::set_shifts_out(size_t byte_shift, uint8_t bits_shift) {
byte_shift_out_ = byte_shift;
bits_shift_out_ = bits_shift;
}
void KLExtensionCard::set_shifts_In(size_t byte_shift, uint8_t bits_shift) {
byte_shift_in_ = byte_shift;
bits_shift_in_ = bits_shift;
}
size_t KLExtensionCard::byte_shift_out() const {
return (byte_shift_out_);
}
size_t KLExtensionCard::byte_shift_in() const {
return (byte_shift_in_);
}
uint8_t KLExtensionCard::bits_shift_out() const {
return (bits_shift_out_);
}
uint8_t KLExtensionCard::bits_shift_in() const {
return (bits_shift_in_);
}
void KLExtensionCard::write_bits(uint8_t* memory_curr_addr,
uint8_t memory_bits_shift,
uint8_t*& value_to_set,
uint8_t& value_bits_shift,
uint8_t bits_to_write) {
// IMPORTANT Note: here always writing in FIRST BYTE of memory_curr_addr
// so memory_bits_shift is always consistent with bits_to_write
// this function build the adequate mask from value then apply it to memory
uint8_t mask = 0;
memory_curr_addr[0] = 0; // reset current byte to write
if ((bits_to_write + value_bits_shift) >
8) { // more than a byte of value must be read
// need to build the mask in two steps:
mask = (value_to_set[0] >>
value_bits_shift); // the last N bits of value are put first in
// the mask (N being 8-value_bits_shift)
// then get the first N bits of value's next byte
++value_to_set; // pointer shift to next byte in value read
mask |=
(value_to_set[0]
<< (8 -
value_bits_shift)); // left most bits may be non meaning full
// but then will be implicitly removed by
// last shit operation on mask
value_bits_shift = static_cast<uint8_t>(
(bits_to_write + value_bits_shift) -
8); // reset the bit shift for next byte in value
} else { // less or equal than a byte of the value must be read
mask = (value_to_set[0] >> value_bits_shift);
value_bits_shift = value_bits_shift +
bits_to_write; // defining next bit shift in value
if (value_bits_shift == 8) {
++value_to_set; // pointer shift to next byte in value read
value_bits_shift = 0;
}
}
mask <<= memory_bits_shift; // this is the last shift operation that keeps
// only meaningfull bits from mask
memory_curr_addr[0] |= mask; // applying mask to memory written
}
void KLExtensionCard::set_bits_in_memory(uint8_t* memory_start_addr,
uint8_t bits_shift,
uint8_t* value_to_set,
uint8_t value_size_in_bits) {
auto current_buffer_addr = memory_start_addr;
auto current_val_addr = value_to_set;
auto remaining_bits = value_size_in_bits;
uint8_t bits_shift_in_value =
0; // initially we start at first bit in value variable
uint8_t bits_to_write = 0;<--- The scope of the variable 'bits_to_write' can be reduced. [+]The scope of the variable 'bits_to_write' can be reduced. Warning: Be careful when fixing this message, especially when there are inner loops. Here is an example where cppcheck will write that the scope for 'i' can be reduced:<--- Variable 'bits_to_write' is assigned a value that is never used.
void f(int x)<--- Variable 'bits_to_write' is assigned a value that is never used.
{<--- Variable 'bits_to_write' is assigned a value that is never used.
int i = 0;<--- Variable 'bits_to_write' is assigned a value that is never used.
if (x) {<--- Variable 'bits_to_write' is assigned a value that is never used.
// it's safe to move 'int i = 0;' here<--- Variable 'bits_to_write' is assigned a value that is never used.
for (int n = 0; n < 10; ++n) {<--- Variable 'bits_to_write' is assigned a value that is never used.
// it is possible but not safe to move 'int i = 0;' here<--- Variable 'bits_to_write' is assigned a value that is never used.
do_something(&i);<--- Variable 'bits_to_write' is assigned a value that is never used.
}<--- Variable 'bits_to_write' is assigned a value that is never used.
}<--- Variable 'bits_to_write' is assigned a value that is never used.
}<--- Variable 'bits_to_write' is assigned a value that is never used.
When you see this message it is always safe to reduce the variable scope 1 level. <--- Variable 'bits_to_write' is assigned a value that is never used.
while (remaining_bits) { // each cycle write on a byte of the memory
bits_to_write = static_cast<uint8_t>(
(((bits_shift + remaining_bits) > 8) ? (8 - bits_shift)
: remaining_bits));
write_bits(current_buffer_addr, bits_shift, current_val_addr,
bits_shift_in_value, bits_to_write);
remaining_bits -= bits_to_write;
if (remaining_bits) {
++current_buffer_addr; // pointer shift to next byte in memory
// written
bits_shift =
0; // no more bit shift after first cycle in memory written
}
}
}
void KLExtensionCard::bits_from_memory(uint8_t* memory_start_addr,
uint8_t bits_shift,
uint8_t* variable_addr,<--- Function 'bits_from_memory' argument 3 names different: declaration 'value_to_set' definition 'variable_addr'.
uint8_t var_size_in_bits) {<--- Function 'bits_from_memory' argument 4 names different: declaration 'value_size_in_bits' definition 'var_size_in_bits'.
auto current_buffer_addr = memory_start_addr;
auto current_var_addr = variable_addr;
auto remaining_bits = var_size_in_bits;
uint8_t bits_to_read = 0;<--- The scope of the variable 'bits_to_read' can be reduced. [+]The scope of the variable 'bits_to_read' can be reduced. Warning: Be careful when fixing this message, especially when there are inner loops. Here is an example where cppcheck will write that the scope for 'i' can be reduced:<--- Variable 'bits_to_read' is assigned a value that is never used.
void f(int x)<--- Variable 'bits_to_read' is assigned a value that is never used.
{<--- Variable 'bits_to_read' is assigned a value that is never used.
int i = 0;<--- Variable 'bits_to_read' is assigned a value that is never used.
if (x) {<--- Variable 'bits_to_read' is assigned a value that is never used.
// it's safe to move 'int i = 0;' here<--- Variable 'bits_to_read' is assigned a value that is never used.
for (int n = 0; n < 10; ++n) {<--- Variable 'bits_to_read' is assigned a value that is never used.
// it is possible but not safe to move 'int i = 0;' here<--- Variable 'bits_to_read' is assigned a value that is never used.
do_something(&i);<--- Variable 'bits_to_read' is assigned a value that is never used.
}<--- Variable 'bits_to_read' is assigned a value that is never used.
}<--- Variable 'bits_to_read' is assigned a value that is never used.
}<--- Variable 'bits_to_read' is assigned a value that is never used.
When you see this message it is always safe to reduce the variable scope 1 level. <--- Variable 'bits_to_read' is assigned a value that is never used.
auto current_buffer_bits_shift = bits_shift;
while (remaining_bits) { // each cycle write on a byte of the local variable
bits_to_read = ((remaining_bits > 8) ? 8 : remaining_bits);
write_bits(
current_var_addr, 0, current_buffer_addr, current_buffer_bits_shift,
bits_to_read); // Note: no shift when reading since we always
// start with bit 0 of each byte of the variable
remaining_bits -= bits_to_read;
if (remaining_bits) {
++current_var_addr; // pointer shift to next byte in memory written
}
}
}
|