-
-
Notifications
You must be signed in to change notification settings - Fork 284
Use IPM for cdc-acm #552
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
Use IPM for cdc-acm #552
Conversation
@eriknyquist @SidLeung ready for review |
cores/arduino/CDCSerialClass.cpp
Outdated
@@ -73,7 +100,9 @@ void CDCSerialClass::init(const uint32_t dwBaudRate, const uint8_t modeReg) | |||
* Empty the Rx buffer but don't touch Tx buffer: it is drained by the | |||
* LMT one way or another */ | |||
_rx_buffer->tail = _rx_buffer->head; | |||
|
|||
|
|||
mailbox_register(6, cdc_mbox_isr); |
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.
Channel 6 is exposed by the CurieMailbox library. If you use this channel, the Mailbox library and Serial will not work simultaneously.
Can we use channel 7 for both RX and TX?
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.
From my initial tests using channel 7 for both was not stable. It freezes when we are sending and receiving on both cores at a high rate
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.
Throughput would be vastly improved if we fill all 16 bytes of the mailbox channel, instead of sending 1 message per character. Let's focus on that first, and then see if it's stable enough to use one channel for RX/TX
cores/arduino/CDCSerialClass.cpp
Outdated
{ | ||
if(((uint8_t)dword) != '\0') | ||
{ | ||
new_head = (Serial._rx_buffer->head +1) % CDCACM_BUFFER_SIZE; |
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.
Surely there's some kind of 'ringbuffer_add' method? we should not be re-implementing this logic for each write to the buffer.
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.
there is none implemented for the cdc-acm ring buffer in shared memory
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.
let's implement one, then.
@@ -36,6 +36,33 @@ extern void CDCSerial_Handler(void); | |||
extern void serialEventRun1(void) __attribute__((weak)); | |||
extern void serialEvent1(void) __attribute__((weak)); | |||
|
|||
static void cdc_mbox_isr(CurieMailboxMsg msg) |
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 function looks really complex for such a simple task. Can't you just do something like this;
unsigned char *ptr = (unsigned char*) msg.data;
/* Continue until 16 chars, or until NULL is seen */
for (unsigned i = 0; i < 16 && ptr[i]; ++i) {
/* Assuming we have some kind of 'put' method for ring buffer... */
ringbuffer_put(ptr[i]);
}
cores/arduino/CDCSerialClass.cpp
Outdated
uint32_t retries = 2; | ||
|
||
CurieMailboxMsg cdcacm_msg; | ||
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.
trailing whitespace
cores/arduino/CDCSerialClass.cpp
Outdated
} while (retries--); | ||
|
||
cdcacm_msg.channel = 7; | ||
cdcacm_msg.data[0] = (uint32_t)uc_data; |
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.
Why the cast to uint32_t? not needed at all. remove please
cores/arduino/CDCSerialClass.cpp
Outdated
} | ||
} while (retries--); | ||
|
||
cdcacm_msg.channel = 7; |
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.
- Give it a name. You know the drill, by now I hope.....
cores/arduino/CDCSerialClass.cpp
Outdated
@@ -73,7 +100,9 @@ void CDCSerialClass::init(const uint32_t dwBaudRate, const uint8_t modeReg) | |||
* Empty the Rx buffer but don't touch Tx buffer: it is drained by the | |||
* LMT one way or another */ | |||
_rx_buffer->tail = _rx_buffer->head; | |||
|
|||
|
|||
mailbox_register(6, cdc_mbox_isr); |
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.
Throughput would be vastly improved if we fill all 16 bytes of the mailbox channel, instead of sending 1 message per character. Let's focus on that first, and then see if it's stable enough to use one channel for RX/TX
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.
Still un-addressed comments in the first revision, and some new things to be addressed in the most recent revision.
cores/arduino/CDCSerialClass.cpp
Outdated
|
||
size_t CDCSerialClass::write(const uint8_t *buffer, size_t size) |
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 function is super complicated.... again the nested for-loops and bit shifting is unnecessary. Also, you forgot to return the number of bytes written at the end.
Here's a different version of this same function, which is much shorter (about 50% of it is comments anyway) and easier to read, only needs a single loop, and handles the missing return as well...
/* Size in bytes of a mailbox message payload */
#define MBOX_BYTES (CHANNEL_DATA_WORDS * sizeof(uint32_t))
...
size_t CDCSerialClass::write(const uint8_t *buffer, size_t size) {
CurieMailboxMsg cdcacm_msg;
unsigned int i, step, remainder;
cdcacm_msg.channel = CDC_MAILBOX_TX_CHANNEL;
if (!_shared_data->device_open || !_shared_data->host_open)
return(0);
do {
/* Distance to next 16-byte boundary */
remainder = i % MBOX_BYTES;
if (i > 0 && (remainder == 0 || !buffer[i] || i == size) {
/* Either we are copying a full 16 bytes (standard condition), or from
* the current position to the last 16-byte boundary (end-of-input condition)*/
step = (buffer[i] || i == size) ? MBOX_BYTES : remainder;
/* Copy data into mailbox message */
memset(cdcacm_msg.data, 0, sizeof(cdcacm_msg.data));
memcpy(cdcacm_msg.data, buffer + (i - step), step);
/* Write to mailbox*/
mailbox_write(cdcacm_msg);
}
/* Continue until a null character, or max. write size, is reached*/
} while (buffer[i] && size > i++);
/* Return no. of bytes written */
return i;
}
if (!_shared_data->device_open || !_shared_data->host_open) | ||
return(0); | ||
|
||
int msg_len = size; |
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.
msg_len
never changes, why is it needed at all? just use size
directly.
-use the IPM instead of shared memory for passing data between ARC and x86 cores for cdc-acm.
-use the IPM instead of shared memory for passing data between ARC
and x86 cores for cdc-acm.