add throughput test, switch 1338 to use UDP

master
Firmware Batman 2017-05-16 17:01:29 -07:00
parent d42335075c
commit 657fdb8469
4 changed files with 142 additions and 46 deletions

View File

@ -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);
}

View File

@ -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 *******************

View File

@ -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):

View File

@ -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)))