-
Notifications
You must be signed in to change notification settings - Fork 18
Feature/serial bridge subscribe #332
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
base: develop
Are you sure you want to change the base?
Conversation
| @@ -0,0 +1,4 @@ | |||
| #pragma once | |||
|
|
|||
| void setup(); | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add comments for functions. Though, this interface is used in many other places. Thinking this common interface could go somewhere like src/lib/user_app
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is supposed to mimic an Arduino like interface for folks looking to quickly dev on the Bristlemouth development kits. Hence why all of the user_code files follow this trend. I would take a look at some of the Bristlemouth DevKit instructions for users looking to develop in the Bristlemouth ecosystem if you haven't taken a look yet!
| #include "sensors.h" | ||
| #include "task_priorities.h" | ||
| #include <inttypes.h> | ||
| #include <string.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- This doesn't include
user_code.h. <inttypes.h> appears to not be used. I think standard int types are coming from<stdin.h>viabm_os.h
| typedef enum { | ||
| BM_NONE, | ||
| BM_SUB, | ||
| } __attribute__((__packed__)) bm_serial_tx_message_t; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could change to
__PACKED_STRUCT bm_serial_tx_message_t {
// fields here
};
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wait -- bm_serial_tx_message_t is an enum. I don't think it makes sense to make an enum a packed struct. Did you mean to put that on bm_serial_tx_t?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is unused and has been removed.
| } | ||
|
|
||
| void setup() { | ||
| PLUART::init(USER_TASK_PRIORITY); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if PLUART is used by another task?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at payload_uart::init(), I have some concern there.
- I suppose PLUART is attempting to do a Singleton pattern, but there is nothing I see that prevents it from being called by multiple users, each potentially changing the setup
- The init function just allocates a new task, but there is no way I see to destroy the task.
- For all cases,
payload_uart::init()configuresMX_LPUART1_UART_Init, but then we are allowed to set the other parameters such asbaud,useByteStreamBuffer, etc and also independantlyenable/disable - There is nothing that calls
payload_uart::disable(). But even if we did, it still does not clean up the FreeRTOS task. Perhaps it shouldnt' for disable, but the name should be calleddisable_serial(). Perhaps there could be a seperate functiondisable_serial_task()-- though, that wouldn't just work as pluart is designed because no handle to the task is returned to the caller. - Outside the scope of this PR, but I don't understand why payload_uart was hardcoded for a specific uart
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually, it's worse user_byte_stream_buffer is static and is reset on each call of init() (same for _user_line, _postTxSemaphore, uart_handle). It may still work ok, but this would be a leak for multiple users. Granted, out of scope for this PR, but unless I'm crazy, if pluart is intended to be a singleton with one client, init should be something like this
// Check if already initialized
if (rxTaskHandle != NULL) {
return pdFAIL; // Already initialized
}
though it may be okay to allow mutliple callers with one instance. In the current design, allowing multiple tasks doesn't make sense because we are hard-binded to one specific uart.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
man...pluart also exposes these in the header
// external declarations for the variables
extern SerialLineBuffer_t lpUART1LineBuffer;
extern SerialHandle_t uart_handle;
these need moved to the cpp file
@matt001k sorry for these pluart comments! I just don't want to lose the thoughts!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm...seeing the vTaskDelay(pdMS_TO_TICKS(5)); code in the setup function made me think that we may actually have the context for the task here, so we may be able to teardown the task from here. Though the memory leaks in pluart remain
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely worth capturing, right now there is no contention in any of our apps but could for sure be in the future.
| #include <inttypes.h> | ||
| #include <string.h> | ||
|
|
||
| typedef enum { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add comments to bm_serial_tx_message_t, bm_serial_tx_message_t, and the variables declarations below. Add new lines after the enum & struct declarations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This typedef is unused and has been removed.
| static constexpr size_t packet_buf_size = rx_buf_size; | ||
| static uint8_t packet_buffer[rx_buf_size]; | ||
|
|
||
| static bool tx_cb(const uint8_t *buff, size_t len, bm_serial_message_t message) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add comments for each internal method
| IOWrite(&BB_PL_BUCK_EN, 0); | ||
| } | ||
|
|
||
| static void reset() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reset_rx may be more clear b/c that is all it is resetting
should we reset packet_buffer here too?
| uint8_t type; | ||
| uint32_t length; | ||
| uint8_t data[0]; | ||
| } bm_serial_tx_t; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bm_serial_tx_t doesn't seem to be used. If correct, can remove it.
| callbacks.pub_fn = pub_cb; | ||
| callbacks.sub_fn = sub_cb; | ||
| callbacks.tx_fn = tx_cb; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The callbacks could be defined compile time
static bm_serial_callbacks_t callbacks = {
callbacks.pub_fn = pub_cb,
callbacks.sub_fn = sub_cb,
callbacks.tx_fn = tx_cb;,
}
you'd just have to forward declare the functions
I do have a slight concern for namespace collection with the generic function names pub_sub, sub_cb, tx_cb. We should be safe for compile b/c they are delcared static. Something like serial_bridge_pub_cb could make it easier to read and trace.
| @@ -0,0 +1,100 @@ | |||
| #include "bm_os.h" | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it'd be more descriptive to name this file something like serial_bridge rather than the generic user_code.cpp. Though I realize this is a common pattern.
|
Good comments, thanks @LarkspurRaven — this PR is low priority and does not need to make it into v0.13.4. |
LarkspurRaven
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not quite done with review, but progress so far
| uint32_t length; | ||
| uint8_t data[0]; | ||
| } bm_serial_tx_t; | ||
| static bm_serial_callbacks_t callbacks; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add comments for variable declarations
| uint8_t data[0]; | ||
| } bm_serial_tx_t; | ||
| static bm_serial_callbacks_t callbacks; | ||
| static constexpr size_t rx_buf_size = 2048; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rx_buf_sizes/b capitalized -->RX_BUF_SIZE. Well, not 100% certain on our naming standards...need to check- As we are using this for both
rx_bufandpkt_buff, could be better to name asBUFFER_SIZE - This is just my preference, but I prefer to have configurable values like this declared at the top of the file in a marked section. Perhaps in a header. Is this buffer size common for other user_code apps?
| static uint8_t packet_buffer[rx_buf_size]; | ||
|
|
||
| static bool tx_cb(const uint8_t *buff, size_t len, bm_serial_message_t message) { | ||
| (void)message; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should probably add a check on buff for null pointer, since it is not coming from us. Perhaps add a check for length as well. Though maybe PLUART::write() checks both.
I don't really understand who calls this method tx_cb(), or when it'd be called. Comment could clarify that.
| return true; | ||
| } | ||
|
|
||
| static void sub_message_cb(uint64_t node_id, const char *topic, uint16_t topic_len, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in sub_message_cb() are topic and data guaranteed to not be null? If not, we should probably add a null check. is there any validation we could consider on the topic and data?
Perhaps bm_serial_pub() handles my concerns? If so, we should call it first
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bm_serial_pub does check the params, so we should call it first
if(bm_serial_pub(...){
printf("Failed to send serial_bridge msg\n");
some_method_to_safely_print_this_message(...);
} else {
printf("Publishing To Topic: %s\n", topic);
}
| } | ||
|
|
||
| static bool sub_cb(const char *topic, uint16_t topic_len) { | ||
| return bm_sub_wl(topic, topic_len, sub_message_cb); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bm_sub_wl returns BmErr not bool. Should cast or handle
| const uint8_t *payload, size_t len, uint8_t type, uint8_t version) { | ||
| (void)node_id; | ||
| printf("publishing %u bytes to %.*s\n", len, topic_len, topic); | ||
| return bm_pub_wl(topic, topic_len, payload, len, type, version) == BmOK; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bm_pub_wl returns BmErr not bool. Should cast or handle
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct, the statements reads:
bm_pub_wl(topic, topic_len, payload, len, type, version) == BmOK
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my mistake 👍
| } | ||
|
|
||
| void setup() { | ||
| PLUART::init(USER_TASK_PRIORITY); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm...seeing the vTaskDelay(pdMS_TO_TICKS(5)); code in the setup function made me think that we may actually have the context for the task here, so we may be able to teardown the task from here. Though the memory leaks in pluart remain
| #include <inttypes.h> | ||
| #include <string.h> | ||
|
|
||
| typedef enum { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This typedef is unused and has been removed.
| typedef enum { | ||
| BM_NONE, | ||
| BM_SUB, | ||
| } __attribute__((__packed__)) bm_serial_tx_message_t; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is unused and has been removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@LarkspurRaven this file was copied from another application. I will make suggested changes but it will not be reflected in the other user_code.cpp file located in this diff.
There should probably be some common location for application that can exist in multiple application spaces.
| const uint8_t *payload, size_t len, uint8_t type, uint8_t version) { | ||
| (void)node_id; | ||
| printf("publishing %u bytes to %.*s\n", len, topic_len, topic); | ||
| return bm_pub_wl(topic, topic_len, payload, len, type, version) == BmOK; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct, the statements reads:
bm_pub_wl(topic, topic_len, payload, len, type, version) == BmOK
| } | ||
|
|
||
| void setup() { | ||
| PLUART::init(USER_TASK_PRIORITY); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely worth capturing, right now there is no contention in any of our apps but could for sure be in the future.
d89bf21 to
6fdfdb4
Compare
What changed?
Added subscription capability to serial bridge application.
Adds serial bridge application to Bristleback.
How does it make Bristlemouth better?
Expands the serial bridge application to allow companion devices to subscribe to topics.
Where should reviewers focus?
Mainly the diff in the serial bridge apps!
Checklist