Here's an idea I've been thinking about for a while for a better (?) PTP <> script interface. Finally got around to working on it
The code is functional but basically at the proof of concept stage.
The basic idea is to let PTP talk to a running script, instead of just running snippets of lua.
Here's how it works:
The CHDK ptp code has two queues of "messages", one for PC->camera (input queue) and one for camera->PC (output queue)
A message is a sequence of bytes, size limited by available memory. From lua it is a string but lua strings are binary safe so it can be anything. The queues just store pointers to the messages.
No task synchronization is needed between the script task and the PTP task, because Lua only reads from the input queue and writes to the output queue, while PTP only does the reverse.
This is implemented with two new PTP commands WriteScriptMsg and ReadScriptMsg and two new lua functions write_usb_msg and read_usb_msg
PC sends WriteScriptMsg to add a message to the input queue. read_usb_msg fetches the message in lua
write_usb_msg adds a message to the output queue. ReadScriptMsg fetches the message on the PC
read*/write* return indications if the queue is empty or full, respectively.
Now a lua script can call read_usb_msg in a loop, and do something based on the content of the messages. This could be commands, or could be lua code. It can send output back with write_usb_msg
Plan is to make the lua functions optionally block with a timeout (like wait_click) but this isn't implemented yet.
Some benefits
- No need to stall PTP waiting for lua results. Long executing lua calls work be fine, as long as they sleep just like other lua scripts. The PC side can just poll until the response message(s) appear.
- you can return arbitrary data.
- You can maintain state between commands on the camera, unlike the current lua command which start from scratch every time.
- The need to expand the core protocol is reduced, because you can implement arbitrary protocols in lua
Other thoughts
- Taking full advantage of this will require a more flexible client than the current ptpcam. Something we need anyway.
- right now there is only one message channel. You can always send messages, even if there is nothing listening, and any script that starts later will see them if it reads. It would be possible to add some listen/connect/close semantics and have multiple channels, but I'm not sure if this is needed.
- it would be useful to be able to send data without going through a lua string, e.g. directly from a pointer
Attached files
chdk-ptpmsg-1.patch - patch against chdk code trunk
ptpcam-chdkde-ptpmsg-1.patch - patch against chdkde ptpcam
ptpmsg.lua - example script
example
ptpcam --chdk
upload ptpmsg.lua A/ptpmsg.lua
lua loadfile('A/ptpmsg.lua')()
putm ls A/
getm
exec return 1+1
getm