I noticed a little bug regarding uart.on function, here's a code snippet demonstrating it
local function func(data)
print(coroutine.status(active_thread))
if data:find("stop") then
print(coroutine.resume(active_thread))
end
end
-- helper to successfuly restore the first thread
local function uart_helper()
uart.on("data", "\r", func, 1)
end
-- function that can resume
local function good_function()
local helper_thread = coroutine.create(uart_helper)
coroutine.resume(helper_thread)
coroutine.yield()
print("this is good_function and i'm going back to main_thread")
coroutine.resume(main_thread)
end
-- broken function which will report that it is already alive when attempted to resume
local function broken_function()
uart.on("data", "\r", func, 1)
coroutine.yield()
print("this is broken_function and i'm going back to main_thread")
coroutine.resume(main_thread)
end
function main()
first_thread = coroutine.create(good_function)
second_thread = coroutine.create(broken_function)
active_thread = first_thread
print("i'm starting the first_thread using good_function")
coroutine.resume(first_thread)
coroutine.yield()
print("im back from first_thread using good_function")
active_thread = second_thread
print("i'm starting the second_thread using broken_function")
coroutine.resume(second_thread)
coroutine.yield()
print("i'm back from second_thread using broken_function")
end
main_thread = coroutine.create(main)
return main_thread
this starts two threads, one wraps the uart.on function in another (third) thread, the other calls it in itself. On uart event, the callback function (func) prints out the coroutine.status of the currently active thread and if the user wrote "stop" in the interpreter it resumes the thread and returns back to main thread. The interesting part is that the uart.on function misrepresents the status of the second thread as it reports it to be "running" on every uart event, and thus fails to resume it:
> =stop
running
false cannot resume running coroutine
whereas if you ask the interpreter it will report "suspended"
> =coroutine.status(active_thread)
running -- response from uart.on callback
suspended -- response from interpreter
here's the entire serial input/output
> coroutine.resume(dofile("test.lua"))
i'm starting the first_thread using good_function
> =
suspended
> =
suspended
> =coroutine.status(active_thread)
suspended
suspended
> =stop
suspended
this is good_function and i'm going back to main_thread
im back from first_thread using good_function
i'm starting the second_thread using broken_function
true
nil
> =
running
> =
running
> =coroutine.status(active_thread)
running
suspended
> =
running
> =stop
running
false cannot resume running coroutine
nil
> =coroutine.resume(active_thread)
running
this is broken_function and i'm going back to main_thread
i'm back from second_thread using broken_function
true
> =
running
> =
running
> =coroutine.status(active_thread)
running
dead
>
The lines prefixed by prompt, >, are user input.
The version of the firmware is nodemcu_integer_0.9.6-dev_20150704
I suspect that other event driven functions, such as conn:on, might behave similarly, but I haven't tested it yet.