Skip to content

Commit 934a6b0

Browse files
committedApr 23, 2015
runtime,coredevice: Ethernet support (buggy)
1 parent 1968304 commit 934a6b0

File tree

8 files changed

+283
-56
lines changed

8 files changed

+283
-56
lines changed
 

Diff for: ‎artiq/coredevice/comm_tcp.py

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ def open(self):
1818
return
1919
self.socket = socket.create_connection((self.host, self.port))
2020
logger.debug("connected to host %s on port %d", self.host, self.port)
21+
self.write(b"ARTIQ coredev\n")
2122

2223
def close(self):
2324
if not hasattr(self, "socket"):

Diff for: ‎benchmarks/ddb.pyon

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
{
22
"comm": {
33
"type": "local",
4-
"module": "artiq.coredevice.comm_serial",
4+
"module": "artiq.coredevice.comm_tcp",
55
"class": "Comm",
6-
"arguments": {"serial_dev": "/dev/ttyUSB1"}
6+
"arguments": {"host": "192.168.0.42"}
77
},
88
"core": {
99
"type": "local",

Diff for: ‎examples/master/ddb.pyon

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
{
22
"comm": {
33
"type": "local",
4-
"module": "artiq.coredevice.comm_serial",
4+
"module": "artiq.coredevice.comm_tcp",
55
"class": "Comm",
6-
"arguments": {"serial_dev": "/dev/ttyUSB1"}
6+
"arguments": {"host": "192.168.0.42"}
77
},
88
"core": {
99
"type": "local",

Diff for: ‎soc/runtime/liblwip/netif/liteethif.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ static struct pbuf *liteeth_low_level_input(struct netif *netif)
9393
if(rxslot)
9494
rxbuffer = rxbuffer1;
9595
else
96-
rxbuffer = rxbuffer0;
96+
rxbuffer = rxbuffer0;
9797

9898
p = pbuf_alloc(PBUF_RAW, rxlen, PBUF_POOL);
9999
q = p;

Diff for: ‎soc/runtime/log.c

+8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#include <stdarg.h>
22
#include <stdio.h>
33

4+
#include <generated/csr.h>
5+
46
#include "log.h"
57

68
static int buffer_index;
@@ -18,6 +20,12 @@ void log_va(const char *fmt, va_list args)
1820
}
1921
buffer[buffer_index] = '\n';
2022
buffer_index = (buffer_index + 1) % LOG_BUFFER_SIZE;
23+
24+
#ifdef CSR_ETHMAC_BASE
25+
/* Since main comms are over ethernet, the serial port
26+
* is free for us to use. */
27+
puts(outbuf);
28+
#endif
2129
}
2230

2331
void log(const char *fmt, ...)

Diff for: ‎soc/runtime/main.c

+248-38
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,13 @@ unsigned char macadr[6] = {0x10, 0xe2, 0xd5, 0x00, 0x00, 0x00};
2929

3030
u32_t clock_ms;
3131

32-
static void clock_init(void)
33-
{
34-
timer0_en_write(0);
35-
timer0_load_write(0xffffffff);
36-
timer0_reload_write(0xffffffff);
37-
timer0_en_write(1);
38-
clock_ms = 0;
39-
}
40-
4132
u32_t sys_now(void)
4233
{
4334
unsigned int freq;
4435
unsigned int prescaler;
4536

4637
freq = identifier_frequency_read();
47-
prescaler = freq/1000; /* sys_now expect time in ms */
38+
prescaler = freq/1000; /* sys_now expects time in ms */
4839
timer0_update_value_write(1);
4940
clock_ms += (0xffffffff - timer0_value_read())/prescaler;
5041
/* Reset timer to avoid rollover, this will increase clock_ms
@@ -64,20 +55,246 @@ static void lwip_service(void)
6455
ethmac_sram_writer_ev_pending_write(ETHMAC_EV_SRAM_WRITER);
6556
}
6657
}
67-
#endif
6858

69-
void comm_service(void)
59+
static void network_init(void)
60+
{
61+
struct ip4_addr local_ip;
62+
struct ip4_addr netmask;
63+
struct ip4_addr gateway_ip;
64+
65+
timer0_en_write(0);
66+
timer0_load_write(0xffffffff);
67+
timer0_reload_write(0xffffffff);
68+
timer0_en_write(1);
69+
clock_ms = 0;
70+
71+
IP4_ADDR(&local_ip, 192, 168, 0, 42);
72+
IP4_ADDR(&netmask, 255, 255, 255, 0);
73+
IP4_ADDR(&gateway_ip, 192, 168, 0, 1);
74+
75+
lwip_init();
76+
77+
netif_add(&netif, &local_ip, &netmask, &gateway_ip, 0, liteeth_init, ethernet_input);
78+
netif_set_default(&netif);
79+
netif_set_up(&netif);
80+
netif_set_link_up(&netif);
81+
}
82+
83+
struct kserver_connstate {
84+
int magic_recognized;
85+
struct pbuf *rp;
86+
int rp_offset;
87+
};
88+
89+
static struct kserver_connstate *cs_new(void)
90+
{
91+
struct kserver_connstate *cs;
92+
93+
cs = (struct kserver_connstate *)mem_malloc(sizeof(struct kserver_connstate));
94+
if(!cs)
95+
return NULL;
96+
cs->magic_recognized = 0;
97+
cs->rp = NULL;
98+
cs->rp_offset = 0;
99+
return cs;
100+
}
101+
102+
static void cs_free(struct kserver_connstate *cs)
103+
{
104+
if(cs->rp)
105+
pbuf_free(cs->rp);
106+
mem_free(cs);
107+
}
108+
109+
static const char kserver_magic[] = "ARTIQ coredev\n";
110+
111+
static int magic_ok(struct kserver_connstate *cs)
112+
{
113+
return cs->magic_recognized >= 14;
114+
}
115+
116+
static struct kserver_connstate *active_cs;
117+
static struct tcp_pcb *active_pcb;
118+
119+
static void kserver_close(struct kserver_connstate *cs, struct tcp_pcb *pcb)
120+
{
121+
if(cs == active_cs) {
122+
session_end();
123+
active_cs = NULL;
124+
active_pcb = NULL;
125+
}
126+
127+
/* lwip loves to call back with broken pointers. Prevent that. */
128+
tcp_arg(pcb, NULL);
129+
tcp_recv(pcb, NULL);
130+
tcp_sent(pcb, NULL);
131+
tcp_err(pcb, NULL);
132+
133+
cs_free(cs);
134+
tcp_close(pcb);
135+
}
136+
137+
static err_t kserver_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
138+
{
139+
struct kserver_connstate *cs;
140+
141+
cs = (struct kserver_connstate *)arg;
142+
if(p) {
143+
if(cs->rp)
144+
pbuf_cat(cs->rp, p);
145+
else {
146+
cs->rp = p;
147+
cs->rp_offset = 0;
148+
}
149+
} else
150+
kserver_close(cs, pcb);
151+
return ERR_OK;
152+
}
153+
154+
static err_t kserver_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
155+
{
156+
session_ack_mem(len);
157+
return ERR_OK;
158+
}
159+
160+
static void tcp_pcb_service(void *arg, struct tcp_pcb *pcb)
161+
{
162+
struct kserver_connstate *cs;
163+
int remaining_in_pbuf;
164+
char *rpp;
165+
struct pbuf *next;
166+
int r;
167+
168+
cs = (struct kserver_connstate *)arg;
169+
170+
while(cs->rp) {
171+
remaining_in_pbuf = cs->rp->len - cs->rp_offset;
172+
rpp = (char *)cs->rp->payload;
173+
while(remaining_in_pbuf > 0) {
174+
if(cs == active_cs) {
175+
r = session_input(&rpp[cs->rp_offset], remaining_in_pbuf);
176+
if(r > 0) {
177+
tcp_recved(pcb, r);
178+
cs->rp_offset += r;
179+
remaining_in_pbuf -= r;
180+
} else if(r == 0)
181+
return;
182+
else
183+
kserver_close(cs, pcb);
184+
} else {
185+
if(rpp[cs->rp_offset] == kserver_magic[cs->magic_recognized]) {
186+
cs->magic_recognized++;
187+
if(magic_ok(cs)) {
188+
if(active_cs)
189+
kserver_close(active_cs, active_pcb);
190+
session_start();
191+
active_cs = cs;
192+
active_pcb = pcb;
193+
tcp_sent(pcb, kserver_sent);
194+
}
195+
} else {
196+
kserver_close(cs, pcb);
197+
return;
198+
}
199+
remaining_in_pbuf--;
200+
cs->rp_offset++;
201+
tcp_recved(pcb, 1);
202+
}
203+
}
204+
next = cs->rp->next;
205+
if(cs->rp->tot_len != cs->rp->len) {
206+
pbuf_ref(next);
207+
pbuf_free(cs->rp);
208+
cs->rp = next;
209+
cs->rp_offset = 0;
210+
} else {
211+
pbuf_free(cs->rp);
212+
cs->rp = NULL;
213+
}
214+
}
215+
}
216+
217+
static void kserver_err(void *arg, err_t err)
218+
{
219+
struct kserver_connstate *cs;
220+
221+
cs = (struct kserver_connstate *)arg;
222+
cs_free(cs);
223+
}
224+
225+
static struct tcp_pcb *listen_pcb;
226+
227+
static err_t kserver_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
228+
{
229+
struct kserver_connstate *cs;
230+
231+
cs = cs_new();
232+
if(!cs)
233+
return ERR_MEM;
234+
tcp_accepted(listen_pcb);
235+
tcp_arg(newpcb, cs);
236+
tcp_recv(newpcb, kserver_recv);
237+
tcp_err(newpcb, kserver_err);
238+
return ERR_OK;
239+
}
240+
241+
static void kserver_init(void)
242+
{
243+
listen_pcb = tcp_new();
244+
tcp_bind(listen_pcb, IP_ADDR_ANY, 1381);
245+
listen_pcb = tcp_listen(listen_pcb);
246+
tcp_accept(listen_pcb, kserver_accept);
247+
}
248+
249+
extern struct tcp_pcb *tcp_active_pcbs;
250+
251+
static void kserver_service(void)
252+
{
253+
struct tcp_pcb *pcb;
254+
void *data;
255+
int len, sndbuf;
256+
257+
/* Assume all active TCP PCBs with a non-NULL arg are our connections. */
258+
pcb = tcp_active_pcbs;
259+
while(pcb) {
260+
if(pcb->callback_arg)
261+
tcp_pcb_service(pcb->callback_arg, pcb);
262+
pcb = pcb->next;
263+
}
264+
265+
if(active_cs) {
266+
session_poll(&data, &len);
267+
if(len > 0) {
268+
sndbuf = tcp_sndbuf(active_pcb);
269+
if(len > sndbuf)
270+
len = sndbuf;
271+
tcp_write(active_pcb, data, len, 0);
272+
session_ack_data(len);
273+
}
274+
}
275+
}
276+
277+
static void regular_main(void)
278+
{
279+
network_init();
280+
kserver_init();
281+
282+
while(1) {
283+
lwip_service();
284+
kserver_service();
285+
}
286+
}
287+
288+
#else /* CSR_ETHMAC_BASE */
289+
290+
static void serial_service(void)
70291
{
71292
char *txdata;
72293
int txlen;
73294
static char rxdata;
74295
static int rxpending;
75296
int r, i;
76297

77-
#ifdef CSR_ETHMAC_BASE
78-
lwip_service();
79-
#endif
80-
81298
if(!rxpending && uart_read_nonblock()) {
82299
rxdata = uart_read();
83300
rxpending = 1;
@@ -86,43 +303,30 @@ void comm_service(void)
86303
r = session_input(&rxdata, 1);
87304
if(r > 0)
88305
rxpending = 0;
306+
if(r < 0) {
307+
session_end();
308+
session_start();
309+
}
89310
}
90311

91312
session_poll((void **)&txdata, &txlen);
92313
if(txlen > 0) {
93314
for(i=0;i<txlen;i++)
94315
uart_write(txdata[i]);
95-
session_ack(txlen);
316+
session_ack_data(txlen);
317+
session_ack_mem(txlen);
96318
}
97319
}
98320

99321
static void regular_main(void)
100322
{
101-
#ifdef CSR_ETHMAC_BASE
102-
struct ip4_addr local_ip;
103-
struct ip4_addr netmask;
104-
struct ip4_addr gateway_ip;
105-
106-
time_init();
107-
clock_init();
108-
109-
IP4_ADDR(&local_ip, 192, 168, 0, 42);
110-
IP4_ADDR(&netmask, 255, 255, 255, 0);
111-
IP4_ADDR(&gateway_ip, 192, 168, 0, 1);
112-
113-
lwip_init();
114-
115-
netif_add(&netif, &local_ip, &netmask, &gateway_ip, 0, liteeth_init, ethernet_input);
116-
netif_set_default(&netif);
117-
netif_set_up(&netif);
118-
netif_set_link_up(&netif);
119-
#endif
120-
323+
/* Open the session for the serial control. */
121324
session_start();
122325
while(1)
123-
comm_service();
326+
serial_service();
124327
}
125328

329+
#endif
126330

127331
static void blink_led(void)
128332
{
@@ -169,6 +373,12 @@ int main(void)
169373
#else
170374
puts("ARTIQ runtime built "__DATE__" "__TIME__" for UP systems\n");
171375
#endif
376+
#ifdef CSR_ETHMAC_BASE
377+
puts("Accepting sessions on Ethernet");
378+
#else
379+
puts("Accepting sessions on serial link");
380+
#endif
381+
puts("Press 't' to enter test mode...");
172382
blink_led();
173383

174384
if(check_test_mode()) {

Diff for: ‎soc/runtime/session.c

+19-11
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ static struct {
3030
char data[BUFFER_IN_SIZE];
3131
} __attribute__((packed)) _buffer_in __attribute__((aligned(4)));
3232
#define buffer_in _buffer_in.data
33-
static int buffer_out_index;
33+
static int buffer_out_index_data;
34+
static int buffer_out_index_mem;
3435
static char buffer_out[BUFFER_OUT_SIZE];
3536

3637
static int get_in_packet_len(void)
@@ -53,7 +54,8 @@ static void submit_output(int len)
5354
{
5455
memset(&buffer_out[0], 0x5a, 4);
5556
memcpy(&buffer_out[4], &len, 4);
56-
buffer_out_index = 0;
57+
buffer_out_index_data = 0;
58+
buffer_out_index_mem = 0;
5759
}
5860

5961
static int user_kernel_state;
@@ -68,7 +70,8 @@ enum {
6870
void session_start(void)
6971
{
7072
buffer_in_index = 0;
71-
buffer_out_index = 0;
73+
buffer_out_index_data = 0;
74+
buffer_out_index_mem = 0;
7275
memset(&buffer_out[4], 0, 4);
7376
#ifdef ARTIQ_AMP
7477
kloader_stop_kernel();
@@ -214,8 +217,8 @@ int rpc(int rpc_num, ...)
214217
va_end(args);
215218

216219
user_kernel_state = USER_KERNEL_WAIT_RPC;
217-
while(user_kernel_state == USER_KERNEL_WAIT_RPC)
218-
comm_service();
220+
/*while(user_kernel_state == USER_KERNEL_WAIT_RPC)
221+
comm_service();*/
219222

220223
if(rpc_reply_eid != EID_NONE)
221224
exception_raise(rpc_reply_eid);
@@ -491,15 +494,20 @@ void session_poll(void **data, int *len)
491494
}
492495
#endif
493496

494-
*len = l - buffer_out_index;
495-
*data = &buffer_out[buffer_out_index];
497+
*len = l - buffer_out_index_data;
498+
*data = &buffer_out[buffer_out_index_data];
496499
}
497500

498-
void session_ack(int len)
501+
void session_ack_data(int len)
499502
{
500-
buffer_out_index += len;
501-
if(buffer_out_index >= get_out_packet_len()) {
503+
buffer_out_index_data += len;
504+
}
505+
506+
void session_ack_mem(int len)
507+
{
508+
buffer_out_index_mem += len;
509+
if(buffer_out_index_mem >= get_out_packet_len()) {
502510
memset(&buffer_out[4], 0, 4);
503-
buffer_out_index = 0;
511+
buffer_out_index_mem = 0;
504512
}
505513
}

Diff for: ‎soc/runtime/session.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ void session_end(void);
66

77
int session_input(void *data, int len);
88
void session_poll(void **data, int *len);
9-
void session_ack(int len);
9+
void session_ack_data(int len);
10+
void session_ack_mem(int len);
1011

1112
int rpc(int rpc_num, ...);
12-
void comm_service(void);
1313

1414
#endif /* __SESSION_H */

0 commit comments

Comments
 (0)
Please sign in to comment.