pierremolinaro / acan2515

MCP2515 CAN Controller Driver for Arduino
MIT License
77 stars 30 forks source link

ACAN2515::begin() hangs if less than about 900b free RAM is left on Arduino UNO #2

Open PatrykSSS opened 5 years ago

PatrykSSS commented 5 years ago

To reproduce put the following code before ACAN2515::begin() in LoopBackDemo: static char Buf[600]; Serial.print(Buf); Result: Sketch uses 7532 bytes (24%) of program storage space. Maximum is 30720 bytes. Global variables use 1122 bytes (54%) of dynamic memory, leaving 926 bytes for local variables. Maximum is 2048 bytes. Checked with Arduino IDE 1.8.8 (1.8.19.0 in Windows Store). I would expect some error to be returned instead, and if the library has indeed so large memory requirements then it could be stated in the documentation. It also prevents usage of two instances (with two CAN interfaces).

pierremolinaro commented 5 years ago

Hello,

The Arduino Uno processor provides a 2048 byte RAM.

An ACAN2515 object requires 61 bytes (release 1.1.0, on Arduino Uno), and when its begin method is executed, allocates dynamically receive and transmit buffers. By default:

The 61 bytes are included in the global variables.

The 512 + 256 bytes are allocated in "local variables" : so 926 - 512 - 256 = 158 bytes are available for other local variables, it's probably too little for the program to work properly.

The only solution is to decrease receive and transmit buffer sizes. For example, you can insert the two following lines before calling can.begin: settings.mReceiveBufferSize = 16 ; settings.mTransmitBuffer0Size = 8 ;

So 926 - 16 * 16 - 8 x 16 = 542 bytes are available for other local variables, and now the program runs properly.

If you need two instances, you have to reduce buffer sizes accordingly.

The second instance uses 61 bytes -> now 926 - 61 = 865 bytes will be available for other local variables. For example, with theses settings: settings.mReceiveBufferSize = 7 ; settings.mTransmitBuffer0Size = 3 ; 865 - 2 7 16 - 2 * 3 x 16 = 545 bytes will be available for other local variables, I think the program will run properly.

Best regards,

Pierre Molinaro

Le 15 janv. 2019 à 13:23, PatrykSSS notifications@github.com a écrit :

To reproduce put the following code before ACAN2515::begin() in LoopBackDemo: static char Buf[600]; Serial.print(Buf); Result: Sketch uses 7532 bytes (24%) of program storage space. Maximum is 30720 bytes. Global variables use 1122 bytes (54%) of dynamic memory, leaving 926 bytes for local variables. Maximum is 2048 bytes. Checked with Arduino IDE 1.8.8 (1.8.19.0 in Windows Store). I would expect some error to be returned instead, and if the library has indeed so large memory requirements then it could be stated in the documentation. It also prevents usage of two instances (with two CAN interfaces).

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/pierremolinaro/acan2515/issues/2, or mute the thread https://github.com/notifications/unsubscribe-auth/ASys1DeVSXN-udiyjB0uPsgCNxhdNYV7ks5vDchIgaJpZM4aA20d.

PatrykSSS commented 5 years ago

Thanks for the explanation and solution - so it looks like either dynamic allocation of buffers failed (and mBuffer doesn't seem to be checked for 0/NULL within ACANBuffer{}), or heap and stack were both growing towards each other and this led to clash. Anyway I have adapted buffer numbers to my needs and now my CHAdeMO controller for electric car has two CAN buses as mandated by the standard - one for communication with the CHAdeMO station and one to talk with BMSes / current sensor / display. Thanks! :-)

pierremolinaro commented 5 years ago

You are right, I will add the check in the next release of ACAN2515.

Best regards,

Pierre

Le 16 janv. 2019 à 02:23, PatrykSSS notifications@github.com a écrit :

Thanks for the explanation and solution - so it looks like either dynamic allocation of buffers failed (and mBuffer doesn't seem to be checked for 0/NULL within ACANBuffer{}), or heap and stack were both growing towards each other and this led to clash. Anyway I have adapted buffer numbers to my needs and now my CHAdeMO controller for electric car has two CAN buses as mandated by the standard - one for communication with the CHAdeMO station and one to talk with BMSes / current sensor / display. Thanks! :-)

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/pierremolinaro/acan2515/issues/2#issuecomment-454615243, or mute the thread https://github.com/notifications/unsubscribe-auth/ASys1GZ7k_0cM-iJJaxJ8ej6-bjYuk9zks5vDn8FgaJpZM4aA20d.