Skip to content

Commit 21b8baf

Browse files
committed
Update Arduino Ethernet driver
1 parent 082604c commit 21b8baf

File tree

4 files changed

+100
-41
lines changed

4 files changed

+100
-41
lines changed

examples/debug_on_pico/xcp_config.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949

5050
#define XCP_ENABLE_EXTERN_C_GUARDS (XCP_ON)
5151

52-
#define XCP_ENABLE_SLAVE_BLOCKMODE (XCP_ON)
52+
#define XCP_ENABLE_SLAVE_BLOCKMODE (XCP_OFF)
5353
#define XCP_ENABLE_MASTER_BLOCKMODE (XCP_OFF)
5454

5555
#define XCP_ENABLE_STIM (XCP_OFF)

src/hw/pico/hw.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ static void XcpHw_DeinitLocks(void) {
7171

7272
void XcpHw_Init(void) {
7373
board_init();
74-
pico_led_init();
74+
//pico_led_init();
7575
XcpHw_InitLocks();
7676
HwState.StartingTime = XcpHw_GetMs32();
7777
}

src/tl/eth/arduino_networking.cpp

Lines changed: 96 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
/*!!! START-INCLUDE-SECTION !!!*/
4141
#include "xcp.h"
4242
#include "xcp_hw.h"
43+
#include "xcp_tl_timeout.h"
4344
/*!!! END-INCLUDE-SECTION !!!*/
4445

4546
const unsigned long READ_TIMEOUT_MS = 2000; // Timeout when reading a frame
@@ -52,6 +53,7 @@ class ClientWrapper {
5253
virtual size_t write_bytes(const uint8_t* buf, size_t len) = 0;
5354
virtual bool connected() = 0;
5455
virtual void stop() = 0;
56+
virtual bool is_datagram() const = 0;
5557

5658
virtual ~ClientWrapper() {
5759
}
@@ -104,6 +106,10 @@ class EthernetClientWrapper : public ClientWrapper {
104106
}
105107
}
106108

109+
bool is_datagram() const override {
110+
return false;
111+
}
112+
107113
private:
108114

109115
EthernetClient m_client;
@@ -173,14 +179,18 @@ class EthernetUdpClientWrapper : public ClientWrapper {
173179
// no persistent connection to stop for UDP
174180
}
175181

182+
bool is_datagram() const override {
183+
return true;
184+
}
185+
176186
private:
177187

178-
EthernetUDP* m_udp;
179-
IPAddress m_remoteIp;
180-
uint16_t m_remotePort;
181-
uint8_t m_buf[XCP_COMM_BUFLEN];
182-
size_t m_size;
183-
size_t m_offset;
188+
EthernetUDP* m_udp;
189+
IPAddress m_remoteIp;
190+
uint16_t m_remotePort;
191+
uint8_t m_buf[XCP_COMM_BUFLEN];
192+
size_t m_size;
193+
size_t m_offset;
184194
};
185195

186196
class EthernetAdapter : public ArduinoNetworkIf {
@@ -197,6 +207,7 @@ class EthernetAdapter : public ArduinoNetworkIf {
197207
while (!Serial) {
198208
; // wait for serial port to connect. Needed for native USB port only
199209
}
210+
Serial.println("\nBlueparrot XCP (UDP) on Ethernet");
200211
Ethernet.init(10);
201212
delay(1000); // Give the hardware some time to initialize
202213

@@ -220,9 +231,6 @@ class EthernetAdapter : public ArduinoNetworkIf {
220231
Serial.println("Failed to get a valid IP address.");
221232
return false;
222233
}
223-
224-
Serial.print("\nBlueparrot XCP (UDP) on Ethernet -- IP: ");
225-
Serial.println(Ethernet.localIP());
226234
m_udp.begin(m_port);
227235
return true;
228236
}
@@ -250,12 +258,12 @@ class EthernetAdapter : public ArduinoNetworkIf {
250258

251259
private:
252260

253-
uint8_t m_mac_address_storage[6] = XCP_ON_ETHERNET_MAC_ADDRESS;
254-
uint8_t* m_mac_address = m_mac_address_storage;
255-
bool m_use_dhcp;
256-
IPAddress m_ip;
257-
uint16_t m_port;
258-
EthernetUDP m_udp;
261+
uint8_t m_mac_address_storage[6] = XCP_ON_ETHERNET_MAC_ADDRESS;
262+
uint8_t* m_mac_address = m_mac_address_storage;
263+
bool m_use_dhcp;
264+
IPAddress m_ip;
265+
uint16_t m_port;
266+
EthernetUDP m_udp;
259267
EthernetUdpClientWrapper m_udpClientWrapper; // preallocated UDP client wrapper
260268
};
261269
#endif // XCP_ON_ETHERNET_ARDUINO_DRIVER == XCP_ON_ETHERNET_DRIVER_ETHERNET
@@ -325,6 +333,10 @@ class WiFiUdpClientWrapper : public ClientWrapper {
325333
// no-op for UDP
326334
}
327335

336+
bool is_datagram() const override {
337+
return true;
338+
}
339+
328340
private:
329341

330342
WiFiUDP* m_udp;
@@ -393,10 +405,20 @@ class WiFiAdapter : public ArduinoNetworkIf {
393405
WiFiUDP m_udp;
394406
const char* m_ssid;
395407
const char* m_pass;
396-
WiFiUdpClientWrapper m_udpClientWrapper; // preallocated UDP client wrapper
408+
WiFiUdpClientWrapper m_udpClientWrapper;
397409
};
398410
#endif // XCP_ON_ETHERNET_ARDUINO_DRIVER == XCP_ON_ETHERNET_DRIVER_WIFI
399411

412+
static ArduinoNetworkIf* s_net = nullptr;
413+
static ClientWrapper* s_client = nullptr;
414+
static bool s_connected = false;
415+
416+
static volatile bool s_timeout_triggered = false;
417+
418+
static void XcpTl_OnTimeout(void) {
419+
s_timeout_triggered = true;
420+
}
421+
400422
class FrameParser {
401423
public:
402424

@@ -442,16 +464,15 @@ class FrameParser {
442464
}
443465
};
444466

445-
static ArduinoNetworkIf* s_net = nullptr;
446-
static ClientWrapper* s_client = nullptr;
447-
static bool s_connected = false;
448-
449467
static bool ar_read_n(uint8_t* out, size_t n, unsigned long timeout_ms) {
450468
if (!s_client)
451469
return false;
452470
unsigned long start = millis();
453471
size_t got = 0;
454472
while (got < n) {
473+
if (s_timeout_triggered) {
474+
return false;
475+
}
455476
if (!s_client->connected() && s_client->available() == 0) {
456477
return false;
457478
}
@@ -462,16 +483,22 @@ static bool ar_read_n(uint8_t* out, size_t n, unsigned long timeout_ms) {
462483
if (r <= 0)
463484
return false;
464485
got += (size_t)r;
486+
XcpTl_TimeoutReset();
465487
} else {
466-
if (millis() - start > timeout_ms)
488+
XcpTl_TimeoutCheck();
489+
if (millis() - start > timeout_ms) {
490+
s_timeout_triggered = true;
467491
return false;
492+
}
468493
delay(1);
469494
}
470495
}
471496
return true;
472497
}
473498

474499
static int ar_read_header(uint16_t* len, uint16_t* counter) {
500+
s_timeout_triggered = false;
501+
XcpTl_TimeoutStart();
475502
uint8_t hdr[4];
476503
if (!ar_read_n(hdr, 4, READ_TIMEOUT_MS)) {
477504
return 0;
@@ -489,6 +516,8 @@ static int ar_read_data(uint8_t* data, uint16_t len) {
489516
extern "C" {
490517

491518
void XcpTl_Init(void) {
519+
XcpTl_TimeoutInit((uint16_t)READ_TIMEOUT_MS, XcpTl_OnTimeout);
520+
s_timeout_triggered = false;
492521
/* Initialize backend network adapter and start listening. */
493522
#if XCP_ON_ETHERNET_ARDUINO_DRIVER == XCP_ON_ETHERNET_DRIVER_WIFI
494523
s_net = new WiFiAdapter(XCP_ON_ETHERNET_WIFI_SSID, XCP_ON_ETHERNET_WIFI_PASSWORD, XCP_ON_ETHERNET_PORT);
@@ -524,11 +553,14 @@ extern "C" {
524553
}
525554

526555
static void XcpTl_Accept(void) {
527-
if (!s_connected && s_net) {
528-
s_net->process();
529-
ClientWrapper* c = s_net->accept_client();
530-
if (c) {
531-
s_client = c;
556+
if (!s_net) {
557+
return;
558+
}
559+
s_net->process();
560+
ClientWrapper* c = s_net->accept_client();
561+
if (c) {
562+
s_client = c;
563+
if (!s_connected) {
532564
s_connected = true;
533565
XcpTl_SaveConnection();
534566
}
@@ -537,6 +569,7 @@ extern "C" {
537569

538570
void XcpTl_MainFunction(void) {
539571
XcpTl_Accept();
572+
XcpTl_TimeoutCheck();
540573
XcpTl_RxHandler();
541574
}
542575

@@ -558,16 +591,33 @@ extern "C" {
558591

559592
int hres = ar_read_header(&dlc, &counter);
560593
if (hres <= 0) {
561-
/* Connection lost or no data */
594+
if (s_timeout_triggered) {
595+
s_timeout_triggered = false;
596+
XcpTl_TimeoutStop();
597+
Serial.println("Reception timeout (header) — aborting current frame");
598+
return;
599+
}
600+
/* Connection lost or other error */
601+
if (s_client && s_client->is_datagram()) {
602+
/* For UDP, keep last endpoint; just stop TL timeout and abort this frame */
603+
XcpTl_TimeoutStop();
604+
return;
605+
}
562606
XcpTl_ReleaseConnection();
563607
s_client->stop();
564608
s_client = nullptr;
565609
s_connected = false;
610+
XcpTl_TimeoutStop();
566611
return;
567612
}
568613

569-
if (dlc > XCP_TRANSPORT_LAYER_CTO_BUFFER_SIZE || dlc > (uint16_t)XCP_COMM_BUFLEN) {
614+
if ((dlc > XCP_TRANSPORT_LAYER_CTO_BUFFER_SIZE) || (dlc > (uint16_t)XCP_COMM_BUFLEN)) {
570615
// XcpHw_ErrorMsg((char*)"XcpTl_RxHandler: DLC too large", EINVAL);
616+
if (s_client && s_client->is_datagram()) {
617+
/* For UDP, keep endpoint but drop this malformed frame */
618+
XcpTl_TimeoutStop();
619+
return;
620+
}
571621
XcpTl_ReleaseConnection();
572622
s_client->stop();
573623
s_client = nullptr;
@@ -578,28 +628,37 @@ extern "C" {
578628
Xcp_CtoIn.len = dlc;
579629
int dres = ar_read_data(Xcp_CtoIn.data, dlc);
580630
if (dres <= 0) {
631+
if (s_timeout_triggered) {
632+
s_timeout_triggered = false;
633+
XcpTl_TimeoutStop();
634+
Serial.println("Reception timeout (data) — aborting current frame");
635+
return;
636+
}
637+
if (s_client && s_client->is_datagram()) {
638+
/* For UDP, keep last endpoint on short read or error; abort this frame only */
639+
XcpTl_TimeoutStop();
640+
return;
641+
}
581642
XcpTl_ReleaseConnection();
582643
s_client->stop();
583644
s_client = nullptr;
584645
s_connected = false;
646+
XcpTl_TimeoutStop();
585647
return;
586648
}
587-
588649
/* Dispatch the freshly received CTO command. */
589650
Xcp_DispatchCommand(&Xcp_CtoIn);
590-
591-
/* For UDP wrappers, the packet is fully consumed now; mark connection free. */
592-
if (!s_client->connected()) {
593-
XcpTl_ReleaseConnection();
594-
s_client->stop();
595-
s_client = nullptr;
596-
s_connected = false;
597-
}
651+
XcpTl_TimeoutStop();
598652
}
599653

600654
void XcpTl_Send(uint8_t const * buf, uint16_t len) {
601655
XCP_TL_ENTER_CRITICAL();
602656
if (s_connected && s_client) {
657+
#ifdef XCP_UDP_DEBUG
658+
Serial.print("XCP_TL_SEND len="); Serial.print(len);
659+
Serial.print(" conn="); Serial.print(s_connected ? 1 : 0);
660+
Serial.print(" datagram="); Serial.println(s_client->is_datagram() ? 1 : 0);
661+
#endif
603662
/* Data already contains ETH header (LEN/CTR) + payload. */
604663
(void)s_client->write_bytes(buf, len);
605664
}

tools/arduino/hello_xcp/xcp_config.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@
3535
** General Options.
3636
*/
3737
// #define TP_CAN
38-
#define TP_ETHER
39-
//#define TP_SXI
38+
// #define TP_ETHER
39+
#define TP_SXI
4040

4141
/*
4242
** Transport-Layer specific Options.

0 commit comments

Comments
 (0)