SpiNNFrontEndCommon 7.1.1
Common support code for user-facing front end systems.
Loading...
Searching...
No Matches
data_speed_up_packet_gatherer.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2017 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// imports
26#include <spin1_api.h>
27#include <common-typedefs.h>
28#include "common.h"
29#include <data_specification.h>
30#include <simulation.h>
31#include <debug.h>
32#include <bit_field.h>
33
34//-----------------------------------------------------------------------------
35// MAGIC NUMBERS
36//-----------------------------------------------------------------------------
37
39#define SDP_TIMEOUT 100
40
43#define MESSAGE_DELAY_TIME_WHEN_FAIL 1
44
46#define FIRST_SEQ_NUM 0
47
49#define MAX_CHIP_INDEX 8
50
66
72
74#define SDRAM_VS_DTCM_THRESHOLD 40000
75
77enum {
80
83
86
89};
90
92#define ALL_MISSING_FLAG 0xFFFFFFFE
93
95#define ROUTER_TIMEOUT_MASK 0xFF
96
98enum {
108
110enum {
120};
121
122//-----------------------------------------------------------------------------
123// TYPES AND GLOBALS
124//-----------------------------------------------------------------------------
125
135
143
153
156
159
162
165
168
171
173static uint32_t max_seq_num = 0xFFFFFFFF;
174
177
180
184
187
190
192enum {
200
218
220enum {
222 SDP = 0
224
232
234static uint chip_x = 0xFFFFFFF; // Not a legal chip coordinate
235
237static uint chip_y = 0xFFFFFFF; // Not a legal chip coordinate
238
241
244
248static bool alloc_in_sdram = false;
249
252
255
258
269
277
290
302
305
308
309//-----------------------------------------------------------------------------
310// FUNCTIONS
311//-----------------------------------------------------------------------------
312
316// Get pointer to 1st virtual processor info struct in SRAM
318
319 // Get the address this core's DTCM data starts at from the user data
320 // member of the structure associated with this virtual processor
322}
323
325static inline void send_sdp_message(void) {
326 log_debug("sending message of length %u", my_msg.length);
327 while (!spin1_send_sdp_msg((sdp_msg_t *) &my_msg, SDP_TIMEOUT)) {
328 log_debug("failed to send SDP message");
329 spin1_delay_us(MESSAGE_DELAY_TIME_WHEN_FAIL);
330 }
333}
334
338static inline void send_mc_message(key_offsets command, uint payload) {
340 while (spin1_send_mc_packet(key, payload, WITH_PAYLOAD) == 0) {
341 spin1_delay_us(MESSAGE_DELAY_TIME_WHEN_FAIL);
342 }
343}
344
353static inline void sanity_check_write(uint write_address, uint n_elements) {
354 // determine size of data to send
355 log_debug("Writing %u elements to 0x%08x", n_elements, write_address);
356
357 uint end_ptr = write_address + n_elements * sizeof(uint);
360 log_error("bad write range 0x%08x-0x%08x", write_address, end_ptr);
362 }
363}
364
375 const uint *data, uint n_elements, bool set_write_address,
377 // send mc message with SDRAM location to correct chip
378 if (set_write_address) {
380 }
381
382 // send mc messages containing rest of sdp data
383 for (uint data_index = 0; data_index < n_elements; data_index++) {
384 log_debug("data is %d", data[data_index]);
386 }
387}
388
396 log_error("Allocating seq num store when already one exists at 0x%08x",
399 }
400 size_of_bitfield = get_bit_field_size(max_seq + 1);
401 if (max_seq_num != max_seq) {
403 alloc_in_sdram = false;
405 (received_seq_nums_store = spin1_malloc(
406 size_of_bitfield * sizeof(uint32_t))))) {
408 sv->sdram_heap, size_of_bitfield * sizeof(uint32_t), 0,
409 ALLOC_LOCK | ALLOC_ID | (sark_vec->app_id << 8));
411 log_error(
412 "Failed to allocate %u bytes for missing seq num store",
413 size_of_bitfield * sizeof(uint32_t));
415 }
416 alloc_in_sdram = true;
417 }
418 }
419 log_debug("clearing bit field");
421}
422
424static inline void free_sequence_number_bitfield(void) {
426 log_error("Freeing a non-existent seq num store");
428 }
429 if (alloc_in_sdram) {
430 sark_xfree(sv->sdram_heap, received_seq_nums_store,
431 ALLOC_LOCK | ALLOC_ID | (sark_vec->app_id << 8));
432 } else {
434 }
436 max_seq_num = 0xFFFFFFFF;
437}
438
446
449static inline void set_message_length(const void *end) {
450 my_msg.length = ((const uint8_t *) end) - &my_msg.flags;
452 log_error("bad message length %u", my_msg.length);
453 }
454}
455
461 // if received when doing a stream. ignore as either clone or oddness
463 log_debug(
464 "received location message with transaction id %d when "
465 "already processing stream with transaction id %d",
466 receive_data_cmd->transaction_id, transaction_id);
467 return;
468 }
469
470 // updater transaction id if it hits the cap
471 if (((transaction_id + 1) & TRANSACTION_CAP) == 0) {
472 transaction_id = 0;
474 }
475
476 // if transaction id is not as expected. ignore it as its from the past.
477 // and worthless
478 if (receive_data_cmd->transaction_id != transaction_id + 1) {
479 log_debug(
480 "received location message with unexpected "
481 "transaction id %d; mine is %d",
482 receive_data_cmd->transaction_id, transaction_id + 1);
483 return;
484 }
485
486 //extract transaction id and update
487 transaction_id = receive_data_cmd->transaction_id;
489
490 // track changes
492
493 // update sdram and tracker as now have the sdram and size
494 chip_x = receive_data_cmd->chip_x;
495 chip_y = receive_data_cmd->chip_y;
496
497 if (prev_x != chip_x || prev_y != chip_y) {
498 log_debug(
499 "Changed stream target chip to %d,%d for transaction id %d",
501 }
502
503 log_debug("Writing %u packets to 0x%08x for transaction id %d",
504 receive_data_cmd->max_seq_num + 1, receive_data_cmd->address,
506
507 // store where the sdram started, for out-of-order UDP packets.
509
510 // allocate location for holding the seq numbers
515
516 // set start of last seq number
518}
519
521static void send_finished_response(void) {
522 // send boundary key, so that monitor knows everything in the previous
523 // stream is done
527 my_msg.length = sizeof(sdp_hdr_t) +
528 sizeof(int) * SEND_MISSING_SEQ_HEADER_WORDS;
530 log_debug("Sent end flag");
531}
532
537 const sdp_msg_pure_data *msg) {
538 // verify in right state
542 log_debug(
543 "received missing seq numbers before a location with a "
544 "transaction id which is stale.");
545 return;
546 }
549 log_debug("received tell request when already sent finish. resending");
551 return;
552 }
553
556
557 // check that missing seq transmission is actually needed, or
558 // have we finished
563 return;
564 }
565
566 // sending missing seq nums
567 log_debug("Looking for %d missing packets",
568 ((int) max_seq_num + 1) - ((int) total_received_seq_nums));
570 const uint *data_start = payload->data;
571 const uint *end_of_buffer = (uint *) (payload + 1);
572 uint *data_ptr = payload->data;
573
574 // handle case of all missing
575 if (total_received_seq_nums == 0) {
576 // send response
577 data_ptr = payload->data;
581 return;
582 }
583
584 // handle a random number of missing seqs
585 for (uint bit = 0; bit <= max_seq_num; bit++) {
586 if (bit_field_test(received_seq_nums_store, bit)) {
587 continue;
588 }
589
590 *(data_ptr++) = bit;
591 if (data_ptr >= end_of_buffer) {
594 data_ptr = payload->data;
595 }
596 }
597
598 // send final message if required
599 if (data_ptr > data_start) {
602 }
603}
604
610 const sdp_msg_pure_data *msg, const uint *data_start) {
611 // Offset in bytes from the start of the SDP message to where the data is
612 uint offset = ((uint8_t *) data_start) - &msg->flags;
613 return (msg->length - offset) / sizeof(uint);
614}
615
620static inline void copy_data(
621 void *restrict target, const void *source, uint n_words) {
622 uint *to = target;
623 const uint *from = source;
624 while (n_words-- > 0) {
625 *to++ = *from++;
626 }
627}
628
632static inline void receive_seq_data(const sdp_msg_pure_data *msg) {
633 // cast to the receive seq data
636
637 // check for bad states
639 log_debug("received data before being given a location");
640 return;
641 }
642 if (receive_data_cmd->transaction_id != transaction_id) {
643 log_debug("received data from a different transaction");
644 return;
645 }
646
647 // all good, process data
648 uint seq = receive_data_cmd->seq_num;
649 log_debug("Sequence data, seq:%u", seq);
650 if (seq > max_seq_num) {
651 log_error("Bad sequence number %u when max is %u!", seq, max_seq_num);
652 return;
653 }
654
656 bool send_sdram_address = (last_seen_seq_num != seq - 1);
657
658 if (!bit_field_test(received_seq_nums_store, seq)) {
659 bit_field_set(received_seq_nums_store, seq);
661 }
662 last_seen_seq_num = seq;
663
664 uint n_elements = n_elements_in_msg(msg, receive_data_cmd->data);
665 log_debug("n elements is %d", n_elements);
667 if (chip_x == 0 && chip_y == 0) {
668 // directly write the data to where it belongs
669 for (uint data_index = 0; data_index < n_elements; data_index++) {
670 log_debug("data is %x", receive_data_cmd->data[data_index]);
671 }
672 copy_data(
674 n_elements);
675 } else {
676 // transmit data to chip; the data lasts to the end of the message
678 receive_data_cmd->data, n_elements,
680 }
681}
682
686 uint command = msg->data[COMMAND_ID];
689
690 // check for separate commands
691 switch (command) {
693 // translate elements to variables
695 break;
697 receive_seq_data(msg);
698 break;
700 log_debug("Checking for missing");
702 break;
703 default:
704 log_error("Failed to recognise command id %u", command);
705 }
706}
707
712static void send_timeout(sdp_msg_t* msg, uint32_t key) {
713 if (msg->arg1 > ROUTER_TIMEOUT_MASK) {
714 msg->cmd_rc = RC_ARG;
715 return;
716 }
717 while (spin1_send_mc_packet(key, msg->arg1, WITH_PAYLOAD) == 0) {
718 spin1_delay_us(MESSAGE_DELAY_TIME_WHEN_FAIL);
719 }
720 msg->cmd_rc = RC_OK;
721}
722
726static void send_clear_message(sdp_msg_t* msg) {
727 while (spin1_send_mc_packet(
729 spin1_delay_us(MESSAGE_DELAY_TIME_WHEN_FAIL);
730 }
731 msg->cmd_rc = RC_OK;
732}
733
738 // handle the key conversion
739 switch (msg->cmd_rc) {
742 log_debug("sent reinjection timeout mc");
743 break;
746 log_debug("sent reinjection emergency timeout mc");
747 break;
748 case CMD_DPRI_CLEAR:
750 log_debug("sent reinjection clear mc");
751 break;
752 default:
753 // If we are here, the command was not recognised, so fail
754 // (ARG as the command is an argument)
755 log_error(
756 "ignoring message as don't know what to do with it when "
757 "command id is %d", msg->cmd_rc);
758 return;
759 }
760
761 // set message to correct format
763 reflect_sdp_message(msg, 0);
764
765 while (!spin1_send_sdp_msg(msg, SDP_TIMEOUT)) {
766 log_debug("failed to send SDP message");
767 spin1_delay_us(MESSAGE_DELAY_TIME_WHEN_FAIL);
768 }
769}
770
775 switch (port) {
776 case REINJECTION_PORT:
778 break;
781 break;
782 default:
783 log_info("unexpected port %d\n", port);
784 }
785 // free the message to stop overload
786 spin1_msg_free((sdp_msg_t *) mailbox);
787}
788
790static void send_data(void) {
792 my_msg.length = sizeof(sdp_hdr_t) + position_in_store * sizeof(uint);
793
794 if (seq_num > max_seq_num) {
795 log_error("Got a funky seq num in sending; max is %d, received %d",
797 }
798
800
801 seq_num++;
805}
806
811static void receive_data(uint key, uint payload) {
812 if (key == new_sequence_key) {
814 log_info("sending surplus data from new seq setting");
815 send_data();
816 }
817
818 log_info("new seq num to set is %d", payload);
819 data[SEQ_NUM_LOC] = payload;
821 seq_num = payload;
823
824 if (payload > max_seq_num) {
825 log_error("Got a funky seq num; max is %d, received %d",
826 max_seq_num, payload);
827 }
828 } else {
829 data[position_in_store] = payload;
831
832 if (key == first_data_key) {
833 log_debug("received new stream with max %d", payload);
837 max_seq_num = payload;
838 }
839
840 if (key == transaction_id_key) {
841 data_out_transaction_id = payload;
846 }
847
848 if (key == end_flag_key) {
849 // set end flag bit in seq num
850 data[SEQ_NUM_LOC] |= 1 << 31;
851
852 // adjust size as last payload not counted
854
855 send_data();
856 log_debug("sent all data");
858 send_data();
859 }
860 }
861}
862
864static void initialise(void) {
865 // Get the address this core's DTCM data starts at from SRAM
868
869 // Read the header
871 log_error("Failed to read the data spec header");
873 }
874
875 log_info("Initialising data out");
876
877 // read keys from sdram
880 new_sequence_key = config->new_seq_key;
881 first_data_key = config->first_data_key;
882 transaction_id_key = config->transaction_id_key;
883 end_flag_key = config->end_flag_key;
884 basic_data_key = config->basic_data_key;
885
886 log_info("new seq key = %d, first data key = %d, transaction id key = %d, "
887 "end flag key = %d, basic_data_key = %d",
890
891 log_info("the tag id being used is %d", config->tag_id);
892 my_msg.tag = config->tag_id; // IPTag 1
893 my_msg.dest_port = PORT_ETH; // Ethernet
894 my_msg.dest_addr = sv->eth_addr; // Nearest Ethernet chip
895
896 // fill in SDP source & flag fields
897 my_msg.flags = 0x07;
898 my_msg.srce_port = 3;
899 my_msg.srce_addr = sv->p2p_addr;
900
901 // Set up provenance
903
905
906 log_info("Initialising data in");
907
908 // Get the address this core's DTCM data starts at from SRAM
911
912 // sort out bitfield for reinjection ack tracking
913 uint32_t n_extra_monitors = chip_key_map->n_extra_monitors;
914
915 // read in the keys for mc packets for data in
916 for (uint i = 0; i < n_extra_monitors; i++) {
917 uint x_coord = chip_key_map->chip_to_key[i].x_coord;
918 uint y_coord = chip_key_map->chip_to_key[i].y_coord;
919 uint base_key = chip_key_map->chip_to_key[i].base_key;
920 data_in_mc_key_map[x_coord][y_coord] = base_key;
921 }
922
923 // set up the reinjection multicast API
924 initialise_reinjection_mc_api(chip_key_map->reinjector_base_key);
925
926 // set sdp callback
928
929 // load user 1 in case this is a consecutive load
931}
932
937void c_main(void) {
938 log_info("Configuring packet gatherer");
939
940 // initialise the code
941 initialise();
942
943 // start execution
944 log_info("Starting");
945
947}
uint32_t * bit_field_t
Command structure, describing a SpiNNaker multicast packet to be sent at some point.
Data type definitions for SpiNNaker Neuron-modelling.
uint32_t * address_t
A generic pointer to a word.
Common definitions for the non-SCAMP system binaries.
static void initialise_reinjection_mc_api(uint32_t base_mc_key)
sets up the multicast keys for the reinjection multicast API
Definition common.h:73
static uint reinject_clear_mc_key
the multicast key used for clear reinjector queue to all extra monitors
Definition common.h:69
@ CMD_DPRI_SET_ROUTER_EMERGENCY_TIMEOUT
Set the router's wait2 timeout.
Definition common.h:32
@ CMD_DPRI_SET_ROUTER_TIMEOUT
Set the router's wait1 timeout.
Definition common.h:30
@ CMD_DPRI_CLEAR
Clear the reinjection queue.
Definition common.h:42
static uint reinject_emergency_timeout_mc_key
the multicast key used for emergency timeouts to all extra monitors
Definition common.h:66
static uint reinject_timeout_mc_key
the multicast key used for basic timeouts to all extra monitors
Definition common.h:63
#define SDP_REPLY_HEADER_LEN
Number of bytes in an SDP header.
Definition common.h:82
#define TRANSACTION_CAP
Flag for cap on transaction id.
Definition common.h:85
static void reflect_sdp_message(sdp_msg_t *msg, uint body_length)
Updates an SDP message so its content (a response to the message) goes back to where the message came...
Definition common.h:91
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.
uint transaction_id
The transaction that the message is taking part in.
@ DATA_IN_NORMAL_PACKET_WORDS
size of data stored in packet with command and seq
@ ITEMS_PER_MISSING_PACKET
size of payload for a packet describing the batch of missing inbound seqs
uint command
The meaning of the message.
static void send_finished_response(void)
sends the finished request
#define SDRAM_VS_DTCM_THRESHOLD
threshold for SDRAM vs DTCM when allocating received_seq_nums_store
static void receive_data(uint key, uint payload)
Handles receipt of a fixed route packet with payload from the SpiNNaker network.
static void send_data(void)
sends data to the host via SDP (using my_msg)
static uint32_t basic_data_key
the key that marks an ordinary word within a data out stream
const uint first_data_key
The key used to indicate the first word of a stream.
ushort chip_y
Board-local y coordinate of chip to do write on.
@ PROVENANCE_REGION
Index of provenance region.
@ CONFIG
Index of general configuration region.
@ CHIP_TO_KEY
Index of chip-to-key mapping table.
uint data[ITEMS_PER_MISSING_PACKET]
The payload data of the message.
static void process_missing_seq_nums_and_request_retransmission(const sdp_msg_pure_data *msg)
searches through received sequence numbers and transmits missing ones back to host for retransmission
const uint transaction_id_key
The key used to indicate a transaction ID.
static void send_sdp_message(void)
sends the SDP message built in the my_msg global
static sdp_msg_pure_data my_msg
SDP message holder for transmissions.
static uint32_t position_in_store
index into data
const uint end_flag_key
The key used to indicate a stream end.
@ WRITE_ADDR_KEY_OFFSET
Payload contains a write address.
@ BOUNDARY_KEY_OFFSET
Write stream complete. Payload irrelevant.
@ DATA_KEY_OFFSET
Payload contains a data word.
const uint new_seq_key
The key used to indicate a new sequence/stream.
#define ALL_MISSING_FLAG
flag when all seq numbers are missing
static uint32_t transaction_id_key
the key that provides a new data out transaction ID
static dsupg_provenance_t prov
The DTCM copy of the provenance.
static void process_address_data(const receive_data_to_location_msg_t *receive_data_cmd)
handles reading the address, chips and max packets from a SDP message (command: SDP_SEND_DATA_TO_LOCA...
const uint32_t reinjector_base_key
The base key for reinjection control messages.
static bit_field_t received_seq_nums_store
Records what sequence numbers we have received from host during Data In.
static void receive_seq_data(const sdp_msg_pure_data *msg)
Handles receipt and parsing of a message full of sequence numbers that need to be retransmitted (comm...
#define SDP_TIMEOUT
timeout used in sending SDP messages
uint command
The meaning of the message.
static void free_sequence_number_bitfield(void)
Frees the allocated sequence number store.
uint32_t n_sdp_recvd
The number of SDP messages received (excluding those for SARK)
uint seq_num
The sequence number of this message.
static void sanity_check_write(uint write_address, uint n_elements)
Sanity checking for writes, ensuring that they're to the buffered SDRAM range.
static uint32_t first_data_key
the key that says this is the first item of data in a data out stream
uint command
The meaning of the message.
static uint32_t data[ITEMS_PER_DATA_PACKET]
uint32_t x_coord
Board local x coordinate of extra monitor.
static uint size_of_bitfield
The size of the bitfield in received_seq_nums_store.
static void create_sequence_number_bitfield(uint max_seq)
creates a store for sequence numbers in a memory store.
static void reinjection_sdp_command(sdp_msg_t *msg)
handles the commands for the reinjector code.
functionality_to_port_num_map
values for port numbers this core will respond to
@ REINJECTION_PORT
Reinjection control messages.
@ DATA_SPEED_UP_IN_PORT
Data Speed Up Inbound messages.
static void data_in_receive_sdp_data(const sdp_msg_pure_data *msg)
processes SDP messages for the Data In protocol
uint transaction_id
The transaction associated with the message.
static bool alloc_in_sdram
Whether received_seq_nums_store was allocated in SDRAM.
uint max_seq_num
Maximum sequence number of data stream.
static void receive_sdp_message(uint mailbox, uint port)
processes SDP messages
static void send_timeout(sdp_msg_t *msg, uint32_t key)
sends the basic timeout command via multicast to the extra monitors
static void copy_data(void *restrict target, const void *source, uint n_words)
because spin1_memcpy() is stupid, especially for access to SDRAM
#define ROUTER_TIMEOUT_MASK
mask needed by router timeout
static uint32_t transaction_id
The Data In transaction ID. Used to distinguish streams of packets.
static void send_mc_message(key_offsets command, uint payload)
sends a multicast (with payload) message to the current target chip
static uint32_t seq_num
default seq num
static dsupg_provenance_t * sdram_prov
The SDRAM copy of the provenance.
address_t address
Where the stream will be writing to in memory.
static uint total_received_seq_nums
Count of received sequence numbers.
void c_main(void)
This function is called at application start-up.
static uint32_t end_flag_key
the key that marks the end of a data out stream
#define MESSAGE_DELAY_TIME_WHEN_FAIL
the time to wait before trying again to send a message (MC, SDP) in microseconds
static uint start_sdram_address
Where the current stream of data started in SDRAM.
static uint data_in_mc_key_map[MAX_CHIP_INDEX][MAX_CHIP_INDEX]
How to find which key to use to talk to which chip on this board.
static uint32_t max_seq_num
maximum sequence number
uint transaction_id
The transaction that the message is taking part in.
uint32_t base_key
Base key to use for talking to that chip.
const uint tag_id
The ID of the IPtag to send the SDP packets out to host on.
@ SDP
SDP receive priority standard (high)
@ MC_PACKET
Multicast packet receive uses FIQ.
static uint32_t data_out_transaction_id
The Data Out transaction ID. Used to distinguish streams of packets.
const struct chip_key_data_t chip_to_key[]
The configuration data for routing messages to specific extra monitors.
@ COMMAND_ID
location of command IDs in SDP message
@ SEQ_NUM_LOC
location of where the seq num is in the packet
@ TRANSACTION_ID
location of the transaction id in the packet
@ START_OF_DATA
location of the start of raw data in the packet
uint32_t y_coord
Board local y coordinate of extra monitor.
ushort chip_x
Board-local x coordinate of chip to do write on.
@ SEND_DATA_LOCATION_HEADER_WORDS
offset with command, transaction id, address in bytes, [x, y], max seq,
@ SEND_SEQ_DATA_HEADER_WORDS
offset with just command transaction id and seq in bytes
@ SEND_MISSING_SEQ_HEADER_WORDS
offset with just command, transaction id
@ ABSOLUTE_MAX_SIZE_OF_SDP_IN_BYTES
absolute maximum size of a SDP message
static void send_clear_message(sdp_msg_t *msg)
sends the clear message to all extra monitors on this board
static uint n_elements_in_msg(const sdp_msg_pure_data *msg, const uint *data_start)
Calculates the number of words of data in an SDP message.
uint data[]
The payload of real data.
static uint calculate_sdram_address_from_seq_num(uint seq_num)
calculates the new sdram location for a given seq num
const uint32_t n_extra_monitors
The number of extra monitors that we can talk to.
static void publish_transaction_id_to_user_1(int transaction_id)
Writes the updated transaction ID to the user1.
sdp_port_commands
SDP port commands relating to the Data In protocol.
@ SDP_SEND_SEQ_DATA_CMD
Data In: Received message contains data to write.
@ SDP_SEND_MISSING_SEQ_DATA_IN_CMD
Data In: Sent message contains missing sequence numbers.
@ SDP_TELL_MISSING_BACK_TO_HOST
Data In: Received message asks for missing sequence numbers.
@ SDP_SEND_FINISHED_DATA_IN_CMD
Data In: Sent message indicates that everything has been received.
@ SDP_SEND_DATA_TO_LOCATION_CMD
Data In: Received message describes where to send data.
static void set_message_length(const void *end)
Sets the length of the outbound SDP message in my_msg.
#define MAX_CHIP_INDEX
max index needed to cover the chips in either direction on a spinn-5 board
const uint basic_data_key
The key used to indicate a general data item in a stream.
static uint32_t new_sequence_key
the key that causes data out sequence number to be processed
#define FIRST_SEQ_NUM
first sequence number to use and reset to
static void initialise(void)
Sets up the application.
static uint last_seen_seq_num
The most recently seen sequence number.
static void process_sdp_message_into_mc_messages(const uint *data, uint n_elements, bool set_write_address, uint write_address)
sends multicast messages accordingly for an SDP message
static uint chip_y
Board-relative y-coordinate of current chip being written to.
static uint chip_x
Board-relative x-coordinate of current chip being written to.
uint32_t n_in_streams
The number of input streams.
uint32_t n_out_streams
The number of output streams (technically, output transactions)
uint32_t n_sdp_sent
The number of SDP messages sent.
The layout of the Data In configuration region.
The layout of the Data Out configuration region.
The structure of the provenance region FIXME.
meaning of payload in first data in SDP packet
meaning of payload in subsequent data in SDP packets
SDP packet payload definition.
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.
static uint32_t packets_sent
The number of packets sent so far this timestamp.
The configuration parameters for the application.
#define PORT_ETH
#define SV_VCPU
#define ALLOC_LOCK
ushort cmd_rc
void * sark_xalloc(heap_t *heap, uint size, uint tag, uint flag)
RTE_SWERR
void sark_free(void *ptr)
RC_ARG
RC_OK
#define ALLOC_ID
SYNC_NOWAIT
ushort length
void rt_error(uint code,...)
void sark_xfree(heap_t *heap, void *ptr, uint flag)
uint8_t flags
SDP flag byte; first byte actually sent.
Definition sdp_no_scp.h:37
uint8_t srce_port
SDP source port/CPU.
Definition sdp_no_scp.h:40
uint16_t length
Length (measured from flags field start)
Definition sdp_no_scp.h:33
uint8_t dest_port
SDP destination port/CPU.
Definition sdp_no_scp.h:39
uint16_t dest_addr
SDP destination address.
Definition sdp_no_scp.h:41
uint32_t data[ITEMS_PER_DATA_PACKET]
User data (272 bytes when no SCP header)
Definition sdp_no_scp.h:45
uint8_t tag
SDP IPtag.
Definition sdp_no_scp.h:38
uint16_t srce_addr
SDP source address.
Definition sdp_no_scp.h:42
@ ITEMS_PER_DATA_PACKET
How many multicast packets are to be received per SDP packet.
Definition sdp_no_scp.h:25
An SDP message with purely data, no SCP header.
Definition sdp_no_scp.h:31
Simulation Functions Header File.
FRPL_PACKET_RECEIVED
SDP_PACKET_RX
#define NULL
WITH_PAYLOAD
uint spin1_get_core_id(void)
uint spin1_start(sync_bool sync)
void spin1_callback_on(uint event_id, callback_t cback, int priority)
#define SDRAM_BASE_UNBUF
unsigned int uint
unsigned short ushort