Shell脚本翻译串口十六进制信息

嵌入式系统的外设日志记录着串口发给主机的报文信息,报文内容是16进制,监控状态和问题的时候往往需要人去对照协议或者记住16进制报文的含义,所以写了这个脚本来翻译日志,让其更为直观易读。

协议对照文本

将报文协议写在一个ini文件内,便于查找翻译,根据协议特点按行写、按字节写、甚至按不同的位写。比如:

[PROTOCOL]
[Modes status]
[gate configuration]0,0=| Entry End |=END
[gate configuration]0,1=| Exit End |=END
[gate configuration]1,0=| Reversible |=END
[gate mode]0,0,0=| Out of service |=END
[gate mode]0,0,1=| Entry mode|=END
[gate mode]0,1,0=| Exit mode|=END
[gate mode]0,1,1=| Free Exit mode|=END
[gate mode]1,0,0=| Bi-directional mode|=END
[gate mode]1,0,1=| Fully free mode|=END
[gate mode]1,1,0=| Maintenance mode|=END
[gate mode]1,1,1=| Emergency mode|=END
[aisle mode]0=| Normally closed |=END
[aisle mode]1=| Normally opened |=END
[NormalByte]
[General status]:bits=0 2 4 6 7=END
[General status]:bit0_0=\033[1;35m | Flap OK  |\033[0m =END
[General status]:bit0_1=\033[1;31m**Flap failure**\033[0m =END
[General status]:bit2_0=\033[1;35m | Repair Door Closed  |\033[0m =END
[General status]:bit2_1=\033[1;31m**Repair Door Opened**\033[0m=END
[General status]:bit4_0=\033[1;35m | No Passage Cancellation  |\033[0m =END
[General status]:bit4_1=\033[1;31m**Cancellation on Time-out**\033[0m=END
[General status]:bit6_0=\033[1;35m | No Emergency  |\033[0m =END
[General status]:bit6_1=\033[1;31m**Emergency Mode**\033[0m=END
[General status]:bit7_0=\033[1;31m| LCM Not Configured  |\033[0m =END
[General status]:bit7_1=\033[1;35m **LCM Well Configured**\033[0m =END

[Zone status]:bits=0 1 2 3 4 5 6 7=END
[Zone status]:bit0_0=\033[1;35m | zone 1 clear  |\033[0m =END
[Zone status]:bit0_1=\033[1;31m**zone 1 occupied**\033[0m =END
[Zone status]:bit1_0=\033[1;35m | zone 2 clear  |\033[0m =END
[Zone status]:bit1_1=\033[1;31m**zone 2 occupied**\033[0m =END
[Zone status]:bit2_0=\033[1;35m | zone 3 clear  |\033[0m =END
[Zone status]:bit2_1=\033[1;31m**zone 3 occupied**\033[0m =END
[Zone status]:bit3_0=\033[1;35m | zone 4 clear  |\033[0m =END
[Zone status]:bit3_1=\033[1;31m**zone 4 occupied**\033[0m =END
[Zone status]:bit4_1=\033[1;31m**intrusion!**\033[0m =END
[Zone status]:bit5_1=\033[1;31m**Sensor test in progress!**\033[0m =END
[Zone status]:bit6_1=\033[1;31m**Through beam sensor!**\033[0m =END
[Zone status]:bit7_0=\033[1;35m| direction:Entry|\033[0m =END
[Zone status]:bit7_1=\033[1;35m|direction:Exit|\033[0m =END

[Fraud Status]:bits=0 5 6=END
[Fraud Status]:bit0_0=\033[1;35m | Flaps are not forced |\033[0m =END
[Fraud Status]:bit0_1=\033[1;31m**Flap forced!!**\033[0m =END
[Fraud Status]:bit5_0=\033[1;35m | No Wrong Way Fraud  |\033[0m =END
[Fraud Status]:bit5_1=\033[1;31m**1 Wrong Way Fraud!!**\033[0m =END
[Fraud Status]:bit6_0=\033[1;35m | No Tail Gating Fraud |\033[0m =END
[Fraud Status]:bit6_1=\033[1;31m**1 Tail Gating Fraud !!**\033[0m =END
[INI]
    GetAllReg(读取所有寄存器)= 01 03 00 96 00 07 E4 24 
    SetDialogDetection(保持PLC活跃)= 01 06 00 72 00 01 E8 11 
	ResponseofSetMultiReg(收到配置命令)= 01 10 00 64 00 16 00 18 
	Normally Close and Bi_Dir mode(设置常闭双向模式)= 01 06 00 64 A4 01 73 15 
	Normally Close and OOS mode(设置常闭OOS模式)= 01 06 00 64 A0 01 71 D5 
	Normally Close and Entry mode(设置常闭单进模式)= 01 06 00 64 A1 01 73 15 
	Normally Close and Exit mode(设置常闭单出模式)= 01 06 00 64 A2 01 71 D5 
	Normally Open and Bi_Dir mode(设置常开双向模式)= 01 06 00 64 B4 01 73 15 
	Normally Open and OOS mode(设置常开OOS模式)= 01 06 00 64 B0 01 71 D5	
	Normally Open and Entry mode(设置常开单进模式)= 01 06 00 64 B1 01 73 15 
	Normally Open and Exit mode(设置常开单出模式)= 01 06 00 64 B2 01 71 D5 
	TEST_Sensor_Start= 01 06 00 6B 05 00 FB 46 
    TEST_Flap_Start= 01 06 00 6B 04 00 FA D6 
    TEST_Signage_Start= 01 06 00 6B 06 00 FB B6 
    TEST_StopAll= 01 06 00 6B 00 00 F8 16 

主程序

ParseLog  $logfilenamestr	

ParseLog子程序

ParseLog()
{	
	fname=$1
	curLine=`awk 'END{print NR}' $fname`
	while true
	do		
		NewLine=`awk 'END{print NR}' $fname`  #line numb in process
		if (( ${curLine} < ${NewLine} ))
		then
			newStr=`sed -n "${curLine}p" $fname`  #line string
			echo ${newStr} 			
			newCode=`echo ${newStr} |awk -F'<<' '{print $2}'`      #com code
			if [ "${newCode}" ]
			then	
				echo -e "\t 收到 ${newCode} 解析:"
				findstr=${newCode}	
				if [[ ${findstr:1:8} == "01 03 0E" ]]  #read All Register		
				then 
					portstr=`Parse_AllReg  ${findstr}` #函数返回字符串
					echo -e "\033[1;35m $portstr \033[0m" 
				else
					parsedStr=`grep "${findstr}" $iniFile| awk -F'=' '{print $1}'`
					if [ "$parsedStr" ]
					then 
						echo -e "\033[1;35m $parsedStr \033[0m"
					else
						echo -e "\033[1;35m !!Unknown Recv!! \033[0m"
					fi
				fi
			else
				newCode=`echo ${newStr}  |awk -F'>>' '{print $2}'`
				echo  -e "\t 发送 ${newCode} 解析:" 
				findstr=${newCode}				
				if [[ ${findstr:1:14} == "01 10 00 64 00" ]]  #Send out PDU configuration	
				then
					ConfigStr=`Parse_Config  ${findstr}` #函数返回字符串			
					echo -e "\033[1;35m ${ConfigStr} \033[0m" 
				else
					parsedStr=`grep "${findstr:1:14}" $iniFile| awk -F'=' '{print $1}'`
					if [ "$parsedStr" ]
					then 
						echo -e "\033[1;31m $parsedStr \033[0m"
					else
						echo -e "\033[1;31m !!Unknown Sendout!! \033[0m"
					fi
				fi
			fi
			curLine=`expr ${curLine} + 1`
		fi
	done

}
  • 先读取log文件,在循环中取出最新的一行:行号NewLine,新行内容存在newStr
  • 本例选了一个Modbus 串口报文的设备
  • 读到新行内容后,用awk 取不同的字节,做分析
  • 有些需要在协议ini文件里查找翻译的子程序如下(其实就是用grep查找文本,找到需要翻译的报文所在行,再用awk分开“=”两边,取出解释性的文本):
iniFile='/root/protocol.ini'
 
function GetSpecificBit()
{	
	_Byte=`echo "ibase=16; $1"| bc`   #16进制转10机制
	_Bit=$2
	_ret=$[ ${_Byte} >> ${_Bit} & 1 ]	
	echo $_ret
}
function ParseNormalByte()
{
	strRet="$1 Value $2: \n"
	strFind="\[$1\]:bits"
	_bits=`grep "${strFind}" $iniFile| awk -F'=' '{print $2}'`
	for _ibit in $_bits
	do
		#echo "_ibit = ${_ibit}"
		_bitVal=`GetSpecificBit ${2} ${_ibit}`
		#echo "_bitVal = ${_bitVal}"
		strFind="\[${1}\]:bit${_ibit}_${_bitVal}"
		#echo "strFind = ${strFind}"
		_bitStr=`grep "${strFind}" $iniFile| awk -F'=' '{print $2}'`
		#echo "_bitStr = ${_bitStr}"
		strRet="${strRet} ${_bitStr}"
		#echo "strRet = ${strRet}"
	done
	echo ${strRet}
}
function ParseModeStatusByte()
{
	strRet="$1 Value $2: \n"
	strFind="\[gate configuration\]"
	_bitVal=`GetSpecificBit ${2} '7'`
	strFind="${strFind}${_bitVal}"
	_bitVal=`GetSpecificBit ${2} '6'`
	strFind="${strFind},${_bitVal}"
	_bitStr=`grep "${strFind}" $iniFile| awk -F'=' '{print $2}'`
	strRet="${strRet} ${_bitStr}"
	
	strFind="\[aisle mode\]"
	_bitVal=`GetSpecificBit ${2} '4'`
	strFind="${strFind}${_bitVal}"
	_bitStr=`grep "${strFind}" $iniFile| awk -F'=' '{print $2}'`
	strRet="${strRet} ${_bitStr}"
	
	strFind="\[gate mode\]"
	_bitVal=`GetSpecificBit ${2} '2'`
	strFind="${strFind}${_bitVal}"
	_bitVal=`GetSpecificBit ${2} '1'`
	strFind="${strFind},${_bitVal}"
	_bitVal=`GetSpecificBit ${2} '0'`
	strFind="${strFind},${_bitVal}"
	_bitStr=`grep "${strFind}" $iniFile| awk -F'=' '{print $2}'`
	strRet="${strRet} ${_bitStr}"
	
	echo ${strRet}
}

运行界面

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

code .

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值