runtime: send analyzer data

This commit is contained in:
Sebastien Bourdeauducq 2015-12-18 00:13:22 +08:00
parent 6ae41e6024
commit 73794b5c25
5 changed files with 172 additions and 2 deletions

View File

@ -4,7 +4,7 @@ include $(MISOC_DIRECTORY)/software/common.mak
PYTHON ?= python3.5
OBJECTS := isr.o clock.o rtiocrg.o flash_storage.o mailbox.o \
session.o log.o moninj.o net_server.o bridge_ctl.o \
session.o log.o analyzer.o moninj.o net_server.o bridge_ctl.o \
ksupport_data.o kloader.o test_mode.o main.o
OBJECTS_KSUPPORT := ksupport.o artiq_personality.o mailbox.o \
bridge.o rtio.o ttl.o dds.o

138
artiq/runtime/analyzer.c Normal file
View File

@ -0,0 +1,138 @@
#include <generated/csr.h>
#include "analyzer.h"
#ifdef CSR_RTIO_ANALYZER_BASE
struct analyzer_header {
unsigned int sent_bytes;
unsigned long long int total_byte_count;
unsigned int overflow_occured;
} __attribute__((packed));
#define ANALYZER_BUFFER_SIZE (512*1024)
static struct analyzer_header analyzer_header;
static char analyzer_buffer[ANALYZER_BUFFER_SIZE] __attribute__((aligned(64)));
static void arm(void)
{
rtio_analyzer_message_encoder_overflow_reset_write(1);
rtio_analyzer_dma_base_address_write((unsigned int)analyzer_buffer);
rtio_analyzer_dma_last_address_write((unsigned int)analyzer_buffer + ANALYZER_BUFFER_SIZE - 1);
rtio_analyzer_dma_reset_write(1);
rtio_analyzer_dma_enable_write(1);
}
static void disarm(void)
{
rtio_analyzer_dma_enable_write(0);
while(rtio_analyzer_dma_busy_read());
}
void analyzer_init(void)
{
arm();
}
enum {
SEND_STATE_HEADER,
SEND_STATE_POST_POINTER, /* send from pointer to end of buffer */
SEND_STATE_PRE_POINTER, /* send from start of buffer to pointer-1 */
SEND_STATE_TERMINATE
};
static int send_state;
static int pointer;
static int wraparound;
static int offset_consumed;
static int offset_sent;
void analyzer_start(void)
{
disarm();
analyzer_header.total_byte_count = rtio_analyzer_dma_byte_count_read();
pointer = analyzer_header.total_byte_count % ANALYZER_BUFFER_SIZE;
wraparound = analyzer_header.total_byte_count >= ANALYZER_BUFFER_SIZE;
if(wraparound)
analyzer_header.sent_bytes = ANALYZER_BUFFER_SIZE;
else
analyzer_header.sent_bytes = analyzer_header.total_byte_count;
analyzer_header.overflow_occured = rtio_analyzer_message_encoder_overflow_read();
offset_consumed = 0;
offset_sent = 0;
send_state = SEND_STATE_HEADER;
}
void analyzer_end(void)
{
arm();
}
int analyzer_input(void *data, int length)
{
/* The analyzer never accepts input. */
return -1;
}
void analyzer_poll(void **data, int *length)
{
switch(send_state) {
case SEND_STATE_HEADER:
*length = sizeof(struct analyzer_header) - offset_consumed;
*data = (char *)&analyzer_header + offset_consumed;
break;
case SEND_STATE_POST_POINTER:
*length = ANALYZER_BUFFER_SIZE - pointer - offset_consumed;
*data = analyzer_buffer + pointer + offset_consumed;
break;
case SEND_STATE_PRE_POINTER:
*length = pointer - offset_consumed;
*data = analyzer_buffer + offset_consumed;
break;
case SEND_STATE_TERMINATE:
*length = -1;
break;
}
}
void analyzer_ack_consumed(int length)
{
offset_consumed += length;
}
void analyzer_ack_sent(int length)
{
offset_sent += length;
switch(send_state) {
case SEND_STATE_HEADER:
if(offset_sent >= sizeof(struct analyzer_header)) {
offset_consumed = 0;
offset_sent = 0;
if(wraparound)
send_state = SEND_STATE_POST_POINTER;
else
send_state = SEND_STATE_PRE_POINTER;
}
break;
case SEND_STATE_POST_POINTER:
if(pointer + offset_consumed >= ANALYZER_BUFFER_SIZE) {
offset_consumed = 0;
offset_sent = 0;
send_state = SEND_STATE_PRE_POINTER;
}
break;
case SEND_STATE_PRE_POINTER:
if(offset_sent >= pointer)
send_state = SEND_STATE_TERMINATE;
break;
}
}
#endif

14
artiq/runtime/analyzer.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef __ANALYZER_H
#define __ANALYZER_H
void analyzer_init(void);
void analyzer_start(void);
void analyzer_end(void);
int analyzer_input(void *data, int length);
void analyzer_poll(void **data, int *length);
void analyzer_ack_consumed(int length);
void analyzer_ack_sent(int length);
#endif /* __ANALYZER_H */

View File

@ -28,6 +28,7 @@
#include "test_mode.h"
#include "net_server.h"
#include "session.h"
#include "analyzer.h"
#include "moninj.h"
#ifdef CSR_ETHMAC_BASE
@ -137,11 +138,27 @@ static struct net_server_instance session_inst = {
.ack_sent = session_ack_sent
};
#ifdef CSR_RTIO_ANALYZER_BASE
static struct net_server_instance analyzer_inst = {
.port = 1382,
.start = analyzer_start,
.end = analyzer_end,
.input = analyzer_input,
.poll = analyzer_poll,
.ack_consumed = analyzer_ack_consumed,
.ack_sent = analyzer_ack_sent
};
#endif
static void regular_main(void)
{
puts("Accepting sessions on Ethernet.");
network_init();
net_server_init(&session_inst);
#ifdef CSR_RTIO_ANALYZER_BASE
analyzer_init();
net_server_init(&analyzer_inst);
#endif
moninj_init();
session_end();

View File

@ -203,7 +203,8 @@ static void out_packet_advance_consumed(int length)
buffer_out_read_cursor += length;
}
static void out_packet_advance_sent(int length) {
static void out_packet_advance_sent(int length)
{
if(buffer_out_sent_cursor + length > buffer_out_write_cursor) {
log("session.c: write underrun (send) while trying to"
" acknowledge %d bytes (%d remaining)",