-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathstream.cc
99 lines (76 loc) · 1.94 KB
/
stream.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include <stdint.h>
#include <stddef.h>
struct Message {
uint32_t id;
};
// layout of shared ddr3 memory (filled in by loader)
struct DDRLayout {
Message volatile *msgbuf;
uint16_t num_msgs;
uint16_t msg_size;
};
struct SharedVars {
// set by pru before halting
char const *abort_file;
int abort_line;
// read-pointer updated by python
uint16_t ridx;
};
far struct DDRLayout ddr __attribute__((location(0x10000))) = {};
far struct SharedVars volatile shmem __attribute__((location(0x10100))) = {};
// for easier debugging, record where in the source code we halted
__attribute__((noreturn))
void abort_at( char const *file, int line )
{
shmem.abort_file = file;
shmem.abort_line = line;
for(;;) __halt();
}
static inline void assert_at( bool cond, char const *file, int line )
{
if( ! cond )
abort_at( file, line );
}
#define abort() abort_at( __FILE__, __LINE__ )
#define assert(cond) assert_at( (cond), __FILE__, __LINE__ )
// local copy of write-pointer
static uint16_t widx = 0;
// global var for write-pointer is located right after message ringbuffer
#define ddr_msgbuf_end ( ddr.msgbuf + ddr.num_msgs )
#define ddr_widx ( *(uint16_t volatile *)ddr_msgbuf_end )
void initialize()
{
// perform sanity-checking
assert( 0x80000000 <= (uint32_t)ddr.msgbuf );
assert( ddr.msgbuf < ddr_msgbuf_end );
assert( ddr.msg_size == sizeof(Message) );
assert( ddr_widx == widx );
assert( shmem.ridx == widx );
}
static inline uint16_t next_idx( uint16_t idx )
{
if( ++idx == ddr.num_msgs )
idx = 0;
return idx;
}
void send_message( uint32_t id )
{
uint16_t next_widx = next_idx( widx );
if( next_widx == shmem.ridx ) {
// can't send message, ringbuffer is full
abort();
}
Message volatile *msg = &ddr.msgbuf[ widx ];
// fill in contents of message
msg->id = id;
// update write-pointer
ddr_widx = widx = next_widx;
}
void main() {
initialize();
uint32_t id = 0;
for(;;) {
send_message( ++id );
__delay_cycles( 10000 );
}
}