Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rx Queue #2

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Rx Queue #2

wants to merge 1 commit into from

Conversation

larry-pan
Copy link

This PR changes to Rx ISR logic to shorten the interrupt. The ISR callback function HAL_CAN_RxFifo0MsgPendingCallback now adds the received CANFrame into a queue (CanardRxQueue) instead of processing the frame with canardHandleRxFrame immediately. The queue is continuously dequeued in the superloop.

Flow chart can be found here: https://uwarg-docs.atlassian.net/wiki/spaces/ZP/pages/2859827205/Rx+Queue+to+Shorten+ISR

Why is this Change Needed: The interrupt is currently very long because the canardHandleRxFrame is long. Additionally, interrupts are processed in LIFO order, so old interrupts can remain unprocessed for a long time. The queue creates FIFO order instead, so the interrupt itself is much shorter because we call canardHandleRxFrame in the superloop and not in the ISR.

How users can use the code: Functionally, the code works the same as before this change.

What tests has been done to prove the code is working: Code was tested on a server controller with through the pixhawk. The servo received messages and responded as expected.

@larry-pan larry-pan requested a review from HardyYu November 30, 2024 19:28
Copy link
Contributor

@HardyYu HardyYu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good stuff! Comments added

struct CanardRxQueueItem* next;
CanardCANFrame frame;
};

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the size of the queue? If there is no boundary for the size of the queue, then what if the rx processing speed is slower than the rx incoming speed? I guess the system would run out of the memory and hard fault.

I think it will be better to keep track of the length of the queue somehow.

struct CanardRxQueueItem* rxQueueHead = NULL;
struct CanardRxQueueItem* rxQueueTail = NULL;

void enqueueRxFrame(CanardCANFrame* rx_frame) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, this enqueue function returns nothing. It would be so much better if this function could return some sort of error code. For instance,
enum rxQueueErrorCode{ SUCCESS, EMPTYITEM, OVERFLOW }

extern struct CanardRxQueueItem* rxQueueHead;
extern struct CanardRxQueueItem* rxQueueTail;

void enqueueRxFrame(CanardCANFrame* rx_frame);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

more comments to describe what the function does, its parameters, and return value are greatly appreciated.


if (!rxQueueHead) {
rxQueueTail = NULL; // after dequeuing, the queue is empty
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you dynamically allocated the queue item, the allocated memory should be handled carefully when we are done with it. You should really explicitly write a comment somewhere to let people know they need to free the memory block themselves after they pop it from the queue. Or, more preferably, you handle it for the user.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants