FsuOS调试相关

FsuOS提供了比较丰富的调试方法用于解决实际工程中的接入问题。

B接口下发命令调试

现在环节比较多:
B接口平台 - FSU网站B接口 - FSU控制程序 - 串口抢断 - A接口协议下发 - 设备回复
用户在进行远程开门,空调开关机等操作的时候,有时候会遇到执行报错的情况,这时候需要按环节一步一步排查:

  • 先确认B接口平台和Fsu网站B接口网络是否是通的,一般情况FSU B接口会使用8080端口,可以直接打开FSU http://ip:8080 会显示wsdl界面。
  • 可以从Fsu网站的实时数据界面,直接向控制程序下发B接口命令,根据B接口ini映射配置,一般会出现操作按钮。主要核对要调用的B接口信号是否一致。
  • FSU控制程序,主要看是否在运行,目标设备的驱动程序是否加载,通信/数据刷新是否正常。
  • 串口抢断,通常情况下,即使不同类型的设备混接在一起,当收到控制命令,会强行中断正在执行的设备招测命令,等待2秒清空后,再执行控制命令。这个情况大部分时候工作都是正常的。有时候也观察到,如果设备接的确实比较乱,有时候数据无法完全清空,造成接收下发命令回复不稳定,反馈失败。
  • A接口协议下发,主要还是核对下发的信号ID对应的命令是否符合预期,是否下发。因为完全依靠B接口的信号ID作为控制命令。
  • 设备回复,看设备是否回复,回复结果是否正确。

一个串口能并接多少个设备

原理上,只要设备电气性能顶的住,FsuOS软件没有做限制。
实际情况。串结过多会造成调试困难,由于不同类型的设备协议不一样,需要小心避开协议冲突,观测调试数据需要更多时间。顺的时候比较顺,不顺的时候,可能会相当不顺,得搞清楚为啥不行。
同时,串联过多,对下发命令的稳定性也有影响,抢断功能,可能会遇到数据清空问题。

FsuOS适配层调试

  • FsuOS网站
    用户通过登录FsuOS网站,点击"设置"->“实时数据查看”,可以看到当前采集器AI,DI,DO通道值。
  • SMDDevice开调试
    用户通过编辑SMDDevice.conf配置文件,打开
    log_fial=1
    或者启动SMDDevice时传递参数
    ./SMDDevice –log_fial=1
    此时主要看打印,就会打印采集的DI,AI值

需要注意的是,AI值,有时候是0-5v或者4-20ma的映射值,有时候是实际的电压(53.5V)或者电流输入值(-20.3A),有时是实际的温湿度值(28.3度),这个需要根据实际FSU的外部接口确定。 用户可以查询 https://www.fsuos.com/docs/fsu-supported/ 来确定。

串口调试

  • FsuOS网站
    用户通过登录FsuOS网站,点击"测试"->“串口测试”,选择一个串口,比如1,点击"连接",下方"请求日志"里显示”连接成功",通讯数据里就会打印选中串口的收发数据。

  • SMDDevice串口数据打印
    由于部分FSU设备上,FsuOS没有实现网站查看串口通讯的功能(比如EISU),个别设备由于网络原因,也会造成网站的串口数据无法查看,此时我们就使用最基本的方式。
    用户通过编辑SMDDevice.conf配置文件,打开
    log_sp=1 # 打开串口打印
    sp_debug=0 # 开串口1的打印,SMDDevice内部是从0开始的
    sp_debug=7 # 开串口6的打印
    然后启动
    ./SMDDevice
    此时注意看:就会看到CMD_DATA Port 0: 01 03 这种发送信息,还有串口0收到数据:01 03 这种接收信息。

串口的工作方式

FsuOS的串口程序默认使用的boost的ASIO的异步读写方式,有时候由于底层FSU操作系统驱动实现不标准(gfsu2),造成通信不稳定,卡死,此时我们可以切换串口模式为 select模式+read模式。
用户通过编辑SMDDevice.conf配置文件,打开
sp_sync=0 # 将串口1改为同步读模式
sp_sync=5 # 将串口6改为同步读模式

DeviceIoControl 函数的状态问题

特别容易出错

int DeviceIoControl(int ioControlCode, const void* inBuffer, int inBufferSize, void* outBuffer, int outBufferSize, int& bytesReturned)
{
    switch(ioControlCode) {
	case 1: {
		ioRet = -1;
		OpenPort();
        state = ioControlCode;
		//do something
		break;
	}
	case WRITE_CURRE
    {
        break;
    }
}

这个执行操作的时候,我们通常会把ioControlCode直接作为状态码。 这时候要小心的是:
state = ioControlCode;
不要写在一开始的地方,因为DeviceIoControl的调用方式,是先发命令,然后重试等待获取结果,比如下发开机命令ioControlCode=50,紧接着就会下发ioControlCode=51问结果,51这个命令不应该修改state,会造成判断结果代码不正常。