SpiNNFrontEndCommon 7.1.1
Common support code for user-facing front end systems.
Loading...
Searching...
No Matches
recording.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2015 The University of Manchester
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
23#include <recording.h>
24#include <simulation.h>
25#include <buffered_eieio_defs.h>
26#include <sark.h>
27#include <circular_buffer.h>
28#include <spin1_api_params.h>
29#include <debug.h>
30#include <wfi.h>
31
32//---------------------------------------
33// Structures
34//---------------------------------------
38typedef struct recording_channel_t {
39 uint8_t *start;
40 uint8_t *end;
41 uint8_t *write;
42 uint32_t space: 31;
43 uint32_t missing: 1;
45
47typedef struct recording_region_t {
49 uint32_t space;
51 uint32_t size:31;
53 uint32_t missing: 1;
55 uint8_t *data;
57
66
67//---------------------------------------
68// Globals
69//---------------------------------------
70
73
76
77//---------------------------------------
81static inline bool has_been_initialised(recording_channel_t *rec) {
82 return rec->start != NULL;
83}
84
85//----------------------------------------
88static inline void close_channel(recording_channel_t *rec) {
89 rec->start = NULL;
90}
91
96static inline void copy_data(
97 void *restrict target, const void *source, uint n_words) {
98 uint *to = target;
99 const uint *from = source;
100 while (n_words-- > 0) {
101 *to++ = *from++;
102 }
103}
104
105bool recording_record(uint8_t channel, void *data, uint32_t size_bytes) {
106 recording_channel_t *rec = &channels[channel];
107 if (has_been_initialised(rec)) {
108
109 if (rec->space >= size_bytes) {
110 if ((((int) data & 0x3) != 0) || ((size_bytes & 0x3) != 0)) {
111 spin1_memcpy(rec->write, data, size_bytes);
112 } else {
113 copy_data(rec->write, data, size_bytes >> 2);
114 }
115 rec->space -= size_bytes;
116 rec->write += size_bytes;
117 return true;
118 }
119
120 if (!rec->missing) {
121 log_warning("WARNING: recording channel %u out of space", channel);
122 rec->missing = 1;
123 }
124 }
125
126 return false;
127}
128
129__attribute__((noreturn))
133void recording_bad_offset(void *data, uint32_t size) {
134 log_error("DMA transfer of non-word data quantity in recording! "
135 "(data=0x%08x, size=0x%x)", data, size);
137}
138
140 log_debug("Finalising recording channels");
141
142 // Loop through channels
143 for (uint32_t channel = 0; channel < regions->n_regions; channel++) {
144 recording_channel_t *rec = &channels[channel];
145 // If this channel's in use, copy things back to SDRAM
146 if (has_been_initialised(rec)) {
147 recording_region_t *reg = &regions->regions[channel];
148 log_info("Recording channel %u, start=0x%08x, end=0x%08x, write=0x%08x, space=%u",
149 channel, rec->start, rec->end, rec->write, rec->space);
150 reg->size = rec->write - rec->start;
151 reg->missing = rec->missing;
152 if (rec->missing) {
153 log_info("Recording channel %u - has missing data", channel);
154 }
155 log_info("Recording channel %u wrote %u bytes", channel, reg->size);
156 close_channel(rec);
157 }
158 }
159}
160
162 void **recording_data_address, uint32_t *recording_flags) {
163 // Get the parameters
164 regions = *recording_data_address;
165
166 // Update the pointer to after the data
167 uint32_t n_regions = regions->n_regions;
168 *recording_data_address = &regions->regions[n_regions];
169
170 // Set up the space for holding recording pointers and sizes
171 channels = spin1_malloc(n_regions * sizeof(recording_channel_t));
172 if (channels == NULL) {
173 log_error("Not enough space to allocate recording channels");
174 return false;
175 }
176
177 // Set up the recording flags
178 if (recording_flags != NULL) {
179 *recording_flags = 0;
180 }
181
182 /* Reserve the actual recording regions.
183 *
184 */
185 for (uint32_t i = 0; i < n_regions; i++) {
186 recording_region_t *region = &regions->regions[i];
187 uint32_t space = region->space;
188 if (space > 0) {
189 region->data = sark_xalloc(
190 sv->sdram_heap, space, 0,
191 ALLOC_LOCK + ALLOC_ID + (sark_vec->app_id << 8));
192 if (region->data == NULL) {
193 log_error("Could not allocate recording region %u of %u bytes,"
194 " available was %u bytes", i, space,
195 sark_heap_max(sv->sdram_heap, 0));
196 return false;
197 }
198 log_info("Allocated %u bytes for recording channel %u at 0x%08x",
199 space, i, region->data);
200 if (recording_flags != NULL) {
201 *recording_flags = (*recording_flags | (1 << i));
202 }
203 }
204 }
205
206 // Set up the channels and write the initial state data
208
209 return true;
210}
211
212void recording_reset(void) {
213 // Go through the regions and set up the data
214 for (uint32_t i = 0; i < regions->n_regions; i++) {
215 recording_region_t *region = &regions->regions[i];
216 recording_channel_t *channel = &channels[i];
217 uint32_t space = region->space;
218 if (space > 0) {
219 uint8_t *data = region->data;
220 channel->start = data;
221 channel->end = data + space;
222 channel->space = space;
223 channel->write = data;
224 channel->missing = 0;
225
226 log_info("Recording channel %u configured to use %u byte memory block"
227 " starting at 0x%08x", i, channel->space, channel->start);
228 } else {
229 close_channel(channel);
230 log_info("Recording channel %u left uninitialised", i);
231 }
232 }
233}
Definitions for the streaming-over-EIEIO buffering protocol.
static uint32_t recording_flags
General recording flags. (Unused by this code.)
static uint32_t data[ITEMS_PER_DATA_PACKET]
SpiNNaker debug header file.
void log_error(const char *message,...)
This function logs errors. Errors usually indicate a serious fault in the program,...
void log_warning(const char *message,...)
This function logs warnings.
void log_debug(const char *message,...)
This function logs debugging messages. This level of message is normally not printed except when the ...
void log_info(const char *message,...)
This function logs informational messages. This is the lowest level of message normally printed.
uint32_t space
The size of the region to record into.
Definition recording.c:49
uint8_t * write
Where to write to next.
Definition recording.c:41
recording_region_t regions[]
Item for each region.
Definition recording.c:63
uint32_t size
The size of the region after recording.
Definition recording.c:51
static bool has_been_initialised(recording_channel_t *rec)
checks that a channel has been initialised
Definition recording.c:81
bool recording_initialize(void **recording_data_address, uint32_t *recording_flags)
initialises the recording of data
Definition recording.c:161
static recording_regions_t * regions
The parameters of the recording.
Definition recording.c:75
static recording_channel_t * channels
Array containing all possible channels.
Definition recording.c:72
uint32_t missing
Flag indicating if recording missed data.
Definition recording.c:43
void recording_finalise(void)
Finishes recording - should only be called if recording_flags is not 0.
Definition recording.c:139
uint8_t * data
Pointer to the recorded data.
Definition recording.c:55
uint32_t space
The space remaining in the channel.
Definition recording.c:42
static void close_channel(recording_channel_t *rec)
closes a channel
Definition recording.c:88
static void copy_data(void *restrict target, const void *source, uint n_words)
copy data in word-size chunks
Definition recording.c:96
uint32_t missing
Flag indicating if any data is missing.
Definition recording.c:53
uint8_t * end
One byte past the end of the buffer.
Definition recording.c:40
uint32_t n_regions
The number of recording regions.
Definition recording.c:61
bool recording_record(uint8_t channel, void *data, uint32_t size_bytes)
records some data into a specific recording channel.
Definition recording.c:105
void recording_reset(void)
resets recording to the state just after initialisation
Definition recording.c:212
void recording_bad_offset(void *data, uint32_t size)
Stop the program because of a bad recording request.
Definition recording.c:133
uint8_t * start
The first byte of the buffer.
Definition recording.c:39
Structure that defines a channel in memory.
Definition recording.c:38
Data for an individual region.
Definition recording.c:47
header of general structure describing all recordings
Definition recording.c:59
interface for recording data into "channels" on the SDRAM in a standard way, and storing buffers to b...
#define ALLOC_LOCK
void * sark_xalloc(heap_t *heap, uint size, uint tag, uint flag)
RTE_SWERR
#define ALLOC_ID
uint sark_heap_max(heap_t *heap, uint flag)
void rt_error(uint code,...)
Simulation Functions Header File.
#define NULL
void spin1_memcpy(void *dst, void const *src, uint len)
unsigned int uint
Wait for interrupt.