console.lua 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. --- 模块功能 luat控制台
  2. -- @module console
  3. -- @author 小强
  4. -- @license MIT
  5. -- @copyright openLuat.com
  6. -- @release 2017.9.15
  7. require"ril"
  8. module(..., package.seeall)
  9. local uart_id
  10. local console_task
  11. local function read_line()
  12. while true do
  13. local s = uart.read(uart_id, "*l")
  14. if s ~= "" then
  15. return s
  16. end
  17. coroutine.yield()
  18. end
  19. end
  20. local function write(s)
  21. uart.write(uart_id, s)
  22. end
  23. local function on_wait_event_timeout()
  24. coroutine.resume(console_task, "TIEMOUT")
  25. end
  26. local function wait_event(event, timeout)
  27. if timeout then
  28. sys.timer_start(on_wait_event_timeout, timeout)
  29. end
  30. while true do
  31. local receive_event = coroutine.yield()
  32. if receive_event == event then
  33. sys.timer_stop(on_wait_event_timeout)
  34. return
  35. elseif receive_event == "TIMEOUT" then
  36. write("WAIT EVENT " .. event .. "TIMEOUT\r\n")
  37. return
  38. end
  39. end
  40. end
  41. local function main_loop()
  42. local cache_data = ""
  43. local wait_event_flag
  44. -- 定义执行环境,命令行下输入的脚本的print重写到命令行的write
  45. local execute_env = {
  46. print = function(...)
  47. for i, v in ipairs(arg) do
  48. arg[i] = type(v) == "nil" and "nil" or tostring(v)
  49. end
  50. write(table.concat(arg, "\t"))
  51. write("\r\n")
  52. end,
  53. sendat = function(cmd, data)
  54. ril.request(cmd, data, function(cmd, success, response, intermediate)
  55. if intermediate then
  56. write("\r\n" .. intermediate .. "\r\n")
  57. end
  58. if response then
  59. write("\r\n" .. response .. "\r\n")
  60. end
  61. coroutine.resume(console_task, "WAIT_AT_RESPONSE")
  62. end, nil)
  63. wait_event_flag = "WAIT_AT_RESPONSE"
  64. end,
  65. }
  66. setmetatable(execute_env, { __index = _G })
  67. -- 输出提示语
  68. write("\r\nWelcome to Luat Console\r\n")
  69. write("\r\n> ")
  70. while true do
  71. -- 读取输入
  72. local new_data = read_line("*l")
  73. -- 输出回显
  74. write(new_data)
  75. -- 拼接之前未成行的剩余数据
  76. cache_data = cache_data .. new_data
  77. -- 去掉回车换行
  78. local line = string.match(cache_data, "(.+\r*\n)")
  79. if line then
  80. -- 收到一整行的数据 清除缓冲数据
  81. cache_data = ""
  82. -- 输出新行
  83. write("\n")
  84. -- 用xpcall执行用户输入的脚本,可以捕捉脚本的错误
  85. xpcall(function()
  86. -- 执行用户输入的脚本
  87. local f = loadstring(line)
  88. setfenv(f, execute_env)
  89. f()
  90. end,
  91. function() -- 错误输出
  92. write(debug.traceback())
  93. end)
  94. if wait_event_flag then
  95. wait_event(wait_event_flag, 3000)
  96. wait_event_flag = nil
  97. end
  98. -- 输出输入提示符
  99. write("\r\n> ")
  100. end
  101. end
  102. end
  103. --- console.setup
  104. -- @param id 串口id
  105. -- @param baudrate 串口波特率
  106. -- @return 无
  107. -- @usage console.setup(1, 115200)
  108. function setup(id, baudrate)
  109. -- 默认串口1
  110. uart_id = id or 1
  111. -- 默认波特率115200
  112. baudrate = baudrate or 115200
  113. -- 创建console处理的协程
  114. console_task = coroutine.create(main_loop)
  115. -- 初始化串口
  116. uart.setup(uart_id, baudrate, 8, uart.PAR_NONE, uart.STOP_1)
  117. -- 串口收到数据时唤醒console协程
  118. uart.on(uart_id, "receive", function()
  119. coroutine.resume(console_task)
  120. end)
  121. coroutine.resume(console_task)
  122. end