Skip to content

Commit

Permalink
Make queue interrupt safe for 1 producer + consumer (#80)
Browse files Browse the repository at this point in the history
* Queue interrupt safe if 1 prod + cons

* CAN Parse generated updates
  • Loading branch information
LukeOxley authored Dec 29, 2023
1 parent 77d3c5c commit ad98366
Show file tree
Hide file tree
Showing 16 changed files with 119 additions and 110 deletions.
16 changes: 9 additions & 7 deletions common/daq/per_dbc.dbc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
VERSION ""


NS_ :
NS_ :
NS_DESC_
CM_
BA_DEF_
Expand Down Expand Up @@ -33,7 +33,7 @@ NS_ :

BS_:

BU_: Main_Module Torque_Vector_fpga Driveline Precharge OrionBMS torque_vector Dashboard Steering Acceleration bootloader BMS_LV BITSTREAM Charger DAQ Precharge ARDUINO TEST_NODE TEST_NODE_2 DAQ
BU_: Main_Module Torque_Vector_fpga Driveline Precharge OrionBMS torque_vector Dashboard Steering PDU Acceleration bootloader BMS_LV BITSTREAM Charger DAQ Precharge ARDUINO TEST_NODE TEST_NODE_2 DAQ


BO_ 2214598913 main_hb: 2 Main_Module
Expand Down Expand Up @@ -909,11 +909,11 @@ CM_ SG_ 2415925569 LV5_I "";
CM_ SG_ 2415925569 LV24_I "";
CM_ BO_ 2415925633 "performance metrics of MCU";
CM_ SG_ 2415925633 can_tx_fails "Number of CAN transmit failures";
CM_ SG_ 2415925633 sched_error "PSCHED Error Flags (bit #)
0 - N/A
1 - no free task
2 - FG Miss
3 - BG Miss
CM_ SG_ 2415925633 sched_error "PSCHED Error Flags (bit #)
0 - N/A
1 - no free task
2 - FG Miss
3 - BG Miss
4 - Individual FG Miss";
CM_ SG_ 2415925633 background_use "Percent of the 1ms loop time used by background tasks";
CM_ SG_ 2415925633 foreground_use "Percent of the 1ms loop time used by foreground tasks";
Expand Down Expand Up @@ -1537,3 +1537,5 @@ SIG_VALTYPE_ 2214593731 P_c : 1;
SIG_VALTYPE_ 2348810751 left_speed : 1;
SIG_VALTYPE_ 2348810751 right_speed : 1;
SIG_VALTYPE_ 2483028349 test_sig5_3 : 1;


13 changes: 7 additions & 6 deletions common/faults/fault_nodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@


//BEGIN AUTO NODE DEFS
#define NODE_MAIN_MODULE 0
#define NODE_DRIVELINE_FRONT 1
#define NODE_DASHBOARD 2
#define NODE_PRECHARGE 3
#define NODE_TV_OLD 4
#define NODE_TEST 5
#define NODE_PDU 0
#define NODE_MAIN_MODULE 1
#define NODE_DRIVELINE_FRONT 2
#define NODE_DASHBOARD 3
#define NODE_PRECHARGE 4
#define NODE_TV_OLD 5
#define NODE_TEST 6
//END AUTO NODE DEFS


Expand Down
116 changes: 53 additions & 63 deletions common/queue/queue.c
Original file line number Diff line number Diff line change
@@ -1,82 +1,72 @@
#include "queue.h"

// @funcname: qConstruct
//
// @brief: Initializes queue for specific item type
//
// @param: q: Handle for queue
// @param: size: Size of each item in queue in bytes
/**
* @brief Initializes queue for specific item type
*
* @param q Handle for queue
* @param size Size of each item in queue in bytes
*/
void qConstruct(q_handle_t* q, uint8_t size)
{
q->item_count = 0; // Initialize number of items to 0
q->size = size; // Initialize size to sizeof(struct)
q->start = q->buffer; // Set start pointer to beginning of buffer
q->current = q->buffer; // Set current pointer to beginning of buffer
q->max_items = (uint8_t) (MEM_SIZE / (float) size); // Calculate maximum number of items
q->max_items = (MEM_SIZE / (float) size); // Calculate maximum number of items
q->head = q->tail = 0;
}

// @funcname: qIsFull
//
// @brief: Returns 1 if the queue is full, 0 else
//
// @param: q: Handle for queue
//
// @return: 1 if queue is full, 0 else
/**
* @brief Returns 1 if the queue is full, 0 else
*
* @param q Handle for queue
* @return 1 if queue is full, 0 else
*/
uint8_t qIsFull(q_handle_t* q)
{
return q->item_count == q->max_items ? 1 : 0; // Return 1 if full, 0 else
uint32_t next_head = (q->head + 1) % q->max_items;
return next_head == q->tail;
}

// @funcname: qSendToBack
//
// @brief: Adds an item to the queue (enqueue)
//
// @param: q: Handle for queue
// @param: item: Item to be added to queue
//
// @return: SUCCESS if value is added, FAILURE if queue is full
success_t qSendToBack(q_handle_t* q, const void* item)
/**
* @brief Returns 1 if the queue is empty, 0 else
*
* @param q Handle for queue
* @return 1 if queue is empty, 0 else
*/
uint8_t qIsEmpty(q_handle_t* q)
{
if (q->item_count == q->max_items) // Ensure that we have a location for the item
{
return FAILURE_G; // We don't, so let the user know it failed
}

if ((q->current - q->buffer) == q->size * q->max_items) // Check if the current pointer location is at the end of the buffer
{
q->current = q->buffer; // Reset the buffer location
}

memcpy(q->current, item, q->size); // Copy item into queue at current location
q->current = q->current + q->size; // Increment pointer by number of bytes corresponding to item size
++q->item_count; // Increment number of items in queue
return q->head == q->tail;
}

/**
* @brief Adds an item to the queue (enqueue)
* @note Interrupt safe ONLY if ONE producer and consumer
*
* @param q Handle for queue
* @param item Item to be added to queue
* @return success_t SUCCESS if value is added, FAILURE if queue is full
*/
success_t qSendToBack(q_handle_t* q, const void* item)
{
uint32_t next_head = (q->head + 1) % q->max_items; // Calculate next head
if (next_head == q->tail) return FAILURE_G; // No room
volatile uint8_t* dst = q->buffer + (q->head * q->size);
for (uint32_t i = 0; i < q->size; ++i) dst[i] = ((uint8_t *)item)[i];
q->head = next_head; // Update head
return SUCCESS_G;
}

// @funcname: qReceive
//
// @brief: Removes an item to the queue (dequeue)
//
// @param: q: Handle for queue
// @param: rx_buf: Location for the item to be "moved" to
//
// @return: SUCCESS if value is removed, FAILURE if queue is empty
/**
* @brief Removes an item to the queue (dequeue)
* @note Interrupt safe ONLY if ONE producer and consumer
*
* @param q Handle for queue
* @param rx_buf Location for the item to be "moved" to
* @return success_t SUCCESS if value is removed, FAILURE if queue is empty
*/
success_t qReceive(q_handle_t* q, void* rx_buf)
{
if (q->item_count == 0) // Ensure that we actually have an item in the queue
{
return FAILURE_G; // We don't, so let the user know it failed
}

if ((q->start - q->buffer) == q->size * q->max_items) // Check if the start pointer location is at the end of the buffer
{
q->start = q->buffer; // Reset the buffer location
}

memcpy(rx_buf, q->start, q->size); // Copy item from queue into buffer
q->start = q->start + q->size; // Increment pointer by number of bytes corresponding to item size
--q->item_count; // Decrement number of items in queue

if (q->tail == q->head) return FAILURE_G; // Empty
volatile uint8_t* src = q->buffer + (q->tail * q->size);
for (uint32_t i = 0; i < q->size; ++i) ((uint8_t *)rx_buf)[i] = src[i];
q->tail = (q->tail + 1) % q->max_items; // Update tail
return SUCCESS_G;
}
}
14 changes: 7 additions & 7 deletions common/queue/queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

// Includes
#include "stdint.h"
#include "string.h"
#include "stdbool.h"

// Generic defines
#ifdef MEM_SMALL
Expand All @@ -23,17 +23,17 @@ typedef enum {

// Structs
typedef struct {
uint8_t buffer[MEM_SIZE]; // Ring buffer for queue storage
uint8_t item_count; // Number of items in queue
uint8_t max_items; // Maximum number of items in queue based on size
uint8_t* start; // Pointer to first item in queue
uint8_t* current; // Pointer to next location for addition
uint16_t size; // Size of each item
volatile uint8_t buffer[MEM_SIZE]; //!< Ring buffer for queue storage
volatile uint32_t head; //!< Element number of first item
volatile uint32_t tail; //!< Element number of last item
uint32_t size; //!< Size of each item
uint32_t max_items; //!< Maximum number of items in queue based on size (can only ever hold max_items - 1)
} q_handle_t;

// Prototypes
void qConstruct(q_handle_t* q, uint8_t size);
uint8_t qIsFull(q_handle_t* q);
uint8_t qIsEmpty(q_handle_t* q);
success_t qSendToBack(q_handle_t* q, const void* item);
success_t qReceive(q_handle_t* q, void* rx_buf);

Expand Down
2 changes: 1 addition & 1 deletion source/bootloader/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ int main (void)
*/
while(!bootloader_timeout || !allow_application_launch)
{
while (q_rx_can.item_count > 0)
while (!qIsEmpty(&q_rx_can))
canRxUpdate();

if (send_status_flag)
Expand Down
4 changes: 2 additions & 2 deletions source/dashboard/can/can_parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -326,8 +326,8 @@ bool initCANFilter()
CAN1->sFilterRegister[8].FR1 = (ID_FAULT_SYNC_MAIN_MODULE << 3) | 4;
CAN1->sFilterRegister[8].FR2 = (ID_FAULT_SYNC_DRIVELINE << 3) | 4;
CAN1->FA1R |= (1 << 9); // configure bank 9
CAN1->sFilterRegister[9].FR1 = (ID_FAULT_SYNC_TORQUE_VECTOR_FPGA << 3) | 4;
CAN1->sFilterRegister[9].FR2 = (ID_FAULT_SYNC_TEST_NODE << 3) | 4;
CAN1->sFilterRegister[9].FR1 = (ID_FAULT_SYNC_PRECHARGE << 3) | 4;
CAN1->sFilterRegister[9].FR2 = (ID_FAULT_SYNC_TORQUE_VECTOR_FPGA << 3) | 4;
CAN1->FA1R |= (1 << 10); // configure bank 10
CAN1->sFilterRegister[10].FR1 = (ID_FAULT_SYNC_TEST_NODE << 3) | 4;
CAN1->sFilterRegister[10].FR2 = (ID_SET_FAULT << 3) | 4;
Expand Down
4 changes: 2 additions & 2 deletions source/dashboard/can/can_parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
#define ID_FAULT_SYNC_DRIVELINE 0x8ca83
#define ID_FAULT_SYNC_PRECHARGE 0x8cac4
#define ID_FAULT_SYNC_TORQUE_VECTOR_FPGA 0x8ca42
#define ID_FAULT_SYNC_TEST_NODE 0x8cb7f
#define ID_FAULT_SYNC_TEST_NODE 0x8cbbf
#define ID_SET_FAULT 0x809c83e
#define ID_RETURN_FAULT_CONTROL 0x809c87e
#define ID_DAQ_COMMAND_DASHBOARD 0x14000172
Expand Down Expand Up @@ -194,7 +194,7 @@ typedef enum {

// Message Raw Structures
/* BEGIN AUTO MESSAGE STRUCTURE */
typedef union {
typedef union {
struct {
uint64_t throttle: 12;
uint64_t throttle_right: 12;
Expand Down
4 changes: 2 additions & 2 deletions source/driveline/can/can_parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,8 @@ bool initCANFilter()
CAN1->sFilterRegister[4].FR1 = (ID_FAULT_SYNC_PDU << 3) | 4;
CAN1->sFilterRegister[4].FR2 = (ID_FAULT_SYNC_MAIN_MODULE << 3) | 4;
CAN1->FA1R |= (1 << 5); // configure bank 5
CAN1->sFilterRegister[5].FR1 = (ID_FAULT_SYNC_PRECHARGE << 3) | 4;
CAN1->sFilterRegister[5].FR2 = (ID_FAULT_SYNC_TORQUE_VECTOR_FPGA << 3) | 4;
CAN1->sFilterRegister[5].FR1 = (ID_FAULT_SYNC_DASHBOARD << 3) | 4;
CAN1->sFilterRegister[5].FR2 = (ID_FAULT_SYNC_PRECHARGE << 3) | 4;
CAN1->FA1R |= (1 << 6); // configure bank 6
CAN1->sFilterRegister[6].FR1 = (ID_FAULT_SYNC_TORQUE_VECTOR_FPGA << 3) | 4;
CAN1->sFilterRegister[6].FR2 = (ID_FAULT_SYNC_TEST_NODE << 3) | 4;
Expand Down
4 changes: 2 additions & 2 deletions source/driveline/can/can_parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ typedef union {
#define ID_FAULT_SYNC_DASHBOARD 0x8cb05
#define ID_FAULT_SYNC_PRECHARGE 0x8cac4
#define ID_FAULT_SYNC_TORQUE_VECTOR_FPGA 0x8ca42
#define ID_FAULT_SYNC_TEST_NODE 0x8cb7f
#define ID_FAULT_SYNC_TEST_NODE 0x8cbbf
#define ID_SET_FAULT 0x809c83e
#define ID_RETURN_FAULT_CONTROL 0x809c87e
#define ID_DAQ_COMMAND_DRIVELINE 0x140000f2
Expand Down Expand Up @@ -228,7 +228,7 @@ typedef enum {

// Message Raw Structures
/* BEGIN AUTO MESSAGE STRUCTURE */
typedef union {
typedef union {
struct {
uint64_t front_left_motor: 8;
uint64_t front_left_motor_link: 8;
Expand Down
4 changes: 2 additions & 2 deletions source/l4_testing/can/can_parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ bool initCANFilter()
CAN1->sFilterRegister[3].FR1 = (ID_FAULT_SYNC_MAIN_MODULE << 3) | 4;
CAN1->sFilterRegister[3].FR2 = (ID_FAULT_SYNC_DRIVELINE << 3) | 4;
CAN1->FA1R |= (1 << 4); // configure bank 4
CAN1->sFilterRegister[4].FR1 = (ID_FAULT_SYNC_PRECHARGE << 3) | 4;
CAN1->sFilterRegister[4].FR2 = (ID_FAULT_SYNC_TORQUE_VECTOR_FPGA << 3) | 4;
CAN1->sFilterRegister[4].FR1 = (ID_FAULT_SYNC_DASHBOARD << 3) | 4;
CAN1->sFilterRegister[4].FR2 = (ID_FAULT_SYNC_PRECHARGE << 3) | 4;
CAN1->FA1R |= (1 << 5); // configure bank 5
CAN1->sFilterRegister[5].FR1 = (ID_FAULT_SYNC_TORQUE_VECTOR_FPGA << 3) | 4;
CAN1->sFilterRegister[5].FR2 = (ID_SET_FAULT << 3) | 4;
Expand Down
4 changes: 2 additions & 2 deletions source/main_module/can/can_parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,8 @@ bool initCANFilter()
CAN1->sFilterRegister[5].FR1 = (ID_FAULT_SYNC_DRIVELINE << 3) | 4;
CAN1->sFilterRegister[5].FR2 = (ID_FAULT_SYNC_DASHBOARD << 3) | 4;
CAN1->FA1R |= (1 << 6); // configure bank 6
CAN1->sFilterRegister[6].FR1 = (ID_FAULT_SYNC_TORQUE_VECTOR_FPGA << 3) | 4;
CAN1->sFilterRegister[6].FR2 = (ID_FAULT_SYNC_TEST_NODE << 3) | 4;
CAN1->sFilterRegister[6].FR1 = (ID_FAULT_SYNC_PRECHARGE << 3) | 4;
CAN1->sFilterRegister[6].FR2 = (ID_FAULT_SYNC_TORQUE_VECTOR_FPGA << 3) | 4;
CAN1->FA1R |= (1 << 7); // configure bank 7
CAN1->sFilterRegister[7].FR1 = (ID_FAULT_SYNC_TEST_NODE << 3) | 4;
CAN1->sFilterRegister[7].FR2 = (ID_SET_FAULT << 3) | 4;
Expand Down
4 changes: 2 additions & 2 deletions source/main_module/can/can_parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
#define ID_FAULT_SYNC_DASHBOARD 0x8cb05
#define ID_FAULT_SYNC_PRECHARGE 0x8cac4
#define ID_FAULT_SYNC_TORQUE_VECTOR_FPGA 0x8ca42
#define ID_FAULT_SYNC_TEST_NODE 0x8cb7f
#define ID_FAULT_SYNC_TEST_NODE 0x8cbbf
#define ID_SET_FAULT 0x809c83e
#define ID_RETURN_FAULT_CONTROL 0x809c87e
#define ID_DAQ_COMMAND_MAIN_MODULE 0x14000072
Expand Down Expand Up @@ -316,7 +316,7 @@ typedef enum {

// Message Raw Structures
/* BEGIN AUTO MESSAGE STRUCTURE */
typedef union {
typedef union {
struct {
uint64_t car_state: 8;
uint64_t precharge_state: 1;
Expand Down
4 changes: 2 additions & 2 deletions source/precharge/can/can_parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,8 @@ bool initCANFilter()
CAN1->sFilterRegister[3].FR1 = (ID_FAULT_SYNC_MAIN_MODULE << 3) | 4;
CAN1->sFilterRegister[3].FR2 = (ID_FAULT_SYNC_DRIVELINE << 3) | 4;
CAN1->FA1R |= (1 << 4); // configure bank 4
CAN1->sFilterRegister[4].FR1 = (ID_FAULT_SYNC_TORQUE_VECTOR_FPGA << 3) | 4;
CAN1->sFilterRegister[4].FR2 = (ID_FAULT_SYNC_TEST_NODE << 3) | 4;
CAN1->sFilterRegister[4].FR1 = (ID_FAULT_SYNC_DASHBOARD << 3) | 4;
CAN1->sFilterRegister[4].FR2 = (ID_FAULT_SYNC_TORQUE_VECTOR_FPGA << 3) | 4;
CAN1->FA1R |= (1 << 5); // configure bank 5
CAN1->sFilterRegister[5].FR1 = (ID_FAULT_SYNC_TEST_NODE << 3) | 4;
CAN1->sFilterRegister[5].FR2 = (ID_SET_FAULT << 3) | 4;
Expand Down
4 changes: 2 additions & 2 deletions source/precharge/can/can_parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
#define ID_FAULT_SYNC_DRIVELINE 0x8ca83
#define ID_FAULT_SYNC_DASHBOARD 0x8cb05
#define ID_FAULT_SYNC_TORQUE_VECTOR_FPGA 0x8ca42
#define ID_FAULT_SYNC_TEST_NODE 0x8cb7f
#define ID_FAULT_SYNC_TEST_NODE 0x8cbbf
#define ID_SET_FAULT 0x809c83e
#define ID_RETURN_FAULT_CONTROL 0x809c87e
#define ID_DAQ_COMMAND_PRECHARGE 0x14000132
Expand Down Expand Up @@ -273,7 +273,7 @@

// Message Raw Structures
/* BEGIN AUTO MESSAGE STRUCTURE */
typedef union {
typedef union {
struct {
uint64_t toggle: 1;
uint64_t time: 16;
Expand Down
Loading

0 comments on commit ad98366

Please sign in to comment.