SpiNNFrontEndCommon 7.3.1
Common support code for user-facing front end systems.
Loading...
Searching...
No Matches
command_sender_multicast_source.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
24
25#include <common-typedefs.h>
26#include <data_specification.h>
27#include <debug.h>
28#include <simulation.h>
29#include <stdbool.h>
30
36typedef struct command {
38 uint32_t key;
42 uint32_t payload;
45 uint32_t repeats;
47 uint32_t delay;
48} command;
49
51typedef struct timed_command {
52 uint32_t time;
55
59typedef struct command_list {
60 uint32_t size;
63
71
72// Globals
74static uint32_t time;
76static uint32_t simulation_ticks;
78static uint32_t infinite_run;
86static uint32_t n_timed_commands;
90static uint32_t n_pause_stop_commands;
92static uint32_t next_timed_command;
94static bool resume = true;
96static uint32_t n_commands_sent;
97
104
121
123typedef struct cs_provenance_t {
127
129enum {
130 FIRST_TIME = 0
131};
132
136static void transmit_command(command *command_to_send) {
137 // check for repeats
138 if (command_to_send->repeats != 0) {
139 for (uint32_t repeat_count = 0;
140 repeat_count <= command_to_send->repeats;
141 repeat_count++) {
142 if (command_to_send->has_payload) {
143 log_debug("Sending %08x, %08x at time %u with %u repeats and "
144 "%u delay",
145 command_to_send->key, command_to_send->payload, time,
146 command_to_send->repeats, command_to_send->delay);
147 spin1_send_mc_packet(
148 command_to_send->key, command_to_send->payload,
150 } else {
151 log_debug("Sending %08x at time %u with %u repeats and "
152 "%u delay",
153 command_to_send->key, time, command_to_send->repeats,
154 command_to_send->delay);
155 spin1_send_mc_packet(command_to_send->key, 0, NO_PAYLOAD);
156 }
158
159 // if the delay is 0, don't call delay
160 if (command_to_send->delay > 0) {
161 spin1_delay_us(command_to_send->delay);
162 }
163 }
164 } else {
165 if (command_to_send->has_payload) {
166 log_debug("Sending %08x, %08x at time %u",
167 command_to_send->key, command_to_send->payload, time);
168
169 //if no repeats, then just send the message
170 spin1_send_mc_packet(
171 command_to_send->key, command_to_send->payload,
173 } else {
174 log_debug("Sending %08x at time %u", command_to_send->key, time);
175 spin1_send_mc_packet(command_to_send->key, 0, NO_PAYLOAD);
176 }
178 }
179}
180
183static void run_stop_pause_commands(void) {
184 log_info("Transmit pause/stop commands");
185 for (uint32_t i = 0; i < n_pause_stop_commands; i++) {
187 }
188}
189
192static void run_start_resume_commands(void) {
193 log_info("Transmit start/resume commands");
194 for (uint32_t i = 0; i < n_start_resume_commands; i++) {
196 }
197}
198
203static bool read_scheduled_parameters(timed_command_list *sdram_timed_commands) {
204 n_timed_commands = sdram_timed_commands->size;
205 log_info("%d timed commands", n_timed_commands);
206
207 // if no data, do not read it in
208 if (n_timed_commands == 0) {
209 return true;
210 }
211
212 // Allocate the space for the scheduled_commands
213 timed_commands = spin1_malloc(n_timed_commands * sizeof(timed_command));
214
215 if (timed_commands == NULL) {
216 log_error("Could not allocate the scheduled commands");
217 return false;
218 }
219
220 spin1_memcpy(timed_commands, sdram_timed_commands->commands,
222
223 log_info("Schedule commands starts at time %u",
224 timed_commands[FIRST_TIME].time);
225 return true;
226}
227
232static bool read_start_resume_commands(command_list *sdram_commands) {
233 n_start_resume_commands = sdram_commands->size;
234 log_info("%u start/resume commands", n_start_resume_commands);
235
236 if (n_start_resume_commands == 0) {
237 return true;
238 }
239
240 // Allocate the space for the start resume
242 spin1_malloc(n_start_resume_commands * sizeof(command));
244 log_error("Could not allocate the start/resume commands");
245 return false;
246 }
247
250 return true;
251}
252
257static bool read_pause_stop_commands(command_list *sdram_commands) {
258 n_pause_stop_commands = sdram_commands->size;
259 log_info("%u pause/stop commands", n_pause_stop_commands);
260
261 if (n_pause_stop_commands == 0) {
262 return true;
263 }
264
265 // Allocate the space for the start resume
267 spin1_malloc(n_pause_stop_commands * sizeof(command));
268 if (pause_stop_commands == NULL) {
269 log_error("Could not allocate the pause/stop commands");
270 return false;
271 }
272
275 return true;
276}
277
278// Callbacks
284static void timer_callback(UNUSED uint unused0, UNUSED uint unused1) {
285 time++;
286
287 if (resume) {
288 log_info("running first start resume commands");
290 resume = false;
291 }
292
295
297
298 log_info("in pause resume mode");
299 resume = true;
300
301 // Subtract 1 from the time so this tick gets done again on the next
302 // run
303 time--;
304
306 return;
307 }
308
313 }
314}
315
318static void write_provenance(address_t address) {
319 cs_provenance_t *sdram_prov = (void *) address;
320 sdram_prov->n_commands_sent = n_commands_sent;
321}
322
326static bool initialize(uint32_t *timer_period) {
327 // Get the address this core's DTCM data starts at from SRAM
330
331 // Read the header
332 if (!data_specification_read_header(ds_regions)) {
333 return false;
334 }
335
336 // Get the timing details and set up the simulation interface
339 APPLICATION_NAME_HASH, timer_period, &simulation_ticks,
340 &infinite_run, &time, SDP, DMA)) {
341 return false;
342 }
347
348 // Read the parameters
349 bool success;
351 COMMANDS_WITH_ARBITRARY_TIMES, ds_regions));
353 COMMANDS_AT_START_RESUME, ds_regions));
355 COMMANDS_AT_STOP_PAUSE, ds_regions));
356 return success;
357}
358
360void c_main(void) {
361 // Configure system
362 uint32_t timer_period = 0;
363 if (!initialize(&timer_period)) {
364 log_error("Error in initialisation - exiting!");
366 }
367
368 // Set timer_callback
369 spin1_set_timer_tick(timer_period);
370
371 // Register callbacks
373
374 // Start the time at "-1" so that the first tick will be 0
375 time = UINT32_MAX;
377}
static bool initialize(void)
Initialises the program.
uint32_t n_commands_sent
The number of commands sent.
static bool resume
Whether we are in the state where the next run will be a start/resume.
static uint32_t n_commands_sent
The number of commands sent.
static timed_command * timed_commands
The commands to send at particular times.
static uint32_t simulation_ticks
The number of ticks to run for.
static command * start_resume_commands
The commands to run when a simulation starts or resumes after pause.
uint32_t repeats
The number of times to repeat the packet.
uint32_t time
The simulation time to send a packet.
command commands[]
The commands to send.
static uint32_t n_start_resume_commands
The number of commands to send on start/resume.
uint32_t key
The key of the packet.
callback_priorities
values for the priority for each callback
@ TIMER
Responding to timers is lowest priority, and most common.
@ DMA
Handling memory transfers is next highest.
@ SDP
Responding to network traffic is highest priority.
static bool read_scheduled_parameters(timed_command_list *sdram_timed_commands)
Copy the list of commands to run at particular times into DTCM.
uint32_t payload
The payload for the packet.
region_identifiers
region identifiers
@ PROVENANCE_REGION
Where to record provenance data. (Format: cs_provenance_t)
@ SYSTEM_REGION
Where simulation system information is stored.
static void run_start_resume_commands(void)
Sends all the commands registered for sending on simulation start or resume.
uint32_t size
The number of commands to send.
static void write_provenance(address_t address)
Write our provenance data into the provenance region.
static uint32_t n_timed_commands
The number of timed commands.
uint32_t size
The number of commands to send.
static uint32_t infinite_run
Whether the simulation is running "forever" (robotics mode).
static bool read_start_resume_commands(command_list *sdram_commands)
Copy the list of commands to run on start or resume into DTCM.
void c_main(void)
Entry point.
static uint32_t next_timed_command
The index of the next timed command to run.
static uint32_t n_pause_stop_commands
The number of commands to send on stop/pause.
static void timer_callback(uint unused0, uint unused1)
The timer tick callback. Sends those commands that are due in the current simulation state and time.
static bool read_pause_stop_commands(command_list *sdram_commands)
Copy the list of commands to run on stop or pause into DTCM.
static void run_stop_pause_commands(void)
Sends all the commands registered for sending on simulation stop or pause.
static command * pause_stop_commands
The commands to run when a simulation stops or pauses.
command command
What to send.
uint32_t delay
The time (in microseconds) to delay between sending each repeat.
static uint32_t time
The simulation timer.
static void transmit_command(command *command_to_send)
Immediately sends SpiNNaker multicast packets in response to a command.
timed_command commands[]
The commands to send, sorted in time order.
bool has_payload
Whether to send a payload with the packet.
Command structure, describing a SpiNNaker multicast packet to be sent at some point.
A collection of commands to be sent in response to an event.
A command that happens at a particular simulation time.
A collection of commands to be sent at particular simulation times.
Data type definitions for SpiNNaker Neuron-modelling.
uint32_t * address_t
A generic pointer to a word.
Data Specification region access API.
data_specification_metadata_t * data_specification_get_data_address(void)
Gets the location of the data for this core using the user0 entry of the SARK VCPU structure.
bool data_specification_read_header(data_specification_metadata_t *ds_regions)
Reads the header from the address given and checks if the parameters are of the correct values.
static void * data_specification_get_region(uint32_t region, data_specification_metadata_t *ds_regions)
Gets the address of a region.
The central structure that the DSE writes.
static dsupg_provenance_t * sdram_prov
The SDRAM copy of the provenance.
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_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.
RTE_SWERR
void rt_error(uint code,...)
Simulation Functions Header File.
void simulation_handle_pause_resume(resume_callback_t callback)
cleans up the house keeping, falls into a sync state and handles the resetting up of states as requir...
Definition simulation.c:113
void simulation_set_provenance_function(prov_callback_t provenance_function, address_t provenance_data_address)
Set an additional callback function to store extra provenance data.
Definition simulation.c:418
void simulation_set_exit_function(exit_callback_t exit_function)
Set an additional function to call before exiting the binary when running without a fixed duration of...
Definition simulation.c:425
bool simulation_is_finished(void)
determine if the simulation is finished. Will also pause the simulation for resynchronisation if requ...
Definition simulation.c:444
void simulation_ready_to_read(void)
Indicates that all data has been written and the core is going idle, so any data can now be read.
Definition simulation.c:131
void simulation_run(void)
Starts the simulation running, returning when it is complete,.
Definition simulation.c:108
bool simulation_initialise(address_t address, uint32_t expected_application_magic_number, uint32_t *timer_period, uint32_t *simulation_ticks_pointer, uint32_t *infinite_run_pointer, uint32_t *time_pointer, int sdp_packet_callback_priority, int dma_transfer_complete_priority)
initialises the simulation interface which involves:
Definition simulation.c:370
TIMER_TICK
#define NULL
void spin1_memcpy(void *dst, void const *src, uint len)
NO_PAYLOAD
WITH_PAYLOAD
void spin1_callback_on(uint event_id, callback_t cback, int priority)
unsigned int uint