-
-
Notifications
You must be signed in to change notification settings - Fork 954
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 all free RAM for FreeRTOS heap #2172
Conversation
Build size and comparison to main:
|
This has been a wishlist item for me for ages! Awesome to see it realised Could you explain the |
Now LFS is using the |
Why not define |
That's what I'm doing here, the issue is that in order to define those macros before littlefs uses them we need to define |
Ah yeah I see the issue now, defining the macro at the right time is annoying. |
Yeah that's what my first idea was but unfortunately it doesn't work because it wouldn't be included when compiling the |
Ah, you're right :) |
Any chance you could take a look at the build failure BTW? Also would I be right in saying that the sbrk implementation can be removed now with littlefs' printf removed? |
I would still leave it in because otherwise if were to ever get called it would corrupt the FreeRTOS heap. Maybe we could replace the body with a hard fault so that at least it crashes right away, to be honest I'm not sure if the implementation using |
Yeah I'm liking the sound of a hard fault there, nothing should ever be calling it. And same, I'm not sure malloc'ing there is correct, looking at the manpage shows some things that don't line up with it just being malloc (particularly the behaviour when decreasing the program break or checking it). I don't know if we could add some linker error to prevent the sbrk even being linked in? - it might be theoretically required by something anyway. |
Sounds good. It does seem like sbrk is being used my something else, more research is needed. |
It seems like there's no way to make _sbrk implementationstatic int brk_size = 0;
static void *brk = NULL;
void* _sbrk(int size) {
if (size == 0) {
return brk;
}
brk_size += size;
brk = pvPortRealloc(brk, brk_size);
if (brk == NULL) {
return (void*)-1;
}
return brk;
} The |
Very interesting reading on the topic https://nadler.com/embedded/newlibAndFreeRTOS.html |
That's very useful indeed, thanks! I'll try the ideas from the article and report back. |
Looks great, lines up nicely with current heap size of 40960! |
Hmm I see the lfs config breaking the formatting check. I haven't thought too much about where it belongs, but would it make sense to move it to the libs directory along with lv_conf.h (everything in libs is not format checked)? There might well be good reasons not to so I'm not sure Edit: Also is there some way to avoid duplicating the original lfs_config.c? Can we add an include somewhere? |
I feel like moving it to the libs folder probably makes the most sense as far as I understand it, especially given that there's already a similar file there. I've also realized that we don't really need to modify the LFS config anymore since we now have a functioning malloc replacement, however I've noticed that replacing the log calls reduces the RAM usage by about 1.4kB, so it might be worth keeping it as-is. EDIT: Nevermind about the first point, I found a better (if hackier) way to include the original CRC implementation here. |
ohhhh nice yeah that undefine trick is good. Probably needs some comments to explain it. I'm all good to move the lfs_config.h to libs then |
Booted fine on my watch. Will daily drive for the forseeable future and report back any issues |
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.
LGTM
No further comments for now, I'll approve after some wrist time (all looking good so far)
Edit: Might want to draft up an InfiniSim PR at some point, no rush though
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.
Been working flawlessly. Is this ready in your eyes?
Been working fine on my end too, I think it's good to go! |
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.
Looks good to me too!
@FintasticMan made me realize that there's a better way to do the |
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 looks good now!
With this change you no longer need to fiddle with FreeRTOS's
configTOTAL_HEAP_SIZE
to make it fit into the RAM and instead it will always automatically use all available RAM for the heap.This is achieved by using two symbols defined by the linker script:
__HeapLimit
and__StackLimit
, which indicate where the used heap ends and where the stack "begins" (really ends) in memory respectively. It's not yet ready for production since I'm still not 100% sure there aren't any side effects (the emulator works fine with this build but if anyone with a devkit can run this for a while that'd be great), and also it currently only uses about 39.5 KB for the heap for reasons I'm still not quite sure about.Here's a rough representation of the RAM:
Note that in this case
<heap>
doesn't refer to FreeRTOS's heap but rather GCC's heap which is 0 bytes long in our case, so__HeapLimit == __HeapBase
.Before this change, FreeRTOS's heap was statically allocated in the
<global vars>
region and the goal was to manually increment the heap size in order to make the<free space>
region as small as possible, since that region is essentially wasted RAM space. Now we instead put the FreeRTOS heap right where the<heap>
region ends and make it stretch right until the top of the stack (__StackLimit
), which ensures we waste no RAM.I did have to overwrite the
_sbrk
method because apparently there's aprintf
definition somewhere that uses a different implementation ofmalloc
that doesn't use the FreeRTOS heap and instead allocates around 1 KB of RAM for itself, this is probably worth looking into just by itself.