--- 模块功能:串口1功能测试 -- @author openLuat -- @module uart.uartTask -- @license MIT -- @copyright openLuat -- @release 2018.03.27 module(...,package.seeall) require "utils" require "pm" require "sys" require "log" require "nvm" require "funlib" --[[ 功能定义: uart按照帧结构接收外围设备的输入,收到正确的指令后,回复ASCII字符串 帧结构如下: 帧头:1字节,0x01表示扫描指令,0x02表示控制GPIO命令,0x03表示控制端口命令 帧体:字节不固定,跟帧头有关 帧尾:1字节,固定为0xC0 收到的指令帧头为0x01时,回复"CMD_SCANNER\r\n"给外围设备;例如接收到0x01 0xC0两个字节,就回复"CMD_SCANNER\r\n" 收到的指令帧头为0x02时,回复"CMD_GPIO\r\n"给外围设备;例如接收到0x02 0xC0两个字节,就回复"CMD_GPIO\r\n" 收到的指令帧头为0x03时,回复"CMD_PORT\r\n"给外围设备;例如接收到0x03 0xC0两个字节,就回复"CMD_PORT\r\n" 收到的指令帧头为其余数据时,回复"CMD_ERROR\r\n"给外围设备;例如接收到0x04 0xC0两个字节,就回复"CMD_ERROR\r\n" ]] --串口ID,1对应uart1 --如果要修改为uart2,把UART_ID赋值为2即可 -- air720UH 可用串口1和2,rfid串口用1 -- air724UH 可用串口1、2、3,rfid串口用3 local UART_ID = nvm.get("rfidUartId") local UART_ID_BAUD_RATE = nvm.get("rfidUartBaudRate") --local UART_ID = 3 --帧头以及帧尾 local FRM_HEAD,FRM_TAIL = 0xaa55,0x0d0a --rfid 上报间隔 local rfidReportIntervalRlian = nvm.get("rfidReportIntervalRlian") or 60 --rfid 数据包缓存最大标签个数 local rfidBufferMaxCountRlian = nvm.get("rfidBufferMaxCountRlian") or 50 --rfid 是否开启节流模式 local rfidEnableThrottleRlian = nvm.get("rfidEnableThrottleRlian") or true --rfid 离线时间阀值 local rfidOfflineTimeoutRlian = nvm.get("rfidOfflineTimeoutRlian") or 5 local rfidType = nvm.get("rfidType") --rfid 离线检测定时器 local rfidOfflineCheckTimerIds = {} --在线的rifd local onlineRfids = {["count"]=0,["buf"]={}} local onlineRfidsMaxCount = 1000 --已上报的rifd local reportRfids = {} --串口读到的数据缓冲区 local rdbuf = "" --rfid 串口初始化定参数时器 local rfid_uart_config_init_timer_id = nil local timerSyncResult = false --是否厂测读rfid标签模式 local isFactoryTestReadRfidMode = false --厂测模式读rifd号 local factoryTestReadRfid = "" local isCmdReadRfidMode = false local cmdReadRfid = "" require "misc" local function getTime() local tm = misc.getClock() return string.format("%04d/%02d/%02d,%02d:%02d:%02d", tm.year, tm.month, tm.day, tm.hour, tm.min, tm.sec) end --初始化rfid缓冲池 local start_time = os.time() local rfids_buf = {["start_time"]=start_time,["rfid_count"]=0,["buf"]={}} --require "HashMap" --local rfid_map = HashMap:new() --任联rfid数据解析 local function parse_rfid_renlian(body) if not body then return false end if body:len() ~= 9 then log.info("parse_rfid_renlian fail,body.length != 9") return false end local id = string.sub(body,1,6):toHex() local type = tonumber(string.byte(body,7)) local status = tonumber(string.byte(body,8)) local rssi = tonumber(string.byte(body,9)) local rfid = {["id"]=id,["type"]=type,["status"]=status,["rssi"]=rssi} return rfid end --任联rfid数据解析 local function parse_rfid_tiandiren(body) if not body then return false end if body:len() ~= 18 then log.info("parse_rfid_tiandiren fail,body.length != 18") return false end local id = string.sub(body,5,8):toHex() if not id then log.info("parse_rfid_tiandiren fail,id empty! body:",body:toHex()) return false end local sn = string.byte(body,2) local dev_type = string.byte(body,3)*16 + string.byte(body,4) local cmd_type = string.byte(body,9) local crc = string.byte(body,15) + string.byte(body,16) * 16 local content = string.sub(body,10,14):toHex() local status = string.byte(body,17) local rssi = string.byte(body,18) --local rfid = {["id"]=id,["cmd_type"]=cmd_type,["dev_type"]=dev_type,["sn"]=sn} local rfid = {["id"]=id,["type"]=cmd_type,["status"]=status,["rssi"]=rssi,["dev_type"]=dev_type,["sn"]=sn,["content"]=content} return rfid end --[[ 函数名:parse_renlian 功能 :按照帧结构解析处理一条完整的帧数据 参数 : data:所有未处理的数据 返回值:第一个返回值是一条完整帧报文的处理结果,第二个返回值是未处理的数据 ]] local function parse_renlian(data) --log.info("uartTask.parse_renlian", data:toHex()) if not data then return end if data:len() < 14 then return false, data end local frm_head = tonumber(string.format( "%02x",string.byte(data,1)) .. string.format( "%02x",string.byte(data,2)),16) local tail = string.find(data,string.char(0x0d)..string.char(0x0a)) if not tail then log.error("uartTask.parse_renlian", "end char:0x0d0a not found,wait for more ... ", data:toHex()) return false,data end if frm_head ~= FRM_HEAD then --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()) return false,string.sub(data,tail+2,-1) end local frm_len = tonumber(string.byte(data,3)) local body,result = string.sub(data,4,tail-1) --检测body完整性 if (frm_len-2) ~= body:len() then log.error("uartTask.parse_renlian", "frm body length error, frm_len-2 = ",frm_len-2,", body:len() = ", body:len(), ", body:toHex() = ", body:toHex()) return false,string.sub(data,tail+2,-1) end --log.info("uart1Task.parse",data:toHex(),frm_head,body:toHex()) --解析rfid local rfid_info = parse_rfid_renlian(body) if not rfid_info then log.error("uartTask.parse_renlian", "parse_rfid_renlian() failed!") return false,string.sub(data,tail+2,-1) end local rfidRssiFilterVal = nvm.get("rfidRssiFilterVal") or 999 if rfidRssiFilterVal > 0 and rfid_info.rssi > rfidRssiFilterVal then log.info("uartTask.parse_renlian", "rfid_info.rssi > ".. rfidRssiFilterVal..", drop it! rfid_info.rssi =", rfid_info.rssi, "rfid:",rfid_info.id) return false,string.sub(data,tail+2,-1) end --进入厂测读rfid标签信号模式 if isFactoryTestReadRfidMode then --读到rfid标签信号后,退出厂测模式 if factoryTestReadRfid == rfid_info.id then sys.publish("factory_test_read_rfid_success",{rssi=rfid_info.rssi,rfid=rfid_info.id}) isFactoryTestMode = false factoryTestReadRfid = "" end return true,string.sub(data,tail+2,-1) end --进入指令读rfid标签信号模式 if isCmdReadRfidMode then --读到rfid标签信号后,退出读标签模式 if cmdReadRfid == rfid_info.id then log.info("uartTask.parse_renlian", "rfid_info:", json.encode(rfid_info)) sys.publish("cmd_read_rfid_success",{rssi=rfid_info.rssi,rfid=rfid_info.id}) isCmdReadRfidMode = false cmdReadRfid = "" end return true,string.sub(data,tail+2,-1) end local cur_time = os.time() --开启节流模式时(报警状态的标签不节流) if rfidEnableThrottleRlian == 1 and rfid_info.status ~= 0x5a then if rfid_info.id:len() ~= 12 then log.error("uartTask.parse_renlian","error,rfid length ~= 12!! rfid:",rfid_info.id) return true,string.sub(data,tail+2,-1) end local rfidPrefix = rfid_info.id:sub(1,6) local rfidSn = rfid_info.id:sub(7,12) if onlineRfids["count"] >= onlineRfidsMaxCount and not onlineRfids["buf"][rfidPrefix] or (onlineRfids["buf"][rfidPrefix] and not onlineRfids["buf"][rfidPrefix][rfidSn]) then if rfid_info.id == "0000CC8C8DF7" or rfid_info.id == "0000CC8C8DF8" then log.info("uartTask.parse_renlian","onlineRfids.count >= ", onlineRfidsMaxCount, " , drop parse!", rfid_info.id) end return true,string.sub(data,tail+2,-1) end if not onlineRfids["buf"][rfidPrefix] then onlineRfids["buf"][rfidPrefix] = {} onlineRfids["count"] = onlineRfids["count"] + 1 onlineRfids["buf"][rfidPrefix][rfidSn] = cur_time elseif onlineRfids["buf"][rfidPrefix] and not onlineRfids["buf"][rfidPrefix][rfidSn] then onlineRfids["count"] = onlineRfids["count"] + 1 onlineRfids["buf"][rfidPrefix][rfidSn] = cur_time else onlineRfids["buf"][rfidPrefix][rfidSn] = cur_time end if rfid_info.id == "0000CC8C8DF7" or rfid_info.id == "0000CC8C8DF8" then log.info("uartTask.parse_renlian", "rfid:", rfid_info.id, "online time:", cur_time) end --log.info("uartTask.parse_renlian",onlineRfids["count"],rfid_info.id) --已上报一次的跳过 if reportRfids[rfidPrefix] and reportRfids[rfidPrefix][rfidSn] then if rfid_info.id == "0000CC8C8DF7" or rfid_info.id == "0000CC8C8DF8" then log.info("uartTask.parse_renlian", "enable Throttle, skip! rfid:", rfid_info.id) end return true,string.sub(data,tail+2,-1) end end --检测到超时时,发布数据并重置 rfids_buf if (cur_time - rfids_buf.start_time >= rfidReportIntervalRlian) or (rfids_buf.rfid_count >= rfidBufferMaxCountRlian) then if rfids_buf.rfid_count > 0 then --log.info("uartTask.parse_renlian", ">>>>>>> uart1Task.parse pub_packet_data", cur_time) sys.publish("pub_packet_data_renlian", rfids_buf) end rfids_buf = {["start_time"]=cur_time,["rfid_count"]=0,["buf"]={}} end --新增数据 if not rfids_buf["buf"][rfid_info.id] then --log.info("uartTask.parse_renlian", ">>>>>>> push rfid to buf,rfid:", rfid_info.id) rfids_buf.rfid_count = rfids_buf.rfid_count + 1 rfids_buf["buf"][rfid_info.id] = {["time"]=cur_time,["recv_count"]=1,["rssi"]=rfid_info.rssi,["type"]=rfid_info.type,["status"]=rfid_info.status} return true,string.sub(data,tail+2,-1) end --更新数据 local recv_count = rfids_buf["buf"][rfid_info.id]["recv_count"] + 1 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} --log.info("uartTask.parse_renlian", ">>>>>>> update rfid_buf,rfid:", rfid_info.id, ", recv_count:", recv_count) return true,string.sub(data,tail+2,-1) end --[[ 函数名:parse_tiandiren 功能 :按照帧结构解析处理一条完整的帧数据 参数 : data:所有未处理的数据 返回值:第一个返回值是一条完整帧报文的处理结果,第二个返回值是未处理的数据 ]] local function parse_tiandiren(data) if not data then return end if data:len() < 20 then return false, data end local frm_head = tonumber(string.format( "%02x",string.byte(data,1)) .. string.format( "%02x",string.byte(data,2)),16) local tail = string.find(data,string.char(0x0d)..string.char(0x0a)) if not tail then log.info("end char:0x0d0a not found,wait for more ... ", data:toHex()) return false,data end if frm_head ~= FRM_HEAD then log.info("FRM_HEAD ERROR,drop it, frm_head = ", frm_head, ", FRM_HEAD = ", FRM_HEAD) return false,string.sub(data,tail+2,-1) end local frm_len = tonumber(string.byte(data,3)) local body,result = string.sub(data,4,tail-1) --检测body完整性 if (frm_len-2) ~= body:len() then log.info("frm body length error, frm_len-2 = ",frm_len-2,", body:len() = ", body:len(), ", body:toHex() = ", body:toHex()) return false,string.sub(data,tail+2,-1) end --log.info("uart1Task.parse",data:toHex(),frm_head,body:toHex()) --解析rfid local rfid_info = parse_rfid_tiandiren(body) if not rfid_info then log.info("parse_rfid_tiandiren() failed!") return false,string.sub(data,tail+2,-1) end --检测到超时时,发布数据并重置 rfids_buf local cur_time = os.time() if (cur_time - rfids_buf.start_time >= rfidReportIntervalRlian) or (rfids_buf.rfid_count >= rfidBufferMaxCountRlian) then if rfids_buf.rfid_count > 0 then --log.info(">>>>>>> uart1Task.parse pub_packet_data", cur_time) sys.publish("pub_packet_data_tiandiren", rfids_buf) --sys.publish("pub_packet_data_renlian", rfids_buf) end rfids_buf = {["start_time"]=cur_time,["rfid_count"]=0,["buf"]={}} end --新增数据 if not rfids_buf["buf"][rfid_info.id] then --log.info(">>>>>>> push rfid to buf,rfid:", rfid_info.id) rfids_buf.rfid_count = rfids_buf.rfid_count + 1 --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} 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} return true,string.sub(data,tail+2,-1) end --更新数据 local recv_count = rfids_buf["buf"][rfid_info.id]["recv_count"] + 1 --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} 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} --log.info(">>>>>>> update rfid_buf,rfid:", rfid_info.id, ", recv_count:", recv_count) return true,string.sub(data,tail+2,-1) end --[[ 函数名:proc 功能 :处理从串口读到的数据 参数 : data:当前一次从串口读到的数据 返回值:无 ]] local function proc(data) if not data or string.len(data) == 0 then return end if not rfidType then log.info("uartTask.proc","rfidType undefined!!") rfidType = nvm.get("rfidType") return false end --追加到缓冲区 rdbuf = rdbuf..data local result,unproc unproc = rdbuf --根据帧结构循环解析未处理过的数据 while true do if rfidType == 'renlian' then result,unproc = parse_renlian(unproc) elseif rfidType == 'tiandiren' then result,unproc = parse_tiandiren(unproc) else log.info("uartTask.proc","rfidType invalid!!") return false end if not unproc or unproc == "" or not result then break end end rdbuf = unproc or "" --log.info("uartTask.proc","------> #rdbuf",#rdbuf) if #rdbuf > 1000 then log.warn("uartTask.proc","rdbuf length > 1000!! rdbuf:", #rdbuf) end end --[[ 函数名:read 功能 :读取串口接收到的数据 参数 :无 返回值:无 ]] local function read() local data = "" --底层core中,串口收到数据时: --如果接收缓冲区为空,则会以中断方式通知Lua脚本收到了新数据; --如果接收缓冲器不为空,则不会通知Lua脚本 --所以Lua脚本中收到中断读串口数据时,每次都要把接收缓冲区中的数据全部读出,这样才能保证底层core中的新数据中断上来,此read函数中的while语句中就保证了这一点 while true do data = uart.read(UART_ID,"*l") if not data or string.len(data) == 0 then break end --打开下面的打印会耗时 --log.info("uartTask.read bin",data) --log.info("uartTask.read hex",data:toHex()) --sys.wait(1000) --处理串口收到的rfid数据 --proc(data) end end --[[ 函数名:write 功能 :通过串口发送数据 参数 : s:要发送的数据 返回值:无 ]] function write(s) log.info("uartTask.write",s) uart.write(UART_ID,s.."\r\n") end local function writeOk() log.info("uartTask.writeOk") end --检测 rfids_buf是否超时 sys.timerLoopStart(function () if not timerSyncResult then log.info("uartTask.timerLoopStart","wait TIMER_SYNC_SUCCESS message ...") return false end if not rfidType then log.info("uartTask.timerLoopStart","rfidType undefined!!") rfidType = nvm.get("rfidType") return false end --log.info(">>>>>>> uart1Task.timerLoopStart ") --检测到超时时,发布数据并重置 rfids_buf local cur_time = os.time() if (cur_time - rfids_buf.start_time >= rfidReportIntervalRlian) or (rfids_buf.rfid_count >= rfidBufferMaxCountRlian) then if rfids_buf.rfid_count > 0 then if rfidType == 'renlian' then --log.info("uartTask.timerLoopStart",">>>>>>> uart1Task.timerLoopStart pub_packet_data_renlian", cur_time) sys.publish("pub_packet_data_renlian", rfids_buf) elseif rfidType == 'tiandiren' then sys.publish("pub_packet_data_tiandiren", rfids_buf) --sys.publish("pub_packet_data_renlian", rfids_buf) else log.error("uartTask.timerLoopStart","rfidType invalid!!") return false end end rfids_buf = {["start_time"]=cur_time,["rfid_count"]=0,["buf"]={}} end end, 100) --记录上报过的rfid标签数据 sys.subscribe("pub_packet_data_renlian", function(packet_data) if rfidEnableThrottleRlian ~= 1 then return end log.info("uartTask.subscribe.pub_packet_data_renlian","update reportRfids, rfid_count:",packet_data.rfid_count,", time:",os.time()) for key, rfid in pairs(packet_data["buf"]) do if key:len() == 12 then local rfidPrefix = key:sub(1,6) local rfidSn = key:sub(7,12) if not reportRfids[rfidPrefix] then reportRfids[rfidPrefix] = {} end reportRfids[rfidPrefix][rfidSn] = true end end end) --等待时间同步成功消息通知 sys.subscribe("TIMER_SYNC_SUCCESS", function ( ... ) log.info("uartTask.subscribe","TIMER_SYNC_SUCCESS") timerSyncResult = true end) --保持系统处于唤醒状态,此处只是为了测试需要,所以此模块没有地方调用pm.sleep("uartTask")休眠,不会进入低功耗休眠状态 --在开发“要求功耗低”的项目时,一定要想办法保证pm.wake("uartTask")后,在不需要串口时调用pm.sleep("uartTask") pm.wake("uartTask") --[[ --初始化rfid串口配置参数 rfid_uart_config_init_timer_id = sys.timerLoopStart(function () if not UART_ID then log.info("UART_ID empty, attempt from nvm.get") UART_ID = nvm.get("rfidUartId") return false end if not UART_ID_BAUD_RATE then log.info("UART_ID_BAUD_RATE empty, attempt from nvm.get") UART_ID_BAUD_RATE = nvm.get("rfidUartBaudRate") return false end if not rfid_uart_config_init_timer_id then log.info("rfid_uart_config_init_timer_id empty") return false end log.info("init rfid uart","UART_ID:",UART_ID,"UART_ID_BAUD_RATE:",UART_ID_BAUD_RATE) --注册串口的数据接收函数,串口收到数据后,会以中断方式,调用read接口读取数据 uart.on(UART_ID,"receive",read) --注册串口的数据发送通知函数 uart.on(UART_ID,"sent",writeOk) --配置并且打开串口 --波特率,可选1200,2400,4800,9600,10400,14400,19200,28800,38400,57600,115200,230400,460800,921600 --uart.setup(UART_ID,115200,8,uart.PAR_NONE,uart.STOP_1) uart.setup(UART_ID,UART_ID_BAUD_RATE,8,uart.PAR_NONE,uart.STOP_1) --如果需要打开“串口发送数据完成后,通过异步消息通知”的功能,则使用下面的这行setup,注释掉上面的一行setup --uart.setup(UART_ID,115200,8,uart.PAR_NONE,uart.STOP_1,nil,1) log.info("uart timer loop stop","rfid_uart_config_init_timer_id:",rfid_uart_config_init_timer_id) sys.timerStop(rfid_uart_config_init_timer_id) end, 100) ]] sys.taskInit(function() if not UART_ID then log.info("UART_ID empty, attempt from nvm.get") UART_ID = nvm.get("rfidUartId") return false end if not UART_ID_BAUD_RATE then log.info("UART_ID_BAUD_RATE empty, attempt from nvm.get") UART_ID_BAUD_RATE = nvm.get("rfidUartBaudRate") return false end log.info("init rfid uart","UART_ID:",UART_ID,"UART_ID_BAUD_RATE:",UART_ID_BAUD_RATE) --注册串口的数据接收函数,串口收到数据后,会以中断方式,调用read接口读取数据 uart.on(UART_ID,"receive",function() sys.publish("UART_RECEIVE") end) --注册串口的数据发送通知函数 uart.on(UART_ID,"sent",writeOk) --配置并且打开串口 --波特率,可选1200,2400,4800,9600,10400,14400,19200,28800,38400,57600,115200,230400,460800,921600 --uart.setup(UART_ID,115200,8,uart.PAR_NONE,uart.STOP_1) uart.setup(UART_ID,UART_ID_BAUD_RATE,8,uart.PAR_NONE,uart.STOP_1) end) local function taskRead() if not sys.waitUntil("TIMER_SYNC_SUCCESS", 600*1000) then log.error("uartTask.taskRead","wait timer sync timeout,reboot now ...") sys.restart("wait timer sync timeout") end --检测是否启用2.4g rfid上报功能 local res,maxtime = false,0 while true do while true do local enableUploadRfid24 = nvm.get("enableUploadRfid24") if enableUploadRfid24 == 0 then log.warn("uartTask.taskRead","not enable upload 2.4g rfid,skip uart read! enableUploadRfid24:", enableUploadRfid24) --sys.wait(2000) res,maxtime = sys.waitUntil("MESSAGE_TYPE_ENABLE_RFID_REPORT", 2000) if res then log.info("uartTask.taskRead", "enable rfid report by heartbeat channel, maxtime:",maxtime) break end else break end end sys.publish("start_uart_read_task") local cacheData = "" local count = 0 local start = os.time() while true do if maxtime >0 and (os.time()-start>maxtime+5) then log.info("uartTask.taskRead","uart read time > ", maxtime+5, ", stop uart read!") break else cacheData = uart.read(UART_ID,"*l") if cacheData == "" then if not sys.waitUntil("UART_RECEIVE",100) then log.info("uartTask.taskRead","100ms no data") end else proc(cacheData) --log.info("uartTask.read hex",cacheData:toHex()) cacheData = "" count = count + 1 if count > 1200 then sys.wait(100) count = 0 end end end end end end --启动串口数据接收任务 sys.taskInit(taskRead) --crc16校验 local function crc16_920_verify(packet) if not packet then log.error("uartTask.crc16_920_verify", "packet empty!!") return false end local res, CRC = funlib.get920Crc16(packet:sub(1,#packet-2)) if not res then log.error("uartTask.crc16_920_verify", "get920Crc16 failed!!",packet:sub(1,#packet-2):toHex()) return false end local CRC_REL = packet:sub(-2,-1):toHex() --log.info("uartTask.crc16_920_verify", packet:toHex(), string.format("%04X",CRC), CRC_REL) if string.format("%04X",CRC) ~= CRC_REL then log.error("uartTask.crc16_920_verify", "CRC ~= CRC_REL!! CRC:", string.format("%04X",CRC),",CRC_REL:", CRC_REL) return false end return true, CRC end --920标签转换成任联rfid标签个数 local function convert_920_to_rfid(bin) if not bin then log.error("uartTask.convert_920_to_rfid","bin not existed!") return false end if #bin ~= string.byte( bin, 1 )+1 then log.error("uartTask.convert_920_to_rfid","bin length error!") return false end --crc校验 local res = crc16_920_verify(bin) if not res then log.error("uartTask.convert_920_to_rfid","crc16_920_verify failed!", bin:toHex()) return false end --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))) --协议转换 local id = bin:sub(5,10) --920类型标签 local dev_type = string.char(0xfa) local status = string.char(0x5a) local rssi = string.char(0x0) local frm_head = string.char(0xaa)..string.char(0x55) local frm_len = string.char(0xb) local rfid_bin = frm_head..frm_len..id..dev_type..status..rssi.."\r\n" log.info("uartTask.convert_920_to_rfid", rfid_bin:toHex()) return true, rfid_bin end --读取到920标签数据 sys.taskInit(function() if not sys.waitUntil("TIMER_SYNC_SUCCESS", 600*1000) then log.error("uartTask.receive_920_data","wait timer sync timeout,reboot now ...") sys.restart("[receive_920_data]wait timer sync timeout") end while true do local cur_time = os.time() local result, packet_data = sys.waitUntil("receive_920_data",3600*1000) if result then local res, convert_data = convert_920_to_rfid(packet_data) if res then proc(convert_data) else log.error("uartTask.receive_920_data","convert_920_to_rfid failed!!") end else log.info("uartTask.receive_920_data","wait receive_920_data timeout") end end end) --启动厂测读rfid标签模式,读取指定rfid标签信号 sys.subscribe("factory_test_start_read_rfid", function ( data ) if data.rfid then log.info("uartTask.subscribe.factory_test_start_read_rfid","factory test mode,start read rifd:",data.rfid) isFactoryTestReadRfidMode = true factoryTestReadRfid = "0000"..data.rfid else log.error("uartTask.subscribe.factory_test_start_read_rfid","data.rfid not existed!!") end end) --退出厂测读rfid标签模式 sys.subscribe("factory_test_stop_read_rfid", function ( ) log.info("uartTask.subscribe.factory_test_stop_read_rfid","factory test stop read rifd") isFactoryTestReadRfidMode = false factoryTestReadRfid = "" end) --启动读rfid标签模式,读取指定rfid标签信号 sys.subscribe("cmd_start_read_rfid", function ( data ) if data.rfid then log.info("uartTask.subscribe.cmd_start_read_rfid","cmd start read rifd:",data.rfid) isCmdReadRfidMode = true cmdReadRfid = data.rfid else log.error("uartTask.subscribe.cmd_start_read_rfid","data.rfid not existed!!") end end) --退出厂测读rfid标签模式 sys.subscribe("cmd_stop_read_rfid", function ( ) log.info("uartTask.subscribe.cmd_stop_read_rfid","cmd stop read rifd") isCmdReadRfidMode = false cmdReadRfid = "" end) --rfid离线检测任务 sys.taskInit(function() while true do if sys.waitUntil("start_uart_read_task", 3600*1000) then break else log.info("uartTask.rfidOfflineCheckTask","wait start_uart_read_task timeout!") end end --开启节流模式时 while rfidEnableThrottleRlian == 1 do local now = os.time() --log.info("uartTask.rfidOfflineCheckTask","start time:",now) local tmp = {["count"]=0,["buf"]={}} local checkCount = 0 local onlineCount = 0 local offlineCount = 0 local totalCount = 0 for rfidPrefix in pairs(onlineRfids["buf"]) do for rfidSn, online_time in pairs(onlineRfids["buf"][rfidPrefix]) do totalCount = totalCount + 1 local rfid = rfidPrefix..rfidSn if online_time then checkCount = checkCount + 1 if now - online_time <= rfidOfflineTimeoutRlian then if rfid == "0000CC8C8DF7" or rfid == "0000CC8C8DF8" then log.info("uartTask.rfidOfflineCheckTask","rfid is online,skip! rfid:", rfid, "online_time:", online_time) end tmp["buf"][rfidPrefix] = {} tmp["buf"][rfidPrefix][rfidSn] = online_time tmp["count"] = tmp["count"] + 1 onlineCount = onlineCount + 1 else offlineCount = offlineCount + 1 if reportRfids[rfidPrefix] and reportRfids[rfidPrefix][rfidSn] then reportRfids[rfidPrefix][rfidSn] = nil end if rfid == "0000CC8C8DF7" or rfid == "0000CC8C8DF8" then log.info("uartTask.rfidOfflineCheckTask","rfid offline! rfid:", rfid, "online_time:", online_time, "now:", now, "rfidOfflineTimeoutRlian:", rfidOfflineTimeoutRlian) end end end end end onlineRfids = tmp log.info("uartTask.rfidOfflineCheckTask", "totalCount:",totalCount, "checkCount:",checkCount, "onlineCount:",onlineCount, "offlineCount:",offlineCount) sys.wait(rfidOfflineTimeoutRlian*1000) end end) --[[ sys.timerLoopStart(function() log.info("uartTask","打印占用的内存:", _G.collectgarbage("count"))-- 打印占用的RAM log.info("uartTask","打印可用的空间", rtos.get_fs_free_size())-- 打印剩余FALSH,单位Byte end, 10000) ]]