Closed tehn closed 5 years ago
i've pushed a bunch of ideas for the ii implementation on crow to https://github.com/trentgill/crow/blob/master/lua/ii.lua
my concern is that the proposed idea of a giant table of lua functions for every potential module is the kind of thing that will chew up all of our working RAM. obviously this is not in itself that big of a deal, but perhaps underlies some lack of understanding about how memory usage works in the lua VM.
as i understand currently whenever we load these libraries with dofile() lua reads them from flash, converts them to lua chunks, and executes those chunks. the issue is these chunks must be held in RAM throughout the duration of the program's existence. the code can't be executed from flash (like it can for c) because the code itself can be modified or destroyed by the GC.
this leads to my conclusion that "all lua code is stored in RAM, for the duration of it's ability to be called".
perhaps i'm optimizing before necessary, but just worried this style of solution isn't going to be workable in our RAM limited environment. the more we use for these things, the less is left for the user to do interesting things.
your more experienced thoughts much appreciated here.
i believe you're correct re: RAM and GC.
we should get some numbers re: RAM usage for a function table for i2c. if we're really squeezed, we can potentially just forgo including the helper functions (and point at a reference guide with cut-paste functions).
ie under the heading ANSIBLE:
ANSIBLE_ADDR = 20 -- or whatever is correct
ANSIBLE_CMD_POS = 3 -- also
function ansible_kria_position(track, position)
i2c(ANSIBLE_ADDR, ANSIBLE_CMD_POS, track, position)
end
imagine this in a big reference guide, then users can cut-paste, or adapt them however they want. but all the info is there. it's a little weird, but perhaps an adequate solution.
also, the reference "guide" lua file could be completely imported within norns and these functions used directly.
i do really like the idea of the big function table, and i guess my concern is perhaps something more broadly affecting the project.
one thing i started doing was make the 'crowlib.lua' file be a wrapper over all the specific pieces of the standard library we mentioned. crowlib is loaded (as crow
) before the init() is called, and by default it loads all the libraries. this means a starting user has access to everything we ship with all the helpers etc.
then there's an option to call crow.libs(arg) which can customize what libraries are loaded. eg: one can load the asl.lua system without the asllib.lua which is a bunch of helpers providing classic shapes like lfo(), ar(), adsr() to save on space.
taking this approach to the i2c context, perhaps loading the whole function table could be optional, or able to be unset if there's memory issues. we could also wrap each modules function table in its own file which is able to be loaded individually. this makes it easier to ask others to provide crow-support for their own modules, by just adding a single lua file and one line to the 'load all' function body.
this feels annoying (having to explicit say "load the kria_ii_commands" before using them), but it would be one way without requiring a separate reference guide. if things are stored in C-headers, there's obviously no issue, the hard part is just figuring out how to access them.
eg: the response to ii.get_commands() could actually fetch a C-string in flash, rather than a lua-string in RAM.
just added a ram-usage checker that's called after each lua lib that's loaded. haven't had the chance to try it yet, but will be good to see these numbers.
duplicate of https://github.com/trentgill/crow/issues/17