lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

Your string should be referenced by a Lua thread, that is not dying/terminating, just waiting to be awoken and resumed later, so that thread should be left in a wait state. In that case, the thread is still alive, references the string (eventually a copy of it, allocated in a memory usable for DMA). If the DMA memory not allocated by Lua, you may need to keep the pointer in a Lua-allocated userdata object owned by that Lua thread). And then the garbage collector should not deallocate that userdata object, it may eventually move it, but it will keep your external pointer inside; you may as well keep in the userdata object other info you need, such as resources allocated for DMA channel, or a I/O request object whose completion will be served by a custom interrupt handler. May be your serial I/O service should be a thread running parmaneltly, until it has to serve a request to shutdown: that thread would be a simple even processing loop waiting for events, i.e. I/O requests to service; it may eventually be able to sueue serveral requests, it could reuse its DMA buffers. Typically for a serial link with an UART, a small buffer of just 64 bytes for the block currently used bny the DMA, and a second buffer for the next block to fill) is sufficient for slow serial speeds below 100 kbps, but you may use longer buffers if you wish.
Then if your main application thread wants to send long strings (200-1000 bytes) it can send I/O requests to your service using blocking I/O, like when writing files or to the standard output of a console: you'll yield to the service thread so that it will scan your query and process it by copying into the small buffers of the service thread, which will switch automatically from a completed buffer to the next one, if it is sufficiently full, or if some small delay has passed (e.g. 10ms). Your service thread should then wait for two kinds of events: I/O completion events from the interrupt handler, or a timer event (e.g. running at 100Hz, may be faster if your device supports faster timers and you want smoother response times).

Le ven. 11 juin 2021 à 13:48, Flyer31 Test <> a écrit :
Hi Shankusu,
thank you for answer, this sounds interesting - can you give me some short example how to put the data best to global data for a Lua programming newbie like me?

... somehow the "upgrade" for my current 
const char* pcData= lua_tostring( L, -1);


On Fri, Jun 11, 2021 at 11:48 AM shankusu2017 <> wrote:
Lua's gc module does not change the reference attribute of the data, so you still need to change the reference attribute of the data. You can set the data to the global table before sending, and delete it from the global table in the handle of the callback when the DMA transmission is completed. Hope Can help you

Flyer31 Test <> 于2021年6月11日周五 下午4:47写道:
In my Lua microcontroller application (quite restricted RAM space), I would implement some function written by C, which sends data out through a serial interface.

So this function gets e. g. a longer string (e. g. 200-1000 bytes), and sends out through serial interface.

For doing this in an optimum way, I would use DMA (Direct Memory access), tell the DMA the start address of this string data, and then continue with my Lua program (or if the user prefers to wait end of send, I would call yieldk/resume and thus do some other CPU work until the DMA send has finished).

Problem now is, that as soon that I leave my c function with yieldk, principally the Lua garbage collector could free this string, as it will not be needed any more by Lua.

Is there some simple and elegant way to tell to avoid this?

(of course I could also allocate some memory by c, and then copy the string to this allocated memory... but this sounds a bit weird for me as I am used to program such microcontroller application always in a very time- and RAM-optimized way - further I want to restrict the dynamic memory allocation exclusively to Lua - for "usual microcontroller" programming I would not use any dynamic memory allocation at all ... therefore it would be great if for the typical send time of some msec (could also be 200msec...) Lua garbage collector could somehow be "informed" that this string still is "in use")

(or should I better disable the Lua garbage collector during this time ... but this would sound also a bit weird to me, as it could me, that during some "file transfer" this sending will occur for longer time, and I would not like to block the lua garbage collector for "longer time").

... but for DMA it is important, that the Lua Garbage collector for sure NEITHER will free this string, NOR will re-allocate this string to some other place, until my C code signifies to Lua that the send is finished / the data is not used any more.