Running C task concurrently (in background) with eLua

classic Classic list List threaded Threaded
9 messages Options
Ashu Ashu
Reply | Threaded
Open this post in threaded view
|

Running C task concurrently (in background) with eLua

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 Thiago Naves
Reply | Threaded
Open this post in threaded view
|

Re: Running C task concurrently (in background) with eLua

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.

Not sure about the executing the .lc in chunks though. An option for that might be context changing. You could create a main task for your backend code and another one for the Lua VM. The main task would do it's job then change to the Lua task, that one would change back after a while (or a timer IRQ or whatever). This probably is not worth the effort...

Best,
Thiago




On Mon, Jun 3, 2013 at 10:46 PM, Ashu <[hidden email]> wrote:
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




--
View this message in context: http://elua-development.2368040.n2.nabble.com/Running-C-task-concurrently-in-background-with-eLua-tp7578047.html
Sent from the eLua Development mailing list archive at Nabble.com.
_______________________________________________
eLua-dev mailing list
[hidden email]
https://lists.berlios.de/mailman/listinfo/elua-dev


_______________________________________________
eLua-dev mailing list
[hidden email]
https://lists.berlios.de/mailman/listinfo/elua-dev
Ashu Ashu
Reply | Threaded
Open this post in threaded view
|

Re: Running C task concurrently (in background) with eLua

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
jbsnyder jbsnyder
Reply | Threaded
Open this post in threaded view
|

Re: Running C task concurrently (in background) with eLua

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,

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




--
View this message in context: http://elua-development.2368040.n2.nabble.com/Running-C-task-concurrently-in-background-with-eLua-tp7578047p7578052.html
Sent from the eLua Development mailing list archive at Nabble.com.
_______________________________________________
eLua-dev mailing list
[hidden email]
https://lists.berlios.de/mailman/listinfo/elua-dev



--
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 Thiago Naves
Reply | Threaded
Open this post in threaded view
|

Re: Running C task concurrently (in background) with eLua

In reply to this post by Ashu



On Tue, Jun 4, 2013 at 1:25 PM, Ashu <[hidden email]> wrote:
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?

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
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()


That or using the debug hooks, as James said, might be the solution.

Best,
Thiago

 
Please advise.

Thanks,
Ash




--
View this message in context: http://elua-development.2368040.n2.nabble.com/Running-C-task-concurrently-in-background-with-eLua-tp7578047p7578052.html
Sent from the eLua Development mailing list archive at Nabble.com.
_______________________________________________
eLua-dev mailing list
[hidden email]
https://lists.berlios.de/mailman/listinfo/elua-dev


_______________________________________________
eLua-dev mailing list
[hidden email]
https://lists.berlios.de/mailman/listinfo/elua-dev
Ashu Ashu
Reply | Threaded
Open this post in threaded view
|

Re: Running C task concurrently (in background) with eLua

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 Thiago Naves
Reply | Threaded
Open this post in threaded view
|

Re: Running C task concurrently (in background) with eLua

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.
This should have the same alternating effect you described.

I don't know how to feed chunks of bytecode to the vm...

Best,
Thiago



On Tue, Jun 4, 2013 at 3:57 PM, Ashu <[hidden email]> wrote:
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().




--
View this message in context: http://elua-development.2368040.n2.nabble.com/Running-C-task-concurrently-in-background-with-eLua-tp7578047p7578055.html
Sent from the eLua Development mailing list archive at Nabble.com.
_______________________________________________
eLua-dev mailing list
[hidden email]
https://lists.berlios.de/mailman/listinfo/elua-dev


_______________________________________________
eLua-dev mailing list
[hidden email]
https://lists.berlios.de/mailman/listinfo/elua-dev
jbsnyder jbsnyder
Reply | Threaded
Open this post in threaded view
|

Re: Running C task concurrently (in background) with eLua




On Tue, Jun 4, 2013 at 3:33 PM, Thiago Naves <[hidden email]> wrote:
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.
This should have the same alternating effect you described.

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 don't know how to feed chunks of bytecode to the vm...

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
 

Best,
Thiago



On Tue, Jun 4, 2013 at 3:57 PM, Ashu <[hidden email]> wrote:
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().




--
View this message in context: http://elua-development.2368040.n2.nabble.com/Running-C-task-concurrently-in-background-with-eLua-tp7578047p7578055.html
Sent from the eLua Development mailing list archive at Nabble.com.
_______________________________________________
eLua-dev mailing list
[hidden email]
https://lists.berlios.de/mailman/listinfo/elua-dev


_______________________________________________
eLua-dev mailing list
[hidden email]
https://lists.berlios.de/mailman/listinfo/elua-dev



--
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
BogdanM BogdanM
Reply | Threaded
Open this post in threaded view
|

Re: Running C task concurrently (in background) with eLua

In reply to this post by Ashu
Hi,


On Tue, Jun 4, 2013 at 4:46 AM, Ashu <[hidden email]> wrote:
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.

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
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?

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.
 

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).

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
 

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




--
View this message in context: http://elua-development.2368040.n2.nabble.com/Running-C-task-concurrently-in-background-with-eLua-tp7578047.html
Sent from the eLua Development mailing list archive at Nabble.com.
_______________________________________________
eLua-dev mailing list
[hidden email]
https://lists.berlios.de/mailman/listinfo/elua-dev


_______________________________________________
eLua-dev mailing list
[hidden email]
https://lists.berlios.de/mailman/listinfo/elua-dev