0

我实现了一个维护与不同端口的串行通信的代码。

但是,相同的代码在 USB 端口 /dev/ttyUSB0 上运行良好,但在端口 /dev/ttyAMA0 上无法运行(如果我使用 PI4J 库,此端口正在运行)

波特率:

/dev/ttyAMA0 - 115200
/dev/ttyUSB0 - 9600

我在带有 Java 9 的树莓派 3B 上运行

我在这里缺少什么?

这是我的代码:

public class JSerialComm extends BaseSerial
{
    private SerialPort serial = null;
    private Object recLock = new Object();
    
    public JSerialComm()
    {
        super();
    }
    @Override
    protected boolean checkIsClosed()
    {
        return this.serial == null || !this.serial.isOpen();
    }

    @Override
    protected void registerToSerialEventListener()
    {
        
        this.serial.addDataListener(new SerialPortPacketListener()
        {

            @Override
            public void serialEvent(SerialPortEvent event)
            {
                try
                {
                    synchronized (recLock)
                    {
                        if(event.getSerialPort().bytesAvailable()>=getPacketSize())
                        {
                            final byte[] newData = new byte[getPacketSize()];
                            event.getSerialPort().readBytes(newData, getPacketSize());
                            
                            notifyHandlers(newData);
                        }
                    }
                }
                catch(Exception e)
                {
                }
            }

            @Override
            public int getListeningEvents()
            {
                return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;
            }

            @Override
            public int getPacketSize()
            {
                return MindoLifeJSerialComm.this.getPacketSize();
            }
        });
    }

    @Override
    protected int sendByteToSerial(byte[] input) throws Exception
    {       
        return sendByteToSerial(input,input.length);
    }

    @Override
    protected void openPort(String portName, int baudRate) throws Exception
    {       
        for (SerialPort port : SerialPort.getCommPorts())
        {
            if (portName.toLowerCase().endsWith(port.getSystemPortName().toLowerCase()))
            {
                serial = port;
            }
        }
        
        if(serial == null)
        {
            throw new Exception("Couldn't find port " + portName );
        }
        
        serial.setBaudRate(baudRate);
        serial.setComPortTimeouts(SerialPort.TIMEOUT_NONBLOCKING, 0, 0);
        serial.setFlowControl(SerialPort.FLOW_CONTROL_DISABLED);
        serial.setParity(SerialPort.NO_PARITY);
        serial.setNumStopBits(SerialPort.ONE_STOP_BIT);
        
        if (!serial.openPort())
        {
            
            throw new Exception("Couldn't open port " + portName + " opened with baud " + baudRate);
        }
    }
    @Override
    protected int sendByteToSerial(byte[] input, int length) throws Exception {
        int res = serial.writeBytes(input, length);
        // TODO:flush
        return res;
    }
    @Override
    protected void closePort() {
        this.serial.closePort();
        
    }
}

基类:

public abstract class BaseSerial
{
    HasSerialMessageHandler handler;
    
    private Object recLock = new Object();
    private int packetSize = 1;
    private String portName;

    protected final void notifyHandlers(byte[] newData)
    {
        if (handler != null)
        {
            handler.incoming(newData);
        }
    }
    
    private Object writeLock = new Object();

    public int write(byte[] input) throws Exception
    {
        return write(input, -1);
    }

    public int write(byte[] input, int length) throws Exception
    {
        int res = sendByteToSerial(input,length);       
        
        return res;
    }

    public void addListener(final HasSerialMessageHandler handler) throws TooManyListenersException
    {
        this.handler = handler;
        registerToSerialEventListener();
    }

    public boolean isClosed()
    {
        return checkIsClosed();
    }

    public void open(String portName, int baudRate) throws Exception
    {
        this.portName = portName;
        openPort(portName, baudRate);
        Thread.sleep(1000);
    }

    public int getPacketSize()
    {
        return packetSize;
    }

    public void setPacketSize(int packetSize)
    {
        this.packetSize = packetSize;
    }

    public void close()
    {
         closePort();
    }
    
    public String getPortName() 
    {
        return portName;
    }

    protected abstract boolean checkIsClosed();
    protected abstract void registerToSerialEventListener();

    protected abstract void openPort(String portName, int baudRate) throws Exception;

    protected abstract int sendByteToSerial(byte[] input) throws Exception;
    protected abstract int sendByteToSerial(byte[] input, int length) throws Exception;
    protected abstract void closePort();
}

初始化和使用(对于两个端口):

public class Main
{
        public static void main(String[] args)
        {
            BaseSerial serial = new JSerialComm ();
            serial.setPacketSize(14);
            
            serial.addListener(new HasSerialMessageHandler() {
            
            @Override
            public void incoming(final byte[] message)
            {               
                if (message.length > 0)
                {           
                    sysout(message);                    
                }               
            }
            
            serial.open("/dev/ttyAMA0", 115200);
        });
        }
}

/etc/inittab的设置如下:

1:2345:respawn:/sbin/getty --noclear 38400 tty1
2:23:respawn:/sbin/getty 38400 tty2
3:23:respawn:/sbin/getty 38400 tty3
4:23:respawn:/sbin/getty 38400 tty4
5:23:respawn:/sbin/getty 38400 tty5
6:23:respawn:/sbin/getty 38400 tty6

# Example how to put a getty on a serial line (for a terminal)
#
#T0:23:respawn:/sbin/getty -L ttyS0 9600 vt100
#T1:23:respawn:/sbin/getty -L ttyS1 9600 vt100

# Example how to put a getty on a modem line.
#
#T3:23:respawn:/sbin/mgetty -x0 -s 57600 ttyS3


#Spawn a getty on Raspberry Pi serial line
#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
4

0 回答 0