add throughput test, switch 1338 to use UDP
parent
d42335075c
commit
657fdb8469
|
@ -27,9 +27,9 @@ struct espconn tcp_conn;
|
|||
// TCP specific protocol structure.
|
||||
esp_tcp tcp_proto;
|
||||
|
||||
// interrupt communication on port 1338
|
||||
// interrupt communication on port 1338, UDP!
|
||||
struct espconn inter_conn;
|
||||
esp_tcp inter_proto;
|
||||
esp_udp inter_proto;
|
||||
|
||||
uint32_t sendData[0x14] = {0};
|
||||
uint32_t recvData[0x40] = {0};
|
||||
|
@ -113,16 +113,19 @@ void ICACHE_FLASH_ATTR tcp_connect_cb(void *arg) {
|
|||
espconn_regist_recvcb(conn, tcp_rx_cb);
|
||||
}
|
||||
|
||||
static volatile os_timer_t some_timer;
|
||||
void ICACHE_FLASH_ATTR some_timerfunc(void *arg) {
|
||||
// must be 0x44, because we can fit 4 more
|
||||
uint8_t buf[0x44*0x10];
|
||||
int queue_send_len = -1;
|
||||
|
||||
void ICACHE_FLASH_ATTR poll_can(void *arg) {
|
||||
uint8_t timerRecvData[0x44] = {0};
|
||||
uint8_t buf[0x44*0x10];
|
||||
int i = 0;
|
||||
int j;
|
||||
|
||||
while (i < 0x40) {
|
||||
int len = spi_comm("\x01\x00\x00\x00", 4, timerRecvData, 0x40);
|
||||
if (len == 0) break;
|
||||
if (len > 0x40) { os_printf("SPI LENGTH ERROR!"); break; }
|
||||
|
||||
// if it sends it, assume it's valid CAN
|
||||
for (j = 0; j < len; j += 0x10) {
|
||||
|
@ -132,30 +135,27 @@ void ICACHE_FLASH_ATTR some_timerfunc(void *arg) {
|
|||
}
|
||||
|
||||
if (i != 0) {
|
||||
espconn_send(&inter_conn, buf, i*0x10);
|
||||
int ret = espconn_sendto(&inter_conn, buf, i*0x10);
|
||||
if (ret != 0) {
|
||||
os_printf("send failed: %d\n", ret);
|
||||
queue_send_len = i*0x10;
|
||||
} else {
|
||||
queue_send_len = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
volatile int timer_started = 0;
|
||||
|
||||
void ICACHE_FLASH_ATTR inter_disc_cb(void *arg) {
|
||||
if (timer_started) {
|
||||
os_timer_disarm(&some_timer);
|
||||
timer_started = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR inter_connect_cb(void *arg) {
|
||||
struct espconn *conn = (struct espconn *)arg;
|
||||
espconn_set_opt(&inter_conn, ESPCONN_NODELAY);
|
||||
espconn_regist_disconcb(conn, inter_disc_cb);
|
||||
|
||||
// setup timer at 200hz
|
||||
// TODO: disable when it runs out
|
||||
if (!timer_started) {
|
||||
os_timer_setfn(&some_timer, (os_timer_func_t *)some_timerfunc, NULL);
|
||||
os_timer_arm(&some_timer, 5, 1);
|
||||
timer_started = 1;
|
||||
int timer_started = 0;
|
||||
void ICACHE_FLASH_ATTR inter_recv_cb(void *arg, char *pusrdata, unsigned short length) {
|
||||
os_printf("UDP recv\n");
|
||||
remot_info *premot = NULL;
|
||||
if (espconn_get_connection_info(&inter_conn,&premot,0) == ESPCONN_OK) {
|
||||
timer_started = 1;
|
||||
inter_conn.proto.udp->remote_port = premot->remote_port;
|
||||
inter_conn.proto.udp->remote_ip[0] = premot->remote_ip[0];
|
||||
inter_conn.proto.udp->remote_ip[1] = premot->remote_ip[1];
|
||||
inter_conn.proto.udp->remote_ip[2] = premot->remote_ip[2];
|
||||
inter_conn.proto.udp->remote_ip[3] = premot->remote_ip[3];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -217,12 +217,16 @@ void ICACHE_FLASH_ATTR wifi_init() {
|
|||
|
||||
// setup inter server
|
||||
inter_proto.local_port = 1338;
|
||||
inter_conn.type = ESPCONN_TCP;
|
||||
inter_conn.state = ESPCONN_NONE;
|
||||
inter_conn.proto.tcp = &inter_proto;
|
||||
espconn_regist_connectcb(&inter_conn, inter_connect_cb);
|
||||
espconn_accept(&inter_conn);
|
||||
espconn_regist_time(&inter_conn, 60, 0); // 60s timeout for all connections
|
||||
const char udp_remote_ip[4] = {255, 255, 255, 255};
|
||||
os_memcpy(inter_proto.remote_ip, udp_remote_ip, 4);
|
||||
inter_proto.remote_port = 1338;
|
||||
|
||||
inter_conn.type = ESPCONN_UDP;
|
||||
inter_conn.proto.udp = &inter_proto;
|
||||
|
||||
espconn_regist_recvcb(&inter_conn, inter_recv_cb);
|
||||
|
||||
espconn_create(&inter_conn);
|
||||
}
|
||||
|
||||
#define LOOP_PRIO 2
|
||||
|
@ -284,10 +288,21 @@ void ICACHE_FLASH_ATTR user_init()
|
|||
|
||||
// jump to OS
|
||||
system_os_task(loop, LOOP_PRIO, my_queue, QUEUE_SIZE);
|
||||
system_os_post(LOOP_PRIO, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
void ICACHE_FLASH_ATTR loop(os_event_t *events) {
|
||||
if (timer_started) {
|
||||
if (queue_send_len == -1) {
|
||||
poll_can(NULL);
|
||||
} else {
|
||||
int ret = espconn_sendto(&inter_conn, buf, queue_send_len);
|
||||
if (ret == 0) {
|
||||
queue_send_len = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
system_os_post(LOOP_PRIO, 0, 0);
|
||||
}
|
||||
|
||||
|
|
47
lib/panda.py
47
lib/panda.py
|
@ -1,6 +1,5 @@
|
|||
# python library to interface with panda
|
||||
import struct
|
||||
|
||||
import hashlib
|
||||
import socket
|
||||
import usb1
|
||||
|
@ -11,6 +10,38 @@ try:
|
|||
except:
|
||||
pass
|
||||
|
||||
def parse_can_buffer(dat):
|
||||
ret = []
|
||||
for j in range(0, len(dat), 0x10):
|
||||
ddat = dat[j:j+0x10]
|
||||
f1, f2 = struct.unpack("II", ddat[0:8])
|
||||
extended = 4
|
||||
if f1 & extended:
|
||||
address = f1 >> 3
|
||||
else:
|
||||
address = f1 >> 21
|
||||
ret.append((address, f2>>16, ddat[8:8+(f2&0xF)], (f2>>4)&0xf))
|
||||
return ret
|
||||
|
||||
class PandaWifiStreaming(object):
|
||||
def __init__(self, ip="192.168.0.10", port=1338):
|
||||
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
self.sock.sendto("hello", (ip, port))
|
||||
self.sock.setblocking(0)
|
||||
self.ip = ip
|
||||
self.port = port
|
||||
|
||||
def can_recv(self):
|
||||
ret = []
|
||||
while 1:
|
||||
try:
|
||||
dat, addr = self.sock.recvfrom(0x200*0x10)
|
||||
if addr == (self.ip, self.port):
|
||||
ret += parse_can_buffer(dat)
|
||||
except socket.error:
|
||||
break
|
||||
return ret
|
||||
|
||||
# stupid tunneling of USB over wifi and SPI
|
||||
class WifiHandle(object):
|
||||
def __init__(self, ip="192.168.0.10", port=1337):
|
||||
|
@ -153,18 +184,6 @@ class Panda(object):
|
|||
self.can_send_many([[addr, None, dat, bus]])
|
||||
|
||||
def can_recv(self):
|
||||
def __parse_can_buffer(dat):
|
||||
ret = []
|
||||
for j in range(0, len(dat), 0x10):
|
||||
ddat = dat[j:j+0x10]
|
||||
f1, f2 = struct.unpack("II", ddat[0:8])
|
||||
extended = 4
|
||||
if f1 & extended:
|
||||
address = f1 >> 3
|
||||
else:
|
||||
address = f1 >> 21
|
||||
ret.append((address, f2>>16, ddat[8:8+(f2&0xF)], (f2>>4)&0xf))
|
||||
return ret
|
||||
dat = ""
|
||||
while 1:
|
||||
try:
|
||||
|
@ -172,7 +191,7 @@ class Panda(object):
|
|||
break
|
||||
except (USBErrorIO, USBErrorOverflow):
|
||||
print "CAN: BAD RECV, RETRYING"
|
||||
return __parse_can_buffer(dat)
|
||||
return parse_can_buffer(dat)
|
||||
|
||||
# ******************* serial *******************
|
||||
|
||||
|
|
|
@ -13,6 +13,9 @@ if __name__ == "__main__":
|
|||
port_number = int(os.getenv("PORT", 0))
|
||||
|
||||
serials = Panda.list()
|
||||
if os.getenv("SERIAL"):
|
||||
serials = filter(lambda x: x==os.getenv("SERIAL"), serials)
|
||||
|
||||
pandas = map(lambda x: Panda(x, False), serials)
|
||||
while 1:
|
||||
for i, panda in enumerate(pandas):
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
#!/usr/bin/env python
|
||||
import os
|
||||
import struct
|
||||
import time
|
||||
from panda.lib.panda import Panda, PandaWifiStreaming
|
||||
from tqdm import tqdm
|
||||
|
||||
# test throughput between USB and wifi
|
||||
|
||||
if __name__ == "__main__":
|
||||
print Panda.list()
|
||||
p_out = Panda("108018800f51363038363036")
|
||||
print p_out.get_serial()
|
||||
#p_in = Panda("02001b000f51363038363036")
|
||||
p_in = Panda("WIFI")
|
||||
print p_in.get_serial()
|
||||
|
||||
p_in = PandaWifiStreaming()
|
||||
|
||||
#while 1:
|
||||
# p_in.can_recv()
|
||||
#exit(0)
|
||||
|
||||
p_out.set_controls_allowed(True)
|
||||
|
||||
set_out, set_in = set(), set()
|
||||
|
||||
# drain
|
||||
p_out.can_recv()
|
||||
p_in.can_recv()
|
||||
|
||||
BATCH_SIZE = 1
|
||||
for a in tqdm(range(0, 10000, BATCH_SIZE)):
|
||||
for b in range(0, BATCH_SIZE):
|
||||
msg = "\xaa"*4 + struct.pack("I", a+b)
|
||||
if a%2 == 0:
|
||||
p_out.can_send(0xaa, msg, 0)
|
||||
|
||||
dat_out, dat_in = p_out.can_recv(), p_in.can_recv()
|
||||
if len(dat_in) != 0:
|
||||
print len(dat_in)
|
||||
|
||||
num_out = [struct.unpack("I", i[4:])[0] for _, _, i, _ in dat_out]
|
||||
num_in = [struct.unpack("I", i[4:])[0] for _, _, i, _ in dat_in]
|
||||
|
||||
set_in.update(num_in)
|
||||
set_out.update(num_out)
|
||||
|
||||
# swag
|
||||
print "waiting for packets"
|
||||
time.sleep(1.0)
|
||||
dat_in = p_in.can_recv()
|
||||
num_in = [struct.unpack("I", i[4:])[0] for _, _, i, _ in dat_in]
|
||||
set_in.update(num_in)
|
||||
|
||||
if len(set_out - set_in):
|
||||
print "MISSING %d" % len(set_out - set_in)
|
||||
if len(set_out - set_in) < 100:
|
||||
print map(hex, sorted(list(set_out - set_in)))
|
Loading…
Reference in New Issue