简体   繁体   中英

How to set baud rate on serial port on Raspberry PI?

I have the following .NET Core 2.0 C# code:

using System;
using System.Runtime.InteropServices;

namespace TestSerial
{
    class Program
    {
        [Flags]
        public enum OpenFlags
        {
            O_RDONLY = 0,
            O_WRONLY = 1,
            O_RDWR = 2,

            O_NONBLOCK = 4,
        }

        [DllImport("libc")]
        public static extern int cfsetspeed(byte[] termios_data, long speed);

        [DllImport("libc")]
        public static extern int tcgetattr(int fd, [Out] byte[] termios_data);

        [DllImport("libc")]
        public static extern int tcsetattr(int fd, int optional_actions, byte[] termios_data);

        [DllImport("libc")]
        public static extern int open(string pathname, OpenFlags flags);


        static void Main(string[] args)
        {
            const string serialDevice = "/dev/serial/by-id/usb-ELT_SENSOR_EK100_V1.0_SN000001-if00-port0";

            int fileDescriptor = open(serialDevice, OpenFlags.O_RDONLY | OpenFlags.O_NONBLOCK);
            Console.WriteLine($"Libc.open returned {fileDescriptor}");

            byte[] termiosData = new byte[256];

            int result = tcgetattr(fileDescriptor, termiosData);
            Console.WriteLine($"Libc.tcgetattr returned {result}");

            result = cfsetspeed(termiosData, 38400);
            Console.WriteLine($"Libc.cfsetspeed returned {result}");

            result = tcsetattr(fileDescriptor, 0, termiosData);
            Console.WriteLine($"Libc.tcsetattr returned {result}");
        }
    }
}

The program should change the baud rate of an USB serial port to 38400. But, the program does not work as expected.

This is the output from running the program:

Libc.open returned 18
Libc.tcgetattr returned 0
Libc.cfsetspeed returned -1
Libc.tcsetattr returned 0

I have also double checked the serial port settings and it is indeed unchanged:

$ sudo stty -a -F /dev/serial/by-id/usb-ELT_SENSOR_EK100_V1.0_SN000001-if00-port0
speed 9600 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke -flusho -extproc

What could be reason for the error returned from Libc.cfsetspeed?

The problem was an incorrect data type (long) in the declaration of the speed parameter for the cfsetspeed function. The datatype for the speed parameter should be uint.

This is the correct code:

using System;
using System.Runtime.InteropServices;

namespace TestSerial
{
    class Program
    {
        [Flags]
        public enum OpenFlags
        {
            O_RDONLY = 0,
            O_WRONLY = 1,
            O_RDWR = 2,

            O_NONBLOCK = 4,
        }

        [DllImport("libc")]
        public static extern int cfsetspeed(byte[] termios_data, uint speed);

        [DllImport("libc")]
        public static extern int tcgetattr(int fd, [Out] byte[] termios_data);

        [DllImport("libc")]
        public static extern int tcsetattr(int fd, int optional_actions, byte[] termios_data);

        [DllImport("libc")]
        public static extern int open(string pathname, OpenFlags flags);


        static void Main(string[] args)
        {
            const string serialDevice = "/dev/serial/by-id/usb-ELT_SENSOR_EK100_V1.0_SN000001-if00-port0";

            int fileDescriptor = open(serialDevice, OpenFlags.O_RDONLY | OpenFlags.O_NONBLOCK);
            Console.WriteLine($"Libc.open returned {fileDescriptor}");

            byte[] termiosData = new byte[256];

            int result = tcgetattr(fileDescriptor, termiosData);
            Console.WriteLine($"Libc.tcgetattr returned {result}");

            result = cfsetspeed(termiosData, 38400);
            Console.WriteLine($"Libc.cfsetspeed returned {result}");

            result = tcsetattr(fileDescriptor, 0, termiosData);
            Console.WriteLine($"Libc.tcsetattr returned {result}");
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM