1
1
use can_dbc:: DBC ;
2
+ use chrono:: Utc ;
2
3
#[ cfg( target_os = "windows" ) ]
3
4
use pcan_basic:: socket:: usb:: UsbCanSocket ;
4
5
use slint:: { Model , VecModel , Weak } ;
5
6
use slint:: { ModelRc , SharedString } ;
6
7
#[ cfg( target_os = "linux" ) ]
7
- use socketcan:: { CanSocket , EmbeddedFrame , Frame , Socket } ;
8
+ use socketcan:: { CanInterface , CanSocket , EmbeddedFrame , Frame , Socket } ;
8
9
use std:: collections:: HashMap ;
9
10
use std:: fmt:: Write ;
10
11
use std:: rc:: Rc ;
11
12
use std:: sync:: mpsc:: Receiver ;
12
13
use std:: sync:: { Arc , Mutex } ;
13
14
use std:: thread:: sleep;
14
15
use std:: time:: Duration ;
16
+ use std:: time:: Instant ;
15
17
16
18
use crate :: slint_generatedAppWindow:: AppWindow ;
17
19
use crate :: slint_generatedAppWindow:: CanData ;
@@ -23,6 +25,7 @@ pub struct CanHandler<'a> {
23
25
pub iface : UsbCanSocket ,
24
26
pub ui_handle : & ' a Weak < AppWindow > ,
25
27
pub mspc_rx : & ' a Arc < Mutex < Receiver < DBC > > > ,
28
+ pub bitrate : String ,
26
29
}
27
30
28
31
static mut NEW_DBC_CHECK : bool = false ;
@@ -33,8 +36,12 @@ impl<'a> CanHandler<'a> {
33
36
if let Ok ( dbc) = self . mspc_rx . lock ( ) . unwrap ( ) . try_recv ( ) {
34
37
#[ cfg( target_os = "linux" ) ]
35
38
{
39
+ let can_if = CanInterface :: open ( self . iface ) . unwrap ( ) ;
40
+ let _ = can_if. bring_down ( ) ;
41
+ let _ = can_if. set_bitrate ( self . bitrate ( ) . unwrap ( ) , None ) ;
42
+ let _ = can_if. bring_up ( ) ;
36
43
let can_socket = self . open_can_socket ( ) ;
37
- self . process_ui_events ( dbc, can_socket) ;
44
+ self . process_ui_events ( dbc, can_socket, can_if ) ;
38
45
}
39
46
#[ cfg( target_os = "windows" ) ]
40
47
self . process_ui_events ( dbc) ;
@@ -60,8 +67,27 @@ impl<'a> CanHandler<'a> {
60
67
}
61
68
}
62
69
#[ cfg( target_os = "linux" ) ]
63
- fn process_ui_events ( & self , dbc : DBC , can_socket : CanSocket ) {
70
+ fn process_ui_events ( & self , dbc : DBC , can_socket : CanSocket , can_if : CanInterface ) {
71
+ let mut start_bus_load = Instant :: now ( ) ;
72
+ let mut total_bits = 0 ;
64
73
loop {
74
+ let bus_state = match can_if. state ( ) . unwrap ( ) . unwrap ( ) {
75
+ socketcan:: nl:: CanState :: ErrorActive => "ERR_ACTIVE" ,
76
+ socketcan:: nl:: CanState :: ErrorWarning => "ERR_WARNING" ,
77
+ socketcan:: nl:: CanState :: ErrorPassive => "ERR_PASSIVE" ,
78
+ socketcan:: nl:: CanState :: BusOff => "BUSOFF" ,
79
+ socketcan:: nl:: CanState :: Stopped => "STOPPED" ,
80
+ socketcan:: nl:: CanState :: Sleeping => "SLEEPING" ,
81
+ } ;
82
+ let bitrate = can_if. bit_rate ( ) . unwrap ( ) . unwrap ( ) ;
83
+ let busload = if start_bus_load. elapsed ( ) >= Duration :: from_millis ( 1000 ) {
84
+ start_bus_load = Instant :: now ( ) ;
85
+ let bus_load = ( total_bits as f64 / bitrate as f64 ) * 100.0 ;
86
+ total_bits = 0 ;
87
+ bus_load
88
+ } else {
89
+ 0.0
90
+ } ;
65
91
let _ = self . ui_handle . upgrade_in_event_loop ( move |ui| unsafe {
66
92
if ui. get_is_new_dbc ( ) {
67
93
if ui. get_is_first_open ( ) {
@@ -71,6 +97,11 @@ impl<'a> CanHandler<'a> {
71
97
}
72
98
ui. set_is_new_dbc ( false ) ;
73
99
}
100
+ ui. set_state ( bus_state. into ( ) ) ;
101
+ ui. set_bitrate ( bitrate as i32 ) ;
102
+ if busload > 0.0 {
103
+ ui. set_bus_load ( busload as i32 ) ;
104
+ }
74
105
} ) ;
75
106
unsafe {
76
107
if NEW_DBC_CHECK {
@@ -79,6 +110,7 @@ impl<'a> CanHandler<'a> {
79
110
}
80
111
}
81
112
if let Ok ( frame) = can_socket. read_frame ( ) {
113
+ total_bits += ( frame. len ( ) + 6 ) * 8 ; // Data length + overhead (approximation)
82
114
let frame_id = frame. raw_id ( ) & !0x80000000 ;
83
115
for message in dbc. messages ( ) {
84
116
if frame_id == ( message. message_id ( ) . raw ( ) & !0x80000000 ) {
@@ -106,9 +138,19 @@ impl<'a> CanHandler<'a> {
106
138
}
107
139
#[ cfg( target_os = "windows" ) ]
108
140
fn process_ui_events ( & mut self , dbc : DBC ) {
109
- use pcan_basic:: socket:: RecvCan ;
110
-
141
+ use pcan_basic:: { error:: PcanError , socket:: RecvCan } ;
142
+ let mut start_bus_load = Instant :: now ( ) ;
143
+ let mut total_bits = 0 ;
111
144
loop {
145
+ let bitrate = self . bitrate ( ) . unwrap ( ) ;
146
+ let busload = if start_bus_load. elapsed ( ) >= Duration :: from_millis ( 1000 ) {
147
+ start_bus_load = Instant :: now ( ) ;
148
+ let bus_load = ( total_bits as f64 / bitrate as f64 ) * 100.0 ;
149
+ total_bits = 0 ;
150
+ bus_load
151
+ } else {
152
+ 0.0
153
+ } ;
112
154
let _ = self . ui_handle . upgrade_in_event_loop ( move |ui| unsafe {
113
155
if ui. get_is_new_dbc ( ) {
114
156
if ui. get_is_first_open ( ) {
@@ -118,39 +160,54 @@ impl<'a> CanHandler<'a> {
118
160
}
119
161
ui. set_is_new_dbc ( false ) ;
120
162
}
163
+ ui. set_bitrate ( bitrate as i32 ) ;
164
+ if busload > 0.0 {
165
+ ui. set_bus_load ( busload as i32 ) ;
166
+ }
121
167
} ) ;
122
168
unsafe {
123
169
if NEW_DBC_CHECK {
124
170
NEW_DBC_CHECK = false ;
125
171
break ;
126
172
}
127
173
}
128
- if let Ok ( frame) = self . iface . recv_frame ( ) {
129
- let id = frame. can_id ( ) ;
130
- let frame_id = id & !0x80000000 ;
131
- for message in dbc. messages ( ) {
132
- if frame_id == ( message. message_id ( ) . raw ( ) & !0x80000000 ) {
133
- let padding_data = Self :: pad_to_8_bytes ( frame. data ( ) ) ;
134
- let hex_string = Self :: array_to_hex_string ( frame. data ( ) ) ;
135
- let signal_data = message. parse_from_can ( & padding_data) ;
136
- let _ = self . ui_handle . upgrade_in_event_loop ( move |ui| {
137
- let is_filter = ui. get_is_filter ( ) ;
138
- let messages: ModelRc < CanData > = if !is_filter {
139
- ui. get_messages ( )
140
- } else {
141
- ui. get_filter_messages ( )
142
- } ;
143
- Self :: update_ui_with_signals (
144
- & messages,
145
- frame_id,
146
- signal_data,
147
- hex_string,
148
- ) ;
149
- } ) ;
174
+ match self . iface . recv_frame ( ) {
175
+ Ok ( frame) => {
176
+ let _ = self . ui_handle . upgrade_in_event_loop ( move |ui| {
177
+ ui. set_state ( "OK" . into ( ) ) ;
178
+ } ) ;
179
+ total_bits += ( frame. dlc ( ) as u32 + 6 ) * 8 ; // Data length + overhead (approximation)
180
+ let id = frame. can_id ( ) ;
181
+ let frame_id = id & !0x80000000 ;
182
+ for message in dbc. messages ( ) {
183
+ if frame_id == ( message. message_id ( ) . raw ( ) & !0x80000000 ) {
184
+ let padding_data = Self :: pad_to_8_bytes ( frame. data ( ) ) ;
185
+ let hex_string = Self :: array_to_hex_string ( frame. data ( ) ) ;
186
+ let signal_data = message. parse_from_can ( & padding_data) ;
187
+ let _ = self . ui_handle . upgrade_in_event_loop ( move |ui| {
188
+ let is_filter = ui. get_is_filter ( ) ;
189
+ let messages: ModelRc < CanData > = if !is_filter {
190
+ ui. get_messages ( )
191
+ } else {
192
+ ui. get_filter_messages ( )
193
+ } ;
194
+ Self :: update_ui_with_signals (
195
+ & messages,
196
+ frame_id,
197
+ signal_data,
198
+ hex_string,
199
+ ) ;
200
+ } ) ;
201
+ }
150
202
}
151
203
}
152
- } else {
153
- sleep ( Duration :: from_millis ( 50 ) ) ;
204
+ Err ( e) => {
205
+ let _ = self . ui_handle . upgrade_in_event_loop ( move |ui| {
206
+ if e != PcanError :: QrcvEmpty {
207
+ ui. set_state ( format ! ( "{:?}" , e) . into ( ) ) ;
208
+ }
209
+ } ) ;
210
+ }
154
211
}
155
212
}
156
213
}
@@ -163,7 +220,10 @@ impl<'a> CanHandler<'a> {
163
220
) {
164
221
for ( message_count, message) in messages. iter ( ) . enumerate ( ) {
165
222
if message. can_id == format ! ( "{:08X}" , frame_id) {
223
+ let now = Utc :: now ( ) . timestamp_micros ( ) ;
166
224
let can_signals = Self :: create_can_signals ( & message, & signal_data) ;
225
+ let circle_time =
226
+ ( now - ( message. time_stamp ) . parse :: < i64 > ( ) . unwrap ( ) ) as f32 / 1000.0 ;
167
227
messages. set_row_data (
168
228
message_count,
169
229
CanData {
@@ -177,6 +237,8 @@ impl<'a> CanHandler<'a> {
177
237
} else {
178
238
ODD_COLOR
179
239
} ,
240
+ circle_time : format ! ( "{:.02} ms" , circle_time) . into ( ) ,
241
+ time_stamp : now. to_string ( ) . into ( ) ,
180
242
} ,
181
243
) ;
182
244
break ;
@@ -240,4 +302,28 @@ impl<'a> CanHandler<'a> {
240
302
hex_string. pop ( ) ; // Remove the trailing space
241
303
hex_string
242
304
}
305
+
306
+ fn bitrate ( & self ) -> Option < u32 > {
307
+ let bitrate_map: HashMap < & str , u32 > = [
308
+ ( "1 Mbit/s" , 1_000_000 ) ,
309
+ ( "800 kbit/s" , 800_000 ) ,
310
+ ( "500 kbit/s" , 500_000 ) ,
311
+ ( "250 kbit/s" , 250_000 ) ,
312
+ ( "125 kbit/s" , 125_000 ) ,
313
+ ( "100 kbit/s" , 100_000 ) ,
314
+ ( "95.238 kbit/s" , 95_238 ) ,
315
+ ( "83.333 kbit/s" , 83_333 ) ,
316
+ ( "50 kbit/s" , 50_000 ) ,
317
+ ( "47.619 kbit/s" , 47_619 ) ,
318
+ ( "33.333 kbit/s" , 33_333 ) ,
319
+ ( "20 kbit/s" , 20_000 ) ,
320
+ ( "10 kbit/s" , 10_000 ) ,
321
+ ( "5 kbit/s" , 5_000 ) ,
322
+ ]
323
+ . iter ( )
324
+ . cloned ( )
325
+ . collect ( ) ;
326
+
327
+ bitrate_map. get ( self . bitrate . as_str ( ) ) . copied ( )
328
+ }
243
329
}
0 commit comments