-
Notifications
You must be signed in to change notification settings - Fork 72
Closed
Description
According to the code, SerialTransfer
requires the passed callback array to stay allocated for its whole lifetime.
- This is not documented.
- All the callback-related examples are actually accessing reusable stack memory.
Steps to reproduce: A modified uart_rx_with_callbacks.ino
example is attached below - using LED blinking, as I have just one serial. I was able to reproduce it also by printing the memory addresses.
Expected behavior:
- This should be documented.
- Examples should have the callback config defined outside of any functions.
- I actually noticed that a solution is already part of the "polishing" effort, where a dynamic linked list is used instead. So not filing a PR for now.
Example of invalid memory access:
#include <Arduino.h>
#include "SerialTransfer.h"
SerialTransfer myTransfer;
// A callback passed to SerialTransfer
void hi() {
digitalWrite(LED_BUILTIN, HIGH);
delay(500);
digitalWrite(LED_BUILTIN, LOW);
delay(500);
}
// My very private function
void hey() {
for (int i = 0; i < 10; i++) {
digitalWrite(LED_BUILTIN, HIGH);
delay(50);
digitalWrite(LED_BUILTIN, LOW);
delay(50);
}
}
// Prevent compiler from optimizing unused stack variables.
// Serial1.println(foo) would work too if you had Serial1 :-)
volatile uint16_t variableInUse1 = 0;
volatile uint16_t variableInUse2 = 0;
void setup() {
Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT);
functionPtr callbackArr[] = { hi };
variableInUse1 = (uint16_t) &callbackArr[0];
///////////////////////////////////////////////////////////////// Config Parameters
configST myConfig;
myConfig.debug = true;
myConfig.callbacks = callbackArr;
myConfig.callbacksLen = sizeof(callbackArr) / sizeof(functionPtr);
/////////////////////////////////////////////////////////////////
myTransfer.begin(Serial, myConfig);
// Dispatch a few messages with the setup() stack
while (millis() < 10000LU) {
myTransfer.tick(); // hi() is called
}
}
void loop() {
functionPtr myVeryPrivateArray[] = { hey };
variableInUse2 = (uint16_t) &myVeryPrivateArray[0];
// Dispatch messages within the loop() stack
myTransfer.tick(); // oh my - hey() is called!
}
Metadata
Metadata
Assignees
Labels
No labels