aboutsummaryrefslogtreecommitdiffstats
path: root/src/pru
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2017-09-07 17:08:58 -0400
committerKevin O'Connor <kevin@koconnor.net>2017-09-08 11:50:21 -0400
commitd618affd63668459c4c00588ecc15905a81ef079 (patch)
treecc996e0dc74175c02dcef710519b171c3065f516 /src/pru
parent121c747cc887e3548932bb6d10d834427e9cb4d8 (diff)
downloadkutter-d618affd63668459c4c00588ecc15905a81ef079.tar.gz
kutter-d618affd63668459c4c00588ecc15905a81ef079.tar.xz
kutter-d618affd63668459c4c00588ecc15905a81ef079.zip
pru: Batch outgoing writes
Allow pru0 to gather multiple outgoing message blocks into a single rpmsg. This can reduce communication overhead. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Diffstat (limited to 'src/pru')
-rw-r--r--src/pru/pru0.c36
1 files changed, 31 insertions, 5 deletions
diff --git a/src/pru/pru0.c b/src/pru/pru0.c
index 8007823a..1239813d 100644
--- a/src/pru/pru0.c
+++ b/src/pru/pru0.c
@@ -31,6 +31,32 @@ static uint16_t transport_dst;
#define CHAN_DESC "Channel 30"
#define CHAN_PORT 30
+#define RPMSG_HDR_SIZE 16
+static char transmit_buf[RPMSG_BUF_SIZE - RPMSG_HDR_SIZE];
+static int transmit_pos;
+
+// Transmit all pending message blocks
+static void
+flush_messages(void)
+{
+ if (!transmit_pos)
+ return;
+ pru_rpmsg_send(&transport, CHAN_PORT, transport_dst
+ , transmit_buf, transmit_pos);
+ transmit_pos = 0;
+}
+
+// Generate a message block and queue it for transmission
+static void
+build_message(char *msg, int msglen)
+{
+ if (transmit_pos + msglen > sizeof(transmit_buf))
+ flush_messages();
+ memcpy(&transmit_buf[transmit_pos], msg, msglen);
+ command_add_frame(&transmit_buf[transmit_pos], msglen);
+ transmit_pos += msglen;
+}
+
// Check if there is data to be sent from PRU1 to the host
static void
check_can_send(void)
@@ -42,8 +68,7 @@ check_can_send(void)
if (!count)
// Queue empty
break;
- command_add_frame(s->data, count);
- pru_rpmsg_send(&transport, CHAN_PORT, transport_dst, &s->data, count);
+ build_message(s->data, count);
writel(&s->count, 0);
SHARED_MEM->send_pop_pos = (
(send_pop_pos + 1) % ARRAY_SIZE(SHARED_MEM->send_data));
@@ -139,8 +164,10 @@ process_io(void)
CT_INTC.SECR0 = (1 << KICK_PRU0_FROM_ARM_EVENT) | (1 << KICK_PRU0_EVENT);
check_can_send();
int can_sleep = check_can_read();
- if (can_sleep)
+ if (can_sleep) {
+ flush_messages();
asm("slp 1");
+ }
}
}
@@ -182,8 +209,7 @@ void
console_sendf(const struct command_encoder *ce, va_list args)
{
char buf[MESSAGE_MIN];
- command_add_frame(buf, sizeof(buf));
- pru_rpmsg_send(&transport, CHAN_PORT, transport_dst, buf, sizeof(buf));
+ build_message(buf, sizeof(buf));
}