-
-
Notifications
You must be signed in to change notification settings - Fork 7k
Serial class use ram for buffer even if not used #1259
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
Comments
Interesting, so you just initialized the buffers structure to NULL, and allocate/deallocate the real memory on begin()/end(), right? there are any other changes that I'm ovrelooking? |
yes, other change are just check is buffer is null into ISR, read, write, If buffer are NULL i return -1 for read, 0 for available and write, and do I'll try to do a pull request later updated to latest code, but i'm at work 2013/2/4 Cristian Maglie [email protected]
|
In the past, other people have expressed concern about using malloc() / dynamic memory for these kinds of things. There's the obvious concern that the allocation could fail, but in general, people seem to have reservations about requiring dynamic memory allocation in core classes. I'm not sure how important those concerns are but they may be worth looking into. |
i've think about this. There are 3 basic solution:
It will be a user's problem check if begin fail, but that way we can be The only real problem i can see is the physical position of the buffer, if 2013/2/4 David A. Mellis [email protected]
|
On AVR, the compiler and linker somehow know to avoid linking the serial interrupts, if none of the other serial code is actually used. If you never call Serial.begin() or any other serial functions on Arduino Uno, the serial port code and interrupt are not included in the output, and the buffers are not allocated in RAM. On ARM, I've been searching (so far without success) for a way to duplicate this functionality. How the AVR interrupt vector table is built is something of a mystery to me... at least so far. On ARM, there's an array of addresses that have weak aliases to an unused handler. As soon as any interrupt routine is seen by the linker, that weak alias is replaced by the address of the interrupt routine. The linker must then include the interrupt code, and of course the buffers it uses in RAM, even though nothing else from that file is linked. AVR somehow avoids this. If anyone knows how, I would really be curious to hear? |
I don't know about interrupt, but I'm pretty sure about ram usage. The
|
@PaulStoffregen, have a look at the comments in #1711 and this post on the mailing list: https://groups.google.com/a/arduino.cc/d/msg/developers/NqRMcgZEKCU/3A2sjSF5h9QJ Together, they should explain how this stuff works on AVR and perhaps allow you to find out what's different on ARM? |
By putting the ISRs and HardwareSerial instance for each instance in a separate compilation unit, the compile will only consider them for linking when the instance is actually used. The ISR is always referenced by the compiler runtime and the Serialx_available() function is always referenced by SerialEventRun(), but both references are weak and thus do not cause the compilation to be included in the link by themselves. The effect of this is that when multiple HardwareSerial ports are available, but not all are used, buffers are only allocated and ISRs are only included for the serial ports that are used. On the mega, this lowers memory usage from 653 bytes to just 182 when only using the first serial port. On boards with just a single port, there is no change, since the code and memory was already left out when no serial port was used at all. This fixes arduino#1425 and fixes arduino#1259.
By putting the ISRs and HardwareSerial instance for each instance in a separate compilation unit, the compile will only consider them for linking when the instance is actually used. The ISR is always referenced by the compiler runtime and the Serialx_available() function is always referenced by SerialEventRun(), but both references are weak and thus do not cause the compilation to be included in the link by themselves. The effect of this is that when multiple HardwareSerial ports are available, but not all are used, buffers are only allocated and ISRs are only included for the serial ports that are used. On the mega, this lowers memory usage from 653 bytes to just 182 when only using the first serial port. On boards with just a single port, there is no change, since the code and memory was already left out when no serial port was used at all. This fixes arduino#1425 and fixes arduino#1259.
Fixed in 1.5.6. |
Hi, actually the Serial class always initialize its buffer. This is bad for example on mega, where much ram is "stolen"
I've modded the serial library to allocate the ram only if begin() is called. also the call of end() free the buffer.
This is backward compatible, but has been tested only by me, so it need better testing.
it is based on HardwareSerial.cpp of 1.0.2
code: http://arduino.cc/forum/index.php?action=dlattach;topic=141254.0;attach=33317
The text was updated successfully, but these errors were encountered: