patch.lua 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. --- 模块功能:Lua补丁
  2. -- @module patch
  3. -- @author openLuat
  4. -- @license MIT
  5. -- @copyright openLuat
  6. -- @release 2017.10.21
  7. require"pm"
  8. module(..., package.seeall)
  9. --[[
  10. 模块名称:Lua自带接口补丁
  11. 模块功能:补丁某些Lua自带的接口,规避调用异常时死机
  12. 模块最后修改时间:2017.02.14
  13. ]]
  14. --保存Lua自带的os.time接口
  15. local oldostime = os.time
  16. --[[
  17. 函数名:safeostime
  18. 功能 :封装自定义的os.time接口
  19. 参数 :
  20. t:日期表,如果没有传入,使用系统当前时间
  21. 返回值:t时间距离1970年1月1日0时0分0秒所经过的秒数
  22. ]]
  23. function safeostime(t)
  24. return oldostime(t) or 0
  25. end
  26. --Lua自带的os.time接口指向自定义的safeostime接口
  27. os.time = safeostime
  28. --保存Lua自带的os.date接口
  29. local oldosdate = os.date
  30. --[[
  31. 函数名:safeosdate
  32. 功能 :封装自定义的os.date接口
  33. 参数 :
  34. s:输出格式
  35. t:距离1970年1月1日0时0分0秒所经过的秒数
  36. 返回值:参考Lua自带的os.date接口说明
  37. ]]
  38. function safeosdate(s, t)
  39. if s == "*t" then
  40. return oldosdate(s, t) or {year = 2012,
  41. month = 12,
  42. day = 11,
  43. hour = 10,
  44. min = 9,
  45. sec = 0}
  46. else
  47. return oldosdate(s, t)
  48. end
  49. end
  50. --Lua自带的os.date接口指向自定义的safeosdate接口
  51. os.date = safeosdate
  52. -- 对coroutine.resume加一个修饰器用于捕获协程错误
  53. local rawcoresume = coroutine.resume
  54. coroutine.resume = function(...)
  55. local arg = { ... }
  56. function wrapper(co,...)
  57. local arg = { ... }
  58. if not arg[1] then
  59. local traceBack = debug.traceback(co) or "empty"
  60. traceBack = (traceBack and traceBack~="") and ((arg[2] or "").."\r\n"..traceBack) or (arg[2] or "")
  61. log.error("coroutine.resume",traceBack)
  62. if errDump and type(errDump.appendErr)=="function" then
  63. errDump.appendErr(traceBack)
  64. end
  65. if _G.COROUTINE_ERROR_RESTART then rtos.restart() end
  66. end
  67. return unpack(arg)
  68. end
  69. return wrapper(arg[1],rawcoresume(...))
  70. end
  71. os.clockms = function() return rtos.tick()/16 end
  72. --保存Lua自带的json.decode接口
  73. if json and json.decode then oldjsondecode = json.decode end
  74. --- 封装自定义的json.decode接口
  75. -- @string s json格式的字符串
  76. -- @return table,第一个返回值为解析json字符串后的table
  77. -- @return boole,第二个返回值为解析结果(true表示成功,false失败)
  78. -- @return string,第三个返回值可选(只有第二个返回值为false时,才有意义),表示出错信息
  79. local function safeJsonDecode(s)
  80. local result, info = pcall(oldjsondecode, s)
  81. if result then
  82. return info, true
  83. else
  84. return {}, false, info
  85. end
  86. end
  87. --Lua自带的json.decode接口指向自定义的safeJsonDecode接口
  88. if json and json.decode then json.decode = safeJsonDecode end
  89. local oldUartWrite = uart.write
  90. uart.write = function(...)
  91. pm.wake("lib.patch.uart.write")
  92. local result = oldUartWrite(...)
  93. pm.sleep("lib.patch.uart.write")
  94. return result
  95. end
  96. if i2c and i2c.write then
  97. local oldI2cWrite = i2c.write
  98. i2c.write = function(...)
  99. pm.wake("lib.patch.i2c.write")
  100. local result = oldI2cWrite(...)
  101. pm.sleep("lib.patch.i2c.write")
  102. return result
  103. end
  104. end
  105. if i2c and i2c.send then
  106. local oldI2cSend = i2c.send
  107. i2c.send = function(...)
  108. pm.wake("lib.patch.i2c.send")
  109. local result = oldI2cSend(...)
  110. pm.sleep("lib.patch.i2c.send")
  111. return result
  112. end
  113. end
  114. if spi and spi.send then
  115. oldSpiSend = spi.send
  116. spi.send = function(...)
  117. pm.wake("lib.patch.spi.send")
  118. local result = oldSpiSend(...)
  119. pm.sleep("lib.patch.spi.send")
  120. return result
  121. end
  122. end
  123. if spi and spi.send_recv then
  124. oldSpiSendRecv = spi.send_recv
  125. spi.send_recv = function(...)
  126. pm.wake("lib.patch.spi.send_recv")
  127. local result = oldSpiSendRecv(...)
  128. pm.sleep("lib.patch.spi.send_recv")
  129. return result
  130. end
  131. end
  132. if disp and disp.sleep then
  133. oldDispSleep = disp.sleep
  134. disp.sleep = function(...)
  135. pm.wake("lib.patch.disp.sleep")
  136. oldDispSleep(...)
  137. pm.sleep("lib.patch.disp.sleep")
  138. end
  139. end
  140. if io and io.mount then
  141. oldIoMount = io.mount
  142. io.mount = function (...)
  143. pm.wake("lib.patch.io.mount")
  144. local result = oldIoMount(...)
  145. pm.sleep("lib.patch.io.mount")
  146. return result
  147. end
  148. end
  149. local pmdInited
  150. if pmd and pmd.init then
  151. oldPmdInit = pmd.init
  152. pmd.init = function (...)
  153. if not pmdInited then pmdInited = true end
  154. local result = oldPmdInit(...)
  155. return result
  156. end
  157. end
  158. pmd.libScriptInit = function()
  159. if not pmdInited then pmd.init({}) end
  160. end