forked from gopher-motorsports/gophercan-lib
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGopherCAN_ring_buffer.c
More file actions
115 lines (89 loc) · 3.12 KB
/
GopherCAN_ring_buffer.c
File metadata and controls
115 lines (89 loc) · 3.12 KB
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*
* GopherCAN.c
*
* Created on: Oct 27, 2020
* Author: Calvin
*/
#include "GopherCAN_ring_buffer.h"
// static function prototypes
static void copy_message(CAN_MSG* source, CAN_MSG* dest);
// init_buffer
// initialize the buffer with the values passed in as parameters
void init_buffer(CAN_MSG_RING_BUFFER* buffer, CAN_MSG buffer_memory_ptr[], U8 buffer_size)
{
buffer->head = 0;
buffer->fill_level = 0;
buffer->size = buffer_size;
buffer->message_buffer = buffer_memory_ptr;
}
// remove_from_front
// will remove the first element of the ring buffer. If the buffer is empty it will do nothing
void remove_from_front(CAN_MSG_RING_BUFFER* buffer)
{
// don't do anything if the buffer is empty
if (IS_EMPTY(buffer))
{
return;
}
// move the head to the next element
buffer->head = (buffer->head + 1) % buffer->size;
// decrement the fill level
buffer->fill_level--;
}
// add_message_to_back
// This function will add message to the first open slot in the ring buffer. Note no
// error checking is done in this function, so it will need to be done somewhere else
// before calling this function
void add_message_to_back(CAN_MSG_RING_BUFFER* buffer, CAN_MSG* message)
{
CAN_MSG* buffer_message;
// set the message in the next open element in the buffer to message_to_add (by value, not by reference)
buffer_message = GET_FROM_BUFFER(buffer, buffer->fill_level);
// copy the message to the buffer memory
copy_message(message, buffer_message);
// adjust the fill_level to reflect the new message added
buffer->fill_level++;
}
// add_message_by_highest_prio
// This function will add message to the buffer based on the ID of the message. Higher
// priority messages (lower ID) will be towards the front, with lower priority
// messages (greater ID) will be towards the back. Removing from the front will get
// the highest priority message. This function assumes the buffer is not full
void add_message_by_highest_prio(CAN_MSG_RING_BUFFER* buffer, CAN_MSG* message)
{
CAN_MSG* buffer_message = GET_FROM_BUFFER(buffer, 0);
S16 c;
// start from the back of the buffer, moving each message towards the back
// by one and put the new message in the correct spot by ID. If the buffer
// was empty when the message first went through here, it will put the new
// message in position 0
buffer->fill_level++;
for (c = buffer->fill_level - 2; c >= 0; c--)
{
buffer_message = GET_FROM_BUFFER(buffer, c);
if (message->id >= buffer_message->id)
{
// we have found the correct place for the new message
buffer_message = GET_FROM_BUFFER(buffer, c + 1);
break;
}
// move this message back by 1 and try again
copy_message(buffer_message, GET_FROM_BUFFER(buffer, c + 1));
}
// put the message into the buffer at this position
copy_message(message, buffer_message);
}
// copy_message
// function to copy all of the data in source to dest by value, not by refernce
static void copy_message(CAN_MSG* source, CAN_MSG* dest)
{
U8 c;
dest->id = source->id;
dest->dlc = source->dlc;
dest->rtr_bit = source->rtr_bit;
for (c = 0; c < dest->dlc; c++)
{
dest->data[c] = source->data[c];
}
}
// End of GopherCAN_ring_buffer.c