uartTask.lua 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756
  1. --- 模块功能:串口1功能测试
  2. -- @author openLuat
  3. -- @module uart.uartTask
  4. -- @license MIT
  5. -- @copyright openLuat
  6. -- @release 2018.03.27
  7. module(...,package.seeall)
  8. require "utils"
  9. require "pm"
  10. require "sys"
  11. require "log"
  12. require "nvm"
  13. require "funlib"
  14. --[[
  15. 功能定义:
  16. uart按照帧结构接收外围设备的输入,收到正确的指令后,回复ASCII字符串
  17. 帧结构如下:
  18. 帧头:1字节,0x01表示扫描指令,0x02表示控制GPIO命令,0x03表示控制端口命令
  19. 帧体:字节不固定,跟帧头有关
  20. 帧尾:1字节,固定为0xC0
  21. 收到的指令帧头为0x01时,回复"CMD_SCANNER\r\n"给外围设备;例如接收到0x01 0xC0两个字节,就回复"CMD_SCANNER\r\n"
  22. 收到的指令帧头为0x02时,回复"CMD_GPIO\r\n"给外围设备;例如接收到0x02 0xC0两个字节,就回复"CMD_GPIO\r\n"
  23. 收到的指令帧头为0x03时,回复"CMD_PORT\r\n"给外围设备;例如接收到0x03 0xC0两个字节,就回复"CMD_PORT\r\n"
  24. 收到的指令帧头为其余数据时,回复"CMD_ERROR\r\n"给外围设备;例如接收到0x04 0xC0两个字节,就回复"CMD_ERROR\r\n"
  25. ]]
  26. --串口ID,1对应uart1
  27. --如果要修改为uart2,把UART_ID赋值为2即可
  28. -- air720UH 可用串口1和2,rfid串口用1
  29. -- air724UH 可用串口1、2、3,rfid串口用3
  30. local UART_ID = nvm.get("rfidUartId")
  31. local UART_ID_BAUD_RATE = nvm.get("rfidUartBaudRate")
  32. --local UART_ID = 3
  33. --帧头以及帧尾
  34. local FRM_HEAD,FRM_TAIL = 0xaa55,0x0d0a
  35. --rfid 上报间隔
  36. local rfidReportIntervalRlian = nvm.get("rfidReportIntervalRlian") or 60
  37. --rfid 数据包缓存最大标签个数
  38. local rfidBufferMaxCountRlian = nvm.get("rfidBufferMaxCountRlian") or 50
  39. --rfid 是否开启节流模式
  40. local rfidEnableThrottleRlian = nvm.get("rfidEnableThrottleRlian") or true
  41. --rfid 离线时间阀值
  42. local rfidOfflineTimeoutRlian = nvm.get("rfidOfflineTimeoutRlian") or 5
  43. local rfidType = nvm.get("rfidType")
  44. --rfid 离线检测定时器
  45. local rfidOfflineCheckTimerIds = {}
  46. --在线的rifd
  47. local onlineRfids = {["count"]=0,["buf"]={}}
  48. local onlineRfidsMaxCount = 1000
  49. --已上报的rifd
  50. local reportRfids = {}
  51. --串口读到的数据缓冲区
  52. local rdbuf = ""
  53. --rfid 串口初始化定参数时器
  54. local rfid_uart_config_init_timer_id = nil
  55. local timerSyncResult = false
  56. --是否厂测读rfid标签模式
  57. local isFactoryTestReadRfidMode = false
  58. --厂测模式读rifd号
  59. local factoryTestReadRfid = ""
  60. local isCmdReadRfidMode = false
  61. local cmdReadRfid = ""
  62. require "misc"
  63. local function getTime()
  64. local tm = misc.getClock()
  65. return string.format("%04d/%02d/%02d,%02d:%02d:%02d", tm.year, tm.month, tm.day, tm.hour, tm.min, tm.sec)
  66. end
  67. --初始化rfid缓冲池
  68. local start_time = os.time()
  69. local rfids_buf = {["start_time"]=start_time,["rfid_count"]=0,["buf"]={}}
  70. --require "HashMap"
  71. --local rfid_map = HashMap:new()
  72. --任联rfid数据解析
  73. local function parse_rfid_renlian(body)
  74. if not body then return false end
  75. if body:len() ~= 9 then
  76. log.info("parse_rfid_renlian fail,body.length != 9")
  77. return false
  78. end
  79. local id = string.sub(body,1,6):toHex()
  80. local type = tonumber(string.byte(body,7))
  81. local status = tonumber(string.byte(body,8))
  82. local rssi = tonumber(string.byte(body,9))
  83. local rfid = {["id"]=id,["type"]=type,["status"]=status,["rssi"]=rssi}
  84. return rfid
  85. end
  86. --任联rfid数据解析
  87. local function parse_rfid_tiandiren(body)
  88. if not body then return false end
  89. if body:len() ~= 18 then
  90. log.info("parse_rfid_tiandiren fail,body.length != 18")
  91. return false
  92. end
  93. local id = string.sub(body,5,8):toHex()
  94. if not id then
  95. log.info("parse_rfid_tiandiren fail,id empty! body:",body:toHex())
  96. return false
  97. end
  98. local sn = string.byte(body,2)
  99. local dev_type = string.byte(body,3)*16 + string.byte(body,4)
  100. local cmd_type = string.byte(body,9)
  101. local crc = string.byte(body,15) + string.byte(body,16) * 16
  102. local content = string.sub(body,10,14):toHex()
  103. local status = string.byte(body,17)
  104. local rssi = string.byte(body,18)
  105. --local rfid = {["id"]=id,["cmd_type"]=cmd_type,["dev_type"]=dev_type,["sn"]=sn}
  106. local rfid = {["id"]=id,["type"]=cmd_type,["status"]=status,["rssi"]=rssi,["dev_type"]=dev_type,["sn"]=sn,["content"]=content}
  107. return rfid
  108. end
  109. --[[
  110. 函数名:parse_renlian
  111. 功能 :按照帧结构解析处理一条完整的帧数据
  112. 参数 :
  113. data:所有未处理的数据
  114. 返回值:第一个返回值是一条完整帧报文的处理结果,第二个返回值是未处理的数据
  115. ]]
  116. local function parse_renlian(data)
  117. --log.info("uartTask.parse_renlian", data:toHex())
  118. if not data then return end
  119. if data:len() < 14 then
  120. return false, data
  121. end
  122. local frm_head = tonumber(string.format( "%02x",string.byte(data,1)) .. string.format( "%02x",string.byte(data,2)),16)
  123. local tail = string.find(data,string.char(0x0d)..string.char(0x0a))
  124. if not tail then
  125. log.error("uartTask.parse_renlian", "end char:0x0d0a not found,wait for more ... ", data:toHex())
  126. return false,data
  127. end
  128. if frm_head ~= FRM_HEAD then
  129. --log.error("FRM_HEAD ERROR,drop it, frm_head = ", frm_head, ", FRM_HEAD = ", FRM_HEAD, data:toHex(), "unproc:", string.sub(data,tail+2,-1):toHex())
  130. return false,string.sub(data,tail+2,-1)
  131. end
  132. local frm_len = tonumber(string.byte(data,3))
  133. local body,result = string.sub(data,4,tail-1)
  134. --检测body完整性
  135. if (frm_len-2) ~= body:len() then
  136. log.error("uartTask.parse_renlian", "frm body length error, frm_len-2 = ",frm_len-2,", body:len() = ", body:len(), ", body:toHex() = ", body:toHex())
  137. return false,string.sub(data,tail+2,-1)
  138. end
  139. --log.info("uart1Task.parse",data:toHex(),frm_head,body:toHex())
  140. --解析rfid
  141. local rfid_info = parse_rfid_renlian(body)
  142. if not rfid_info then
  143. log.error("uartTask.parse_renlian", "parse_rfid_renlian() failed!")
  144. return false,string.sub(data,tail+2,-1)
  145. end
  146. local rfidRssiFilterVal = nvm.get("rfidRssiFilterVal") or 999
  147. if rfidRssiFilterVal > 0 and rfid_info.rssi > rfidRssiFilterVal then
  148. log.info("uartTask.parse_renlian", "rfid_info.rssi > ".. rfidRssiFilterVal..", drop it! rfid_info.rssi =", rfid_info.rssi, "rfid:",rfid_info.id)
  149. return false,string.sub(data,tail+2,-1)
  150. end
  151. --进入厂测读rfid标签信号模式
  152. if isFactoryTestReadRfidMode then
  153. --读到rfid标签信号后,退出厂测模式
  154. if factoryTestReadRfid == rfid_info.id then
  155. sys.publish("factory_test_read_rfid_success",{rssi=rfid_info.rssi,rfid=rfid_info.id})
  156. isFactoryTestMode = false
  157. factoryTestReadRfid = ""
  158. end
  159. return true,string.sub(data,tail+2,-1)
  160. end
  161. --进入指令读rfid标签信号模式
  162. if isCmdReadRfidMode then
  163. --读到rfid标签信号后,退出读标签模式
  164. if cmdReadRfid == rfid_info.id then
  165. log.info("uartTask.parse_renlian", "rfid_info:", json.encode(rfid_info))
  166. sys.publish("cmd_read_rfid_success",{rssi=rfid_info.rssi,rfid=rfid_info.id})
  167. isCmdReadRfidMode = false
  168. cmdReadRfid = ""
  169. end
  170. return true,string.sub(data,tail+2,-1)
  171. end
  172. local cur_time = os.time()
  173. --开启节流模式时(报警状态的标签不节流)
  174. if rfidEnableThrottleRlian == 1 and rfid_info.status ~= 0x5a then
  175. if rfid_info.id:len() ~= 12 then
  176. log.error("uartTask.parse_renlian","error,rfid length ~= 12!! rfid:",rfid_info.id)
  177. return true,string.sub(data,tail+2,-1)
  178. end
  179. local rfidPrefix = rfid_info.id:sub(1,6)
  180. local rfidSn = rfid_info.id:sub(7,12)
  181. if onlineRfids["count"] >= onlineRfidsMaxCount and not onlineRfids["buf"][rfidPrefix] or (onlineRfids["buf"][rfidPrefix] and not onlineRfids["buf"][rfidPrefix][rfidSn]) then
  182. if rfid_info.id == "0000CC8C8DF7" or rfid_info.id == "0000CC8C8DF8" then
  183. log.info("uartTask.parse_renlian","onlineRfids.count >= ", onlineRfidsMaxCount, " , drop parse!", rfid_info.id)
  184. end
  185. return true,string.sub(data,tail+2,-1)
  186. end
  187. if not onlineRfids["buf"][rfidPrefix] then
  188. onlineRfids["buf"][rfidPrefix] = {}
  189. onlineRfids["count"] = onlineRfids["count"] + 1
  190. onlineRfids["buf"][rfidPrefix][rfidSn] = cur_time
  191. elseif onlineRfids["buf"][rfidPrefix] and not onlineRfids["buf"][rfidPrefix][rfidSn] then
  192. onlineRfids["count"] = onlineRfids["count"] + 1
  193. onlineRfids["buf"][rfidPrefix][rfidSn] = cur_time
  194. else
  195. onlineRfids["buf"][rfidPrefix][rfidSn] = cur_time
  196. end
  197. if rfid_info.id == "0000CC8C8DF7" or rfid_info.id == "0000CC8C8DF8" then
  198. log.info("uartTask.parse_renlian", "rfid:", rfid_info.id, "online time:", cur_time)
  199. end
  200. --log.info("uartTask.parse_renlian",onlineRfids["count"],rfid_info.id)
  201. --已上报一次的跳过
  202. if reportRfids[rfidPrefix] and reportRfids[rfidPrefix][rfidSn] then
  203. if rfid_info.id == "0000CC8C8DF7" or rfid_info.id == "0000CC8C8DF8" then
  204. log.info("uartTask.parse_renlian", "enable Throttle, skip! rfid:", rfid_info.id)
  205. end
  206. return true,string.sub(data,tail+2,-1)
  207. end
  208. end
  209. --检测到超时时,发布数据并重置 rfids_buf
  210. if (cur_time - rfids_buf.start_time >= rfidReportIntervalRlian) or (rfids_buf.rfid_count >= rfidBufferMaxCountRlian) then
  211. if rfids_buf.rfid_count > 0 then
  212. --log.info("uartTask.parse_renlian", ">>>>>>> uart1Task.parse pub_packet_data", cur_time)
  213. sys.publish("pub_packet_data_renlian", rfids_buf)
  214. end
  215. rfids_buf = {["start_time"]=cur_time,["rfid_count"]=0,["buf"]={}}
  216. end
  217. --新增数据
  218. if not rfids_buf["buf"][rfid_info.id] then
  219. --log.info("uartTask.parse_renlian", ">>>>>>> push rfid to buf,rfid:", rfid_info.id)
  220. rfids_buf.rfid_count = rfids_buf.rfid_count + 1
  221. rfids_buf["buf"][rfid_info.id] = {["time"]=cur_time,["recv_count"]=1,["rssi"]=rfid_info.rssi,["type"]=rfid_info.type,["status"]=rfid_info.status}
  222. return true,string.sub(data,tail+2,-1)
  223. end
  224. --更新数据
  225. local recv_count = rfids_buf["buf"][rfid_info.id]["recv_count"] + 1
  226. rfids_buf["buf"][rfid_info.id] = {["time"]=cur_time,["recv_count"]=recv_count,["rssi"]=rfid_info.rssi,["type"]=rfid_info.type,["status"]=rfid_info.status}
  227. --log.info("uartTask.parse_renlian", ">>>>>>> update rfid_buf,rfid:", rfid_info.id, ", recv_count:", recv_count)
  228. return true,string.sub(data,tail+2,-1)
  229. end
  230. --[[
  231. 函数名:parse_tiandiren
  232. 功能 :按照帧结构解析处理一条完整的帧数据
  233. 参数 :
  234. data:所有未处理的数据
  235. 返回值:第一个返回值是一条完整帧报文的处理结果,第二个返回值是未处理的数据
  236. ]]
  237. local function parse_tiandiren(data)
  238. if not data then return end
  239. if data:len() < 20 then
  240. return false, data
  241. end
  242. local frm_head = tonumber(string.format( "%02x",string.byte(data,1)) .. string.format( "%02x",string.byte(data,2)),16)
  243. local tail = string.find(data,string.char(0x0d)..string.char(0x0a))
  244. if not tail then
  245. log.info("end char:0x0d0a not found,wait for more ... ", data:toHex())
  246. return false,data
  247. end
  248. if frm_head ~= FRM_HEAD then
  249. log.info("FRM_HEAD ERROR,drop it, frm_head = ", frm_head, ", FRM_HEAD = ", FRM_HEAD)
  250. return false,string.sub(data,tail+2,-1)
  251. end
  252. local frm_len = tonumber(string.byte(data,3))
  253. local body,result = string.sub(data,4,tail-1)
  254. --检测body完整性
  255. if (frm_len-2) ~= body:len() then
  256. log.info("frm body length error, frm_len-2 = ",frm_len-2,", body:len() = ", body:len(), ", body:toHex() = ", body:toHex())
  257. return false,string.sub(data,tail+2,-1)
  258. end
  259. --log.info("uart1Task.parse",data:toHex(),frm_head,body:toHex())
  260. --解析rfid
  261. local rfid_info = parse_rfid_tiandiren(body)
  262. if not rfid_info then
  263. log.info("parse_rfid_tiandiren() failed!")
  264. return false,string.sub(data,tail+2,-1)
  265. end
  266. --检测到超时时,发布数据并重置 rfids_buf
  267. local cur_time = os.time()
  268. if (cur_time - rfids_buf.start_time >= rfidReportIntervalRlian) or (rfids_buf.rfid_count >= rfidBufferMaxCountRlian) then
  269. if rfids_buf.rfid_count > 0 then
  270. --log.info(">>>>>>> uart1Task.parse pub_packet_data", cur_time)
  271. sys.publish("pub_packet_data_tiandiren", rfids_buf)
  272. --sys.publish("pub_packet_data_renlian", rfids_buf)
  273. end
  274. rfids_buf = {["start_time"]=cur_time,["rfid_count"]=0,["buf"]={}}
  275. end
  276. --新增数据
  277. if not rfids_buf["buf"][rfid_info.id] then
  278. --log.info(">>>>>>> push rfid to buf,rfid:", rfid_info.id)
  279. rfids_buf.rfid_count = rfids_buf.rfid_count + 1
  280. --rfids_buf["buf"][rfid_info.id] = {["time"]=cur_time,["recv_count"]=1,["dev_type"]=rfid_info.dev_type,["msg_type"]=rfid_info.msg_type,["sn"]=rfid_info.sn}
  281. rfids_buf["buf"][rfid_info.id] = {["time"]=cur_time,["recv_count"]=1,["rssi"]=rfid_info.rssi,["type"]=rfid_info.type,["status"]=rfid_info.status,["dev_type"]=rfid_info.dev_type,["sn"]=rfid_info.sn,["content"]=content}
  282. return true,string.sub(data,tail+2,-1)
  283. end
  284. --更新数据
  285. local recv_count = rfids_buf["buf"][rfid_info.id]["recv_count"] + 1
  286. --rfids_buf["buf"][rfid_info.id] = {["time"]=cur_time,["recv_count"]=recv_count,["dev_type"]=rfid_info.dev_type,["msg_type"]=rfid_info.msg_type,["sn"]=rfid_info.sn}
  287. rfids_buf["buf"][rfid_info.id] = {["time"]=cur_time,["recv_count"]=recv_count,["rssi"]=rfid_info.rssi,["type"]=rfid_info.type,["status"]=rfid_info.status,["dev_type"]=rfid_info.dev_type,["sn"]=rfid_info.sn,["content"]=content}
  288. --log.info(">>>>>>> update rfid_buf,rfid:", rfid_info.id, ", recv_count:", recv_count)
  289. return true,string.sub(data,tail+2,-1)
  290. end
  291. --[[
  292. 函数名:proc
  293. 功能 :处理从串口读到的数据
  294. 参数 :
  295. data:当前一次从串口读到的数据
  296. 返回值:无
  297. ]]
  298. local function proc(data)
  299. if not data or string.len(data) == 0 then return end
  300. if not rfidType then
  301. log.info("uartTask.proc","rfidType undefined!!")
  302. rfidType = nvm.get("rfidType")
  303. return false
  304. end
  305. --追加到缓冲区
  306. rdbuf = rdbuf..data
  307. local result,unproc
  308. unproc = rdbuf
  309. --根据帧结构循环解析未处理过的数据
  310. while true do
  311. if rfidType == 'renlian' then
  312. result,unproc = parse_renlian(unproc)
  313. elseif rfidType == 'tiandiren' then
  314. result,unproc = parse_tiandiren(unproc)
  315. else
  316. log.info("uartTask.proc","rfidType invalid!!")
  317. return false
  318. end
  319. if not unproc or unproc == "" or not result then
  320. break
  321. end
  322. end
  323. rdbuf = unproc or ""
  324. --log.info("uartTask.proc","------> #rdbuf",#rdbuf)
  325. if #rdbuf > 1000 then
  326. log.warn("uartTask.proc","rdbuf length > 1000!! rdbuf:", #rdbuf)
  327. end
  328. end
  329. --[[
  330. 函数名:read
  331. 功能 :读取串口接收到的数据
  332. 参数 :无
  333. 返回值:无
  334. ]]
  335. local function read()
  336. local data = ""
  337. --底层core中,串口收到数据时:
  338. --如果接收缓冲区为空,则会以中断方式通知Lua脚本收到了新数据;
  339. --如果接收缓冲器不为空,则不会通知Lua脚本
  340. --所以Lua脚本中收到中断读串口数据时,每次都要把接收缓冲区中的数据全部读出,这样才能保证底层core中的新数据中断上来,此read函数中的while语句中就保证了这一点
  341. while true do
  342. data = uart.read(UART_ID,"*l")
  343. if not data or string.len(data) == 0 then break end
  344. --打开下面的打印会耗时
  345. --log.info("uartTask.read bin",data)
  346. --log.info("uartTask.read hex",data:toHex())
  347. --sys.wait(1000)
  348. --处理串口收到的rfid数据
  349. --proc(data)
  350. end
  351. end
  352. --[[
  353. 函数名:write
  354. 功能 :通过串口发送数据
  355. 参数 :
  356. s:要发送的数据
  357. 返回值:无
  358. ]]
  359. function write(s)
  360. log.info("uartTask.write",s)
  361. uart.write(UART_ID,s.."\r\n")
  362. end
  363. local function writeOk()
  364. log.info("uartTask.writeOk")
  365. end
  366. --检测 rfids_buf是否超时
  367. sys.timerLoopStart(function ()
  368. if not timerSyncResult then
  369. log.info("uartTask.timerLoopStart","wait TIMER_SYNC_SUCCESS message ...")
  370. return false
  371. end
  372. if not rfidType then
  373. log.info("uartTask.timerLoopStart","rfidType undefined!!")
  374. rfidType = nvm.get("rfidType")
  375. return false
  376. end
  377. --log.info(">>>>>>> uart1Task.timerLoopStart ")
  378. --检测到超时时,发布数据并重置 rfids_buf
  379. local cur_time = os.time()
  380. if (cur_time - rfids_buf.start_time >= rfidReportIntervalRlian) or (rfids_buf.rfid_count >= rfidBufferMaxCountRlian) then
  381. if rfids_buf.rfid_count > 0 then
  382. if rfidType == 'renlian' then
  383. --log.info("uartTask.timerLoopStart",">>>>>>> uart1Task.timerLoopStart pub_packet_data_renlian", cur_time)
  384. sys.publish("pub_packet_data_renlian", rfids_buf)
  385. elseif rfidType == 'tiandiren' then
  386. sys.publish("pub_packet_data_tiandiren", rfids_buf)
  387. --sys.publish("pub_packet_data_renlian", rfids_buf)
  388. else
  389. log.error("uartTask.timerLoopStart","rfidType invalid!!")
  390. return false
  391. end
  392. end
  393. rfids_buf = {["start_time"]=cur_time,["rfid_count"]=0,["buf"]={}}
  394. end
  395. end, 100)
  396. --记录上报过的rfid标签数据
  397. sys.subscribe("pub_packet_data_renlian", function(packet_data)
  398. if rfidEnableThrottleRlian ~= 1 then
  399. return
  400. end
  401. log.info("uartTask.subscribe.pub_packet_data_renlian","update reportRfids, rfid_count:",packet_data.rfid_count,", time:",os.time())
  402. for key, rfid in pairs(packet_data["buf"]) do
  403. if key:len() == 12 then
  404. local rfidPrefix = key:sub(1,6)
  405. local rfidSn = key:sub(7,12)
  406. if not reportRfids[rfidPrefix] then
  407. reportRfids[rfidPrefix] = {}
  408. end
  409. reportRfids[rfidPrefix][rfidSn] = true
  410. end
  411. end
  412. end)
  413. --等待时间同步成功消息通知
  414. sys.subscribe("TIMER_SYNC_SUCCESS", function ( ... )
  415. log.info("uartTask.subscribe","TIMER_SYNC_SUCCESS")
  416. timerSyncResult = true
  417. end)
  418. --保持系统处于唤醒状态,此处只是为了测试需要,所以此模块没有地方调用pm.sleep("uartTask")休眠,不会进入低功耗休眠状态
  419. --在开发“要求功耗低”的项目时,一定要想办法保证pm.wake("uartTask")后,在不需要串口时调用pm.sleep("uartTask")
  420. pm.wake("uartTask")
  421. --[[
  422. --初始化rfid串口配置参数
  423. rfid_uart_config_init_timer_id = sys.timerLoopStart(function ()
  424. if not UART_ID then
  425. log.info("UART_ID empty, attempt from nvm.get")
  426. UART_ID = nvm.get("rfidUartId")
  427. return false
  428. end
  429. if not UART_ID_BAUD_RATE then
  430. log.info("UART_ID_BAUD_RATE empty, attempt from nvm.get")
  431. UART_ID_BAUD_RATE = nvm.get("rfidUartBaudRate")
  432. return false
  433. end
  434. if not rfid_uart_config_init_timer_id then
  435. log.info("rfid_uart_config_init_timer_id empty")
  436. return false
  437. end
  438. log.info("init rfid uart","UART_ID:",UART_ID,"UART_ID_BAUD_RATE:",UART_ID_BAUD_RATE)
  439. --注册串口的数据接收函数,串口收到数据后,会以中断方式,调用read接口读取数据
  440. uart.on(UART_ID,"receive",read)
  441. --注册串口的数据发送通知函数
  442. uart.on(UART_ID,"sent",writeOk)
  443. --配置并且打开串口
  444. --波特率,可选1200,2400,4800,9600,10400,14400,19200,28800,38400,57600,115200,230400,460800,921600
  445. --uart.setup(UART_ID,115200,8,uart.PAR_NONE,uart.STOP_1)
  446. uart.setup(UART_ID,UART_ID_BAUD_RATE,8,uart.PAR_NONE,uart.STOP_1)
  447. --如果需要打开“串口发送数据完成后,通过异步消息通知”的功能,则使用下面的这行setup,注释掉上面的一行setup
  448. --uart.setup(UART_ID,115200,8,uart.PAR_NONE,uart.STOP_1,nil,1)
  449. log.info("uart timer loop stop","rfid_uart_config_init_timer_id:",rfid_uart_config_init_timer_id)
  450. sys.timerStop(rfid_uart_config_init_timer_id)
  451. end, 100)
  452. ]]
  453. sys.taskInit(function()
  454. if not UART_ID then
  455. log.info("UART_ID empty, attempt from nvm.get")
  456. UART_ID = nvm.get("rfidUartId")
  457. return false
  458. end
  459. if not UART_ID_BAUD_RATE then
  460. log.info("UART_ID_BAUD_RATE empty, attempt from nvm.get")
  461. UART_ID_BAUD_RATE = nvm.get("rfidUartBaudRate")
  462. return false
  463. end
  464. log.info("init rfid uart","UART_ID:",UART_ID,"UART_ID_BAUD_RATE:",UART_ID_BAUD_RATE)
  465. --注册串口的数据接收函数,串口收到数据后,会以中断方式,调用read接口读取数据
  466. uart.on(UART_ID,"receive",function() sys.publish("UART_RECEIVE") end)
  467. --注册串口的数据发送通知函数
  468. uart.on(UART_ID,"sent",writeOk)
  469. --配置并且打开串口
  470. --波特率,可选1200,2400,4800,9600,10400,14400,19200,28800,38400,57600,115200,230400,460800,921600
  471. --uart.setup(UART_ID,115200,8,uart.PAR_NONE,uart.STOP_1)
  472. uart.setup(UART_ID,UART_ID_BAUD_RATE,8,uart.PAR_NONE,uart.STOP_1)
  473. end)
  474. local function taskRead()
  475. if not sys.waitUntil("TIMER_SYNC_SUCCESS", 600*1000) then
  476. log.error("uartTask.taskRead","wait timer sync timeout,reboot now ...")
  477. sys.restart("wait timer sync timeout")
  478. end
  479. --检测是否启用2.4g rfid上报功能
  480. local res,maxtime = false,0
  481. while true do
  482. while true do
  483. local enableUploadRfid24 = nvm.get("enableUploadRfid24")
  484. if enableUploadRfid24 == 0 then
  485. log.warn("uartTask.taskRead","not enable upload 2.4g rfid,skip uart read! enableUploadRfid24:", enableUploadRfid24)
  486. --sys.wait(2000)
  487. res,maxtime = sys.waitUntil("MESSAGE_TYPE_ENABLE_RFID_REPORT", 2000)
  488. if res then
  489. log.info("uartTask.taskRead", "enable rfid report by heartbeat channel, maxtime:",maxtime)
  490. break
  491. end
  492. else
  493. break
  494. end
  495. end
  496. sys.publish("start_uart_read_task")
  497. local cacheData = ""
  498. local count = 0
  499. local start = os.time()
  500. while true do
  501. if maxtime >0 and (os.time()-start>maxtime+5) then
  502. log.info("uartTask.taskRead","uart read time > ", maxtime+5, ", stop uart read!")
  503. break
  504. else
  505. cacheData = uart.read(UART_ID,"*l")
  506. if cacheData == "" then
  507. if not sys.waitUntil("UART_RECEIVE",100) then
  508. log.info("uartTask.taskRead","100ms no data")
  509. end
  510. else
  511. proc(cacheData)
  512. --log.info("uartTask.read hex",cacheData:toHex())
  513. cacheData = ""
  514. count = count + 1
  515. if count > 1200 then
  516. sys.wait(100)
  517. count = 0
  518. end
  519. end
  520. end
  521. end
  522. end
  523. end
  524. --启动串口数据接收任务
  525. sys.taskInit(taskRead)
  526. --crc16校验
  527. local function crc16_920_verify(packet)
  528. if not packet then
  529. log.error("uartTask.crc16_920_verify", "packet empty!!")
  530. return false
  531. end
  532. local res, CRC = funlib.get920Crc16(packet:sub(1,#packet-2))
  533. if not res then
  534. log.error("uartTask.crc16_920_verify", "get920Crc16 failed!!",packet:sub(1,#packet-2):toHex())
  535. return false
  536. end
  537. local CRC_REL = packet:sub(-2,-1):toHex()
  538. --log.info("uartTask.crc16_920_verify", packet:toHex(), string.format("%04X",CRC), CRC_REL)
  539. if string.format("%04X",CRC) ~= CRC_REL then
  540. log.error("uartTask.crc16_920_verify", "CRC ~= CRC_REL!! CRC:", string.format("%04X",CRC),",CRC_REL:", CRC_REL)
  541. return false
  542. end
  543. return true, CRC
  544. end
  545. --920标签转换成任联rfid标签个数
  546. local function convert_920_to_rfid(bin)
  547. if not bin then
  548. log.error("uartTask.convert_920_to_rfid","bin not existed!")
  549. return false
  550. end
  551. if #bin ~= string.byte( bin, 1 )+1 then
  552. log.error("uartTask.convert_920_to_rfid","bin length error!")
  553. return false
  554. end
  555. --crc校验
  556. local res = crc16_920_verify(bin)
  557. if not res then
  558. log.error("uartTask.convert_920_to_rfid","crc16_920_verify failed!", bin:toHex())
  559. return false
  560. end
  561. --log.info("uartTask.convert_920_to_rfid", bin:sub(1,10):toHex(), string.format("%04X",crypto.crc16("USER-DEFINED",bin:sub(1,10),0x8408,0xffff,0xffff,0,0)))
  562. --协议转换
  563. local id = bin:sub(5,10)
  564. --920类型标签
  565. local dev_type = string.char(0xfa)
  566. local status = string.char(0x5a)
  567. local rssi = string.char(0x0)
  568. local frm_head = string.char(0xaa)..string.char(0x55)
  569. local frm_len = string.char(0xb)
  570. local rfid_bin = frm_head..frm_len..id..dev_type..status..rssi.."\r\n"
  571. log.info("uartTask.convert_920_to_rfid", rfid_bin:toHex())
  572. return true, rfid_bin
  573. end
  574. --读取到920标签数据
  575. sys.taskInit(function()
  576. if not sys.waitUntil("TIMER_SYNC_SUCCESS", 600*1000) then
  577. log.error("uartTask.receive_920_data","wait timer sync timeout,reboot now ...")
  578. sys.restart("[receive_920_data]wait timer sync timeout")
  579. end
  580. while true do
  581. local cur_time = os.time()
  582. local result, packet_data = sys.waitUntil("receive_920_data",3600*1000)
  583. if result then
  584. local res, convert_data = convert_920_to_rfid(packet_data)
  585. if res then
  586. proc(convert_data)
  587. else
  588. log.error("uartTask.receive_920_data","convert_920_to_rfid failed!!")
  589. end
  590. else
  591. log.info("uartTask.receive_920_data","wait receive_920_data timeout")
  592. end
  593. end
  594. end)
  595. --启动厂测读rfid标签模式,读取指定rfid标签信号
  596. sys.subscribe("factory_test_start_read_rfid", function ( data )
  597. if data.rfid then
  598. log.info("uartTask.subscribe.factory_test_start_read_rfid","factory test mode,start read rifd:",data.rfid)
  599. isFactoryTestReadRfidMode = true
  600. factoryTestReadRfid = "0000"..data.rfid
  601. else
  602. log.error("uartTask.subscribe.factory_test_start_read_rfid","data.rfid not existed!!")
  603. end
  604. end)
  605. --退出厂测读rfid标签模式
  606. sys.subscribe("factory_test_stop_read_rfid", function ( )
  607. log.info("uartTask.subscribe.factory_test_stop_read_rfid","factory test stop read rifd")
  608. isFactoryTestReadRfidMode = false
  609. factoryTestReadRfid = ""
  610. end)
  611. --启动读rfid标签模式,读取指定rfid标签信号
  612. sys.subscribe("cmd_start_read_rfid", function ( data )
  613. if data.rfid then
  614. log.info("uartTask.subscribe.cmd_start_read_rfid","cmd start read rifd:",data.rfid)
  615. isCmdReadRfidMode = true
  616. cmdReadRfid = data.rfid
  617. else
  618. log.error("uartTask.subscribe.cmd_start_read_rfid","data.rfid not existed!!")
  619. end
  620. end)
  621. --退出厂测读rfid标签模式
  622. sys.subscribe("cmd_stop_read_rfid", function ( )
  623. log.info("uartTask.subscribe.cmd_stop_read_rfid","cmd stop read rifd")
  624. isCmdReadRfidMode = false
  625. cmdReadRfid = ""
  626. end)
  627. --rfid离线检测任务
  628. sys.taskInit(function()
  629. while true do
  630. if sys.waitUntil("start_uart_read_task", 3600*1000) then
  631. break
  632. else
  633. log.info("uartTask.rfidOfflineCheckTask","wait start_uart_read_task timeout!")
  634. end
  635. end
  636. --开启节流模式时
  637. while rfidEnableThrottleRlian == 1 do
  638. local now = os.time()
  639. --log.info("uartTask.rfidOfflineCheckTask","start time:",now)
  640. local tmp = {["count"]=0,["buf"]={}}
  641. local checkCount = 0
  642. local onlineCount = 0
  643. local offlineCount = 0
  644. local totalCount = 0
  645. for rfidPrefix in pairs(onlineRfids["buf"]) do
  646. for rfidSn, online_time in pairs(onlineRfids["buf"][rfidPrefix]) do
  647. totalCount = totalCount + 1
  648. local rfid = rfidPrefix..rfidSn
  649. if online_time then
  650. checkCount = checkCount + 1
  651. if now - online_time <= rfidOfflineTimeoutRlian then
  652. if rfid == "0000CC8C8DF7" or rfid == "0000CC8C8DF8" then
  653. log.info("uartTask.rfidOfflineCheckTask","rfid is online,skip! rfid:", rfid, "online_time:", online_time)
  654. end
  655. tmp["buf"][rfidPrefix] = {}
  656. tmp["buf"][rfidPrefix][rfidSn] = online_time
  657. tmp["count"] = tmp["count"] + 1
  658. onlineCount = onlineCount + 1
  659. else
  660. offlineCount = offlineCount + 1
  661. if reportRfids[rfidPrefix] and reportRfids[rfidPrefix][rfidSn] then
  662. reportRfids[rfidPrefix][rfidSn] = nil
  663. end
  664. if rfid == "0000CC8C8DF7" or rfid == "0000CC8C8DF8" then
  665. log.info("uartTask.rfidOfflineCheckTask","rfid offline! rfid:", rfid, "online_time:", online_time, "now:", now, "rfidOfflineTimeoutRlian:", rfidOfflineTimeoutRlian)
  666. end
  667. end
  668. end
  669. end
  670. end
  671. onlineRfids = tmp
  672. log.info("uartTask.rfidOfflineCheckTask", "totalCount:",totalCount, "checkCount:",checkCount, "onlineCount:",onlineCount, "offlineCount:",offlineCount)
  673. sys.wait(rfidOfflineTimeoutRlian*1000)
  674. end
  675. end)
  676. --[[
  677. sys.timerLoopStart(function()
  678. log.info("uartTask","打印占用的内存:", _G.collectgarbage("count"))-- 打印占用的RAM
  679. log.info("uartTask","打印可用的空间", rtos.get_fs_free_size())-- 打印剩余FALSH,单位Byte
  680. end, 10000)
  681. ]]