console.lua 4.0 KB

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