console.lua 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  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. local arg = { ... }
  49. for i, v in ipairs(arg) do
  50. arg[i] = type(v) == "nil" and "nil" or tostring(v)
  51. end
  52. write(table.concat(arg, "\t"))
  53. write("\r\n")
  54. end,
  55. sendat = function(cmd, data)
  56. ril.request(cmd, data, function(cmd, success, response, intermediate)
  57. if intermediate then
  58. write("\r\n" .. intermediate .. "\r\n")
  59. end
  60. if response then
  61. write("\r\n" .. response .. "\r\n")
  62. end
  63. coroutine.resume(console_task, "WAIT_AT_RESPONSE")
  64. end, nil)
  65. wait_event_flag = "WAIT_AT_RESPONSE"
  66. end,
  67. }
  68. setmetatable(execute_env, { __index = _G })
  69. -- 输出提示语
  70. write("\r\nWelcome to Luat Console\r\n")
  71. write("\r\n> ")
  72. while true do
  73. -- 读取输入
  74. local new_data = read_line("*l")
  75. -- 输出回显
  76. write(new_data)
  77. -- 拼接之前未成行的剩余数据
  78. cache_data = cache_data .. new_data
  79. -- 去掉回车换行
  80. local line = string.match(cache_data, "(.-)\r?\n")
  81. if line then
  82. -- 收到一整行的数据 清除缓冲数据
  83. cache_data = ""
  84. -- 输出新行
  85. write("\n")
  86. -- 用xpcall执行用户输入的脚本,可以捕捉脚本的错误
  87. xpcall(function()
  88. -- 执行用户输入的脚本
  89. local f = assert(loadstring(line.." "))
  90. setfenv(f, execute_env)
  91. f()
  92. end,
  93. function(err) -- 错误输出
  94. write(err .. '\r\n')
  95. write(debug.traceback())
  96. end)
  97. if wait_event_flag then
  98. wait_event(wait_event_flag, 3000)
  99. wait_event_flag = nil
  100. end
  101. -- 输出输入提示符
  102. write("\r\n> ")
  103. end
  104. end
  105. end
  106. --- 配置控制台使用的串口参数,创建控制台协程
  107. -- @number id 控制台使用的串口ID:1表示串口1,2表示串口2
  108. -- @number[opt=115200] baudrate 控制台使用的串口波特率
  109. -- 支持1200,2400,4800,9600,10400,14400,19200,28800,38400,57600,76800,115200,230400,460800,576000,921600,1152000,4000000
  110. -- @return nil
  111. -- @usage console.setup(1, 115200)
  112. function setup(id, baudrate)
  113. -- 默认串口1
  114. uart_id = id or 1
  115. -- 默认波特率115200
  116. baudrate = baudrate or 115200
  117. -- 创建console处理的协程
  118. console_task = coroutine.create(main_loop)
  119. -- 初始化串口
  120. uart.setup(uart_id, baudrate, 8, uart.PAR_NONE, uart.STOP_1)
  121. -- 串口收到数据时唤醒console协程
  122. uart.on(uart_id, "receive", function()
  123. coroutine.resume(console_task)
  124. end)
  125. coroutine.resume(console_task)
  126. end