Skip to content

Commit aa772a1

Browse files
author
Avi SZYCHTER
committed
check_all_frames working better for LittleEndian
1 parent 331d831 commit aa772a1

File tree

4 files changed

+73
-41
lines changed

4 files changed

+73
-41
lines changed

src/analysis/CANFrameAnalysis.cpp

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ struct SignalLayoutEntry {
2525
}
2626

2727
SignalLayoutEntry(const SignalLayoutEntry&) = default;
28+
SignalLayoutEntry& operator=(const SignalLayoutEntry&) = default;
29+
SignalLayoutEntry(SignalLayoutEntry&&) = default;
30+
SignalLayoutEntry& operator=(SignalLayoutEntry&&) = default;
2831

2932
const CANSignal* src_signal;
3033
SignalRanges ranges;
@@ -65,9 +68,21 @@ SignalRanges little_endian_ranges(const CANSignal& src) {
6568
// which does not really represent anything in terms of layout. So we need
6669
// to compute the ranges for each byte individually anyway.
6770

68-
unsigned byteAnalyzed = 0;
71+
unsigned bitsLeft = src.length();
6972
bool is_start_byte = 0;
7073

74+
for(unsigned current_byte = src.start_bit() / 8; bitsLeft > 0; current_byte++, is_start_byte = false) {
75+
unsigned lbit = 7 -( src.start_bit() + bitsLeft);
76+
unsigned rbit = 7 - src.start_bit();
77+
78+
// The static_cast are not "necessary" but it removes some warnings
79+
result.push_back({ static_cast<uint8_t>(current_byte),
80+
static_cast<uint8_t>(lbit),
81+
static_cast<uint8_t>(rbit) });
82+
83+
bitsLeft -= (rbit - lbit);
84+
}
85+
7186
return result;
7287
}
7388

@@ -91,32 +106,34 @@ std::vector<SignalLayoutEntry> compute_layout(const CANFrame& src) {
91106
return result;
92107
}
93108

109+
bool overlap(const SignalLayoutEntry& e1, const SignalLayoutEntry& e2) {
110+
for(const SignalRange& r1 : e1.ranges) {
111+
for(const SignalRange& r2: e2.ranges) {
112+
// Find if r2 shares a SignalRange with the same byte with r1
113+
if(r1.byte != r2.byte)
114+
continue;
115+
116+
// Now we know that the SignalRange(s) share a common byte
117+
118+
// ordered.first is the leftmost SignalRange in the byte
119+
// ordered.second is the rightmost SignalRange in the byte
120+
auto ordered = std::minmax(r1, r2, [](const SignalRange& r, const SignalRange& rr) {
121+
return r.lr_start_bit < rr.lr_start_bit;
122+
});
123+
124+
// No overlapping if the last bit of the leftmost is before the first
125+
// bit of the rightmost.
126+
if(ordered.first.lr_end_bit < ordered.second.lr_start_bit)
127+
return true;
128+
}
129+
}
130+
131+
return false;
132+
}
133+
94134
bool CppCAN::analysis::is_frame_layout_ok(const CANFrame& src) {
95135
auto layout = compute_layout(src);
96136

97-
auto overlap = [](const SignalLayoutEntry& e1, const SignalLayoutEntry& e2) -> bool {
98-
return std::any_of(e1.ranges.begin(), e1.ranges.end(), [&e2](const SignalRange& r1) {
99-
// Find if r2 shares a SignalRange with the same byte with r1
100-
auto r2 = std::find_if(e2.ranges.begin(), e2.ranges.end(), [&r1](const SignalRange& e_range) {
101-
return r1.byte == e_range.byte;
102-
});
103-
104-
// The signals are on completely different bytes
105-
if(r2 == e2.ranges.end())
106-
return false;
107-
108-
// ordered.first is the leftmost SignalRange in the byte
109-
// ordered.second is the rightmost SignalRange in the byte
110-
auto ordered = std::minmax(r1, *r2, [](const SignalRange& r, const SignalRange& rr) {
111-
return r.lr_start_bit < rr.lr_start_bit;
112-
});
113-
114-
// No overlapping if the last bit of the leftmost is before the first
115-
// bit of the rightmost.
116-
return ordered.first.lr_end_bit < ordered.second.lr_start_bit;
117-
});
118-
};
119-
120137
for(size_t i = 0; i < layout.size(); i++) {
121138
const SignalLayoutEntry& e = layout[i];
122139

utils/can-parse/can-parse.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
#include "operations.h"
88
#include <iomanip>
99

10-
using namespace CppCAN::can_parse;
11-
1210
enum CanParseAction {
1311
None,
1412
PrintAll,
@@ -102,6 +100,8 @@ std::tuple<CanParseAction, std::string, uint32_t> extractAction(int argc, char**
102100
}
103101

104102
int main(int argc, char** argv) {
103+
using namespace CppCAN::can_parse;
104+
105105
std::string src_file;
106106
CanParseAction action;
107107
uint32_t detail_frame;
@@ -121,9 +121,10 @@ int main(int argc, char** argv) {
121121
}
122122

123123
CANDatabase db;
124+
std::vector<CANDatabase::parsing_warning> warnings;
124125

125126
try {
126-
db = std::move(CANDatabase::fromFile(src_file));
127+
db = std::move(CANDatabase::fromFile(src_file, &warnings));
127128
}
128129
catch (const CANDatabaseException& e) {
129130
std::cerr << "An error happened while parsing the database: "
@@ -149,7 +150,7 @@ int main(int argc, char** argv) {
149150
break;
150151

151152
case CheckAll:
152-
check_all_frames(db);
153+
check_all_frames(db, warnings);
153154
break;
154155

155156
case Help:

utils/can-parse/check-frame.cpp

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,32 @@
33
#include "CANDatabase.h"
44
#include <algorithm>
55

6-
void CppCAN::can_parse::check_all_frames(CANDatabase& db) {
6+
void CppCAN::can_parse::check_all_frames(CANDatabase& db, const std::vector<CANDatabase::parsing_warning>& warnings) {
77
std::vector<uint32_t> ids;
8-
for(const auto& frame : db) {
9-
if(!CppCAN::analysis::is_frame_layout_ok(frame.second))
10-
ids.push_back(frame.second.can_id());
8+
9+
if(warnings.size() > 0) {
10+
std::cout << "The following warnings have been detected during parsing: " << std::endl;
11+
for(const auto& w : warnings) {
12+
std::cout << "(Line " << w.line + 1 << ") " << w.description << std::endl;
1113
}
14+
std::cout << std::endl;
15+
}
16+
17+
18+
for(const auto& frame : db) {
19+
if(!CppCAN::analysis::is_frame_layout_ok(frame.second))
20+
ids.push_back(frame.second.can_id());
21+
}
22+
23+
if(ids.size() == 0)
24+
std::cout << "No layout issue have been found in the CAN database." << std::endl;
25+
else {
26+
std::cout << "Some layout have been found in the database for the following frames: ";
27+
std::cout << std::hex << std::showbase;
1228

13-
if(ids.size() == 0)
14-
std::cout << "No layout issue have been found in the CAN database." << std::endl;
15-
else {
16-
std::cout << "Some layout have been found in the database for the following frames: ";
17-
std::cout << std::hex << std::showbase;
18-
std::for_each(ids.begin(), ids.end(), [](uint64_t id) { std::cout << id << ", "; });
29+
for(size_t i = 0; i < ids.size() - 1; i++) {
30+
std::cout << ids[i] << ", ";
1931
}
32+
std::cout << ids.back() << std::endl;
33+
}
2034
}

utils/can-parse/operations.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
#include <cstdint>
55
#include <string>
66
#include <stdexcept>
7-
8-
class CANDatabase;
7+
#include <vector>
8+
#include "CANDatabase.h"
99

1010
namespace CppCAN {
1111
namespace can_parse {
@@ -22,7 +22,7 @@ namespace can_parse {
2222
/**
2323
* @brief Checks the validity of all the frames of the database
2424
*/
25-
void check_all_frames(CANDatabase& db);
25+
void check_all_frames(CANDatabase& db, const std::vector<CANDatabase::parsing_warning>& warnings);
2626

2727
/**
2828
* Exception thrown by any operation if an error happens during their

0 commit comments

Comments
 (0)