Hi All,
I have a token-passing protocol stack (C code) that need to run in background (over SAM7x uart1). Idea is -- using uLua I can encapsulate the objects (functions) from this protocol and interact with them via Lua script. So far I have tried a couple of approaches: 1) Create platform independent module for the protocol to access its services using three functions: proto.heartbeat, proto.setval abd proto.getval. proto.heartbeat, entry function into protocol's state-machine needs to be called every 5~10 mS, so that it can receive, process and pass tokens in timely fashion. To maxmize speed, I am using complied (.lc) bytecode of my script; which looks something like this: proto.setval(1,"RLY2") --turn on relay 2 while uart.getchar(1,0)=="" do --continue until knock on term... proto.heartbeat() if(proto.getval("SWT1")==1) then proto.setval(1,"RLY1") else proto.setval(0,"RLY1") end end Problem/ challenge here -- not sure how fast eLua interpreter/ VM gets invoked, but this doesn't allow token passing to happen in timely manner. RLY2 does get set to 1 (and relay clicks on) but but the one in the loop (RLY1) doesn't get serviced at all. Apparently because heartbeat must be getting called fast enough, causing token/s to be dropped. 2) If I call heartbeat() raw C/directly from main.c -- now proper token-passing behavior is restored. But now, I need to have a way to alternately pass control to eLua VM/ processor. Therefore this question -- if I had lua byte code (contents of .lc/ .luac file) loaded in local memory, how can I execute those chucks in-between calls to heartbeat? Please feel free to suggest any alternate solution/s, such as speeding up eLua invocation, perhaps that might allow me to use approach #1 above (by speeding up call frequency to proto.heartbeat). Any help, pointers will be greatly appreciated. P.S. I had great fun exploring and playing with eLua so far...My Sincere THANKS to all developers involved in bringing it to us. Excellent stuff!!! Thanks, Ash |
Thiago Naves |
Depending on your code, running the heartbeat call in a timer interrupt (in C, not Lua) might be an option. If the code is too long for an IRQ, you could create a hook in the Lua VM to call it.On Mon, Jun 3, 2013 at 10:46 PM, Ashu <[hidden email]> wrote: Hi All, _______________________________________________ eLua-dev mailing list [hidden email] https://lists.berlios.de/mailman/listinfo/elua-dev |
Thanks Thiago,
I am in the middle of trying out calling C code from timer IRQ handler. However, I would definitely like to explore the second suggestion - context switching between LuaVM and background task. How do I do that; is there any document or code that you can point me to? Also looking through eLua source code, to understand how lc bytecode loaded in memory can be executed in chunks. Feeding/ executing Lua chunks (not lc bytecode) is already being done from shell; if I can find the Lua function that can do the same to lc bytecode(?) That will solve my problem too! Alternately calling heartbeat and "lc chunk" vm interpreter functions from a tight while loop in main() Please advise. Thanks, Ash |
It sounds like you might want to look into the debug hooks for lua:
The eLua interrupt handlers (see elua_int.c: https://github.com/elua/elua/blob/master/src/elua_int.c) make use of this in order to get Lua-based interrupt handlers to execute periodically. It sets a count hook with lua_sethook which gets called every 2 bytecode instructions:
As it's set up, elua_int_hook is intended for only calling Lua handlers, but you could either set your own similar hook (if you're not going to use the eLua interrupts, since ) or extend elua_int_hook to include an option to execute periodic C handlers. You could also use the other periodicity of the hooks if you like: line, return or call.
As an aside: be careful about what you do in between VM instructions if you're going to be doing anything with Lua state. Hope that helps. Bogdan: if you have anything you want to chime in with, feel free.
On Tue, Jun 4, 2013 at 11:25 AM, Ashu <[hidden email]> wrote: Thanks Thiago, James Snyder Biomedical Engineering Northwestern University http://fanplastic.org/key.txt ph: (847) 448-0386 _______________________________________________ eLua-dev mailing list [hidden email] https://lists.berlios.de/mailman/listinfo/elua-dev |
Thiago Naves |
In reply to this post by Ashu
On Tue, Jun 4, 2013 at 1:25 PM, Ashu <[hidden email]> wrote: Thanks Thiago, There's nothing ready do be used for that in the eLua code (and I don't think there will be). That's usually a OS job (and we don't have one...). This leaves 2 choices: Grab the context switching functions for your platform from an OS (like FreeRTOS) or write your own. For writing your own, the ARM website has a lot of info on various arm architectures. There you can find which registers you need to save and what instructions do that. I would only go in this route as a last resort. As nether those options are simple. Also looking through eLua source code, to understand how lc bytecode loaded That or using the debug hooks, as James said, might be the solution. Best, Thiago Please advise. _______________________________________________ eLua-dev mailing list [hidden email] https://lists.berlios.de/mailman/listinfo/elua-dev |
In reply to this post by jbsnyder
Thanks for the pointers/ links.
On second part of my question -- lc byte-code loaded in memory, how can I execute it in chunks? If this use-case is supported in eLua; please point me to the hook function that I can feed lc byte- code chunks to. What I intend to do with that: switch/share execution control by alternately calling heartbeat and lc bytecode interpreter function (for chuck-at-a-time script execution) from a tight loop in main(). |
Thiago Naves |
The hook function is automatically called by the vm loop at regular intervals, so just call the heartbeat in the hook function and you don't need to worry about feeding the bytecode. As long as the Lua interpreter is running code, the hook function will be called, just make sure the Lua code has an infinite loop to keep it running or the hook will stop.I don't know how to feed chunks of bytecode to the vm... On Tue, Jun 4, 2013 at 3:57 PM, Ashu <[hidden email]> wrote: Thanks for the pointers/ links. _______________________________________________ eLua-dev mailing list [hidden email] https://lists.berlios.de/mailman/listinfo/elua-dev |
On Tue, Jun 4, 2013 at 3:33 PM, Thiago Naves <[hidden email]> wrote:
Yep, this is what I was intending when I sent that reply. Side note on the "if the VM stops, so do the hooks" front. There is some work on a branch that replaces the readline functionality to allow calling other things, including the eLua interrupt handler when nothing is being typed into the REPL. It's not yet ready to merge, but it would allow you to keep doing "background" operations when it's blocking on line input at the REPL.
I'll also admit that I'm not sure whether what is being asked for is practical to do. The code that handles reading in pre-compiled code to the Lua state is in lundump.c, with the public function for that being luaU_undump, which gets called when you do a lua_load and the chunk you provide is precompiled rather than source (otherwise it will parse & compile).
I'm not really sure how well it might work to feed bytecode through this to get it executed in the way that you're suggesting, since generally after you do a load you have to do a lua_pcall to execute it. So I believe you'd have to feed it a complete chunk (http://www.lua.org/manual/5.1/manual.html#2.4.1) before you'd be able to execute the constituent instructions.
You could field this type of question on the Lua list, since functionally eLua shouldn't differ much from how you might do this in Lua: http://www.lua.org/lua-l.html
James Snyder Biomedical Engineering Northwestern University http://fanplastic.org/key.txt ph: (847) 448-0386 _______________________________________________ eLua-dev mailing list [hidden email] https://lists.berlios.de/mailman/listinfo/elua-dev |
In reply to this post by Ashu
Hi,
On Tue, Jun 4, 2013 at 4:46 AM, Ashu <[hidden email]> wrote: Hi All, Interesting. The SAM7X isn't a particulary fast CPU, but still I would've expected your inner while loop to run at more than 100Hz (since you said that 'heartbeat' must be called at least every 10ms). Have you tried to see how long does it take between subsequent invocations of proto.hearbeat? The SAM7X backend has an implementation of the system timer, you can use it to measure this. Also, one thing you can do to gain speed is to "cache" as much as the table lookups in local variables. Something like this: local heartbeart, getval, setval = proto.heartbeat, proto.getval, proto.setval local getchar = uart.getchar while getchar(1,0) == "" do heartbeat() if(getval("SWT1")==1) then setval(1,"RLY1") else setval(0,"RLY1") end end Definitely worth trying. 2) If I call heartbeat() raw C/directly from main.c -- now proper This is quite a hard question. In theory, you can't simply execute arbitrary chunks of Lua code in the same instance (by which I mean the same Lua state) in which you're running your main Lua program by interrupting said program. The proper way would be to use Lua interrupt handlers, but if that's not fast enough for you, you definitely have a problem. But try it first.
Besides using local variables (as above), if you're not using floating point at all in your system, you could also try compiling your image with 'target=lualong'. I don't think there's much more you can do. Maybe modify the builder to switch the compiler flags from 'optimize for size' to 'optimize for speed', but you're most likely going to have a problem with this approach on the SAM7X if it's a part with 256K of flash. In fact, compilation on AT91SAM7X defaults to "thumb" mode in order to make the eLua firmware fit in 256k (which is yet another performance hit). If you have a 512k part, definitely change the compilation mode to ARM (cpumode=arm) and try to compile for speed (change '-Os,-fomit-frame-pointer' in build_elua.lua to '-O3'). Best, Bogdan
_______________________________________________ eLua-dev mailing list [hidden email] https://lists.berlios.de/mailman/listinfo/elua-dev |
Free forum by Nabble | Edit this page |