Is the baud rate for the uarts limited

  • Hi,


    we use the PicoCOM4 with a self compiled version of the latest 1.4 Kernel. And run now in the problem that the port ttySAC1 seams not to run on the right baud rate. I changed the serial example to cfsetispeed(&options, B115200);
    cfsetospeed(&options, B115200);


    where case B115200: inputSpeed = 115200; break;


    after opening the port I send known data to the port but only get crap. For control I read the stream with a logic analyzer in parallel. These data is correct. I notized that the logic analyzer determined the baud rate of some packages I send from the ttySAC1 to the test device is only 39215 bps.


    Any idea where this behaviour comes from? I suspected the serial console in the kernel parameters, but redirecting the console to tty0 doesn't change anything.


    Sincerely yours


    Christian Moll

  • The serial console is by default configured for 38400 bps. This is done in NBoot. However this is no big deal as NBoot does not send anything during a standard boot sequence. But then U-Boot is starting. U-Boot will output some messages and will use 38400 for this. The kernel will use the speed that is configured on the kernel command line, i.e. in the bootargs variable in U-Boot. And finally buildroot may also use a fix speed when starting its getty on the serial line (see /ect/inittab).


    So you have to change the speed in several places:


    1. U-Boot (can be done by setting some environment variable as far as I know)
    2. Kernel (can be done by setting the bootargs variable in U-Boot)
    3. The getty in buildroot (/etc/inittab)
    4. In your own application


    Your F&S Support Team

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • Thanks for your reply.


    I redirected the kernel console to /dev/tty0 (no speed specified) by console=/dev/tty0
    And disabled the framebuffer console support in the Kernel.
    I commented the getty call in inittab.
    I didn't change anything for the uboot.
    I set the speed with the simpleserial example. Once to B19200 and once to B115200 (which I added to the switch case statement).


    When sniffing on the serial line with a logic analyzer I always get 38400 as a result for the outgoing stream.
    Is it really necessary to change the speed on all stages? My understanding was that I only have to redirect the kernel console and set the speed I like to have via terminos API.


    Any idea?


    Christian Moll



    P.S.
    With setserial -a I get:


  • Just to be sure: you set the serial speed in your program and use the serial line directly within the same program? Or do you set the serial speed with one program and then want to output data in a different program, without setting the speed again? The second approach will not work. When the serial port is closed again, the port is reset again to the original speed. So the second program will use the default speed again. You always have to set the speed when you open a serial port, before you output anything to the port. The speed is not persistent after closing the port until opening it again.

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • Did some more research on the problem.


    When I change
    #define CONFIG_BAUDRATE 57600
    in the picocom4.h of the uboot 1.4 sources.


    I have the baud rate of ttySAC1 afterwards on 57600 (also checked this by the logic analyzer)


    Then I found a interesting comment in the file mach-picocom4.c of the Kernel


    Quote

    /* UART1 is the debug port and it is already configured by the boot
    loader U-Boot/NBoot; nothing to do here */


    looks for me that the console I set in the bootargs is not respected in total. In my understanding it should close the serial port I use to access the uboot and open the device I specified in the bootargs with the given speed. And the device not used for the console should be fully usable after Kernel is up.

  • The comment in the Linux file simply means that we do not need to configure the pin multiplexing (UART function) and pad control (pull-up/down, drive strength, etc) anymore as it was already done earlier. This has nothing to do with the baud rate. As you can see, the other ports also don't get any baud rate set in this place.


    And yes, if you set a baud rate in U-Boot, then this baud rate will be used in U-Boot, and if you don't set a different baud rate for Linux, it will also be used as default baud rate in Linux. So if you open this port in Linux and don't set your own speed, you will get this baud rate.


    Let's summarize.


    Case 1: You set "console=ttySAC1,sss" in U-Boot
    Then the kernel will open this serial line with the given speed sss to send boot messages. Then the Buildroot system takes over and the init function will execute /etc/inittab. There a getty is started, that also uses the debug line. This used to be a fix port (ttySAC1) and a fix speed (38400), but in V1.4 this was changed and now the getty is opened on the first console found in /proc/consoles and the speed is left on the kernel default. Whether this now results in the speed configured in U-Boot or the one set with console= above I can not say at the moment. I would have assumed that it is the speed set with console=, but if the console is actually closed again before getty is started, then the speed of this port may be reset to the default speed, i.e. the speed promoted by U-Boot.


    Case 2: You don't set "console=ttySAC1,sss" in U-Boot
    Then the kernel will not open the serial console and in V1.4 there will also be no getty on the serial port. So the speed of ttySAC1 will remain at the default speed, i.e. the speed set in U-Boot.


    In any case
    However in any case, if you want to use this port, you have to open the ttySAC1 device and as one of the first actions you set a new speed, transfer format, flow control, etc for this file handle. And when doing this, you can set whatever speed you like. This speed will remain active until you close the filehandle again and then the port will either stay on this speed or it may switch back to the default speed, whichever it is what Linux does when a port is closed.


    So using a serial port is always:


    1. open the port
    2. set transfer speed and other transmission parameters
    3. use the port
    4. close the port


    And *not*:


    1. open the port
    2. use the port
    3. close the port


    Because then you'll never know for sure what the default parameters are and you may end up sending crap.


    So where is the problem? Why can't you set a speed after opening the device and before sending/receiving anything? Or do I miss your point?


    Your F&S Support Team

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • Seams so.


    I repeated the hole experiment.


    1. new PicoCOM4
    2. I installed the 1.4 Kernel provided by F&S
    3. I installed the buildrootFS 1.4 provided by F&S
    4. set root password to access by ssh, deleted S99.. S35... and S01fs... scripts in /etc/init.d
    5. changed bootargs console to console=tty0
    6. commented out the the getty line in /etc/inittab. (removed it to be sure it has not a side effect)
    7. reboot the system and executed the simpleserial example. See source code below...


    Quote

    Case 2: You don't set "console=ttySAC1,sss" in U-Boot
    Then the kernel will not open the serial console and in V1.4 there will also be no getty on the serial port. So the speed of ttySAC1 will remain at the default speed, i.e. the speed set in U-Boot.


    The example states that the baud rate was 9600! In the u-boot the baud is set to 38400!
    The example also states that the speed is set to 115200bps, and writes "Testmessage" to the port.
    I record this "Testmessage" with a logic-analyzer. It has some nice protocol analysis features like determine the baud rate and what data where in the stream.
    It says the speed is ~38400bps and the Message was "Testmessage". If I set it to 1115200bps it only gets crap as incoming message.


    As you can see below the port is set to 115200 8N1.


    Quote

    So using a serial port is always:


    1. open the port --> fopen(...)
    2. set transfer speed and other transmission parameters --> initport(...)
    3. use the port-->write(...)
    4. close the port-->close(...)


    Looks like the example is doing as you described.


    To summarize.
    1. Buad rate set in u-boot doesn't have an effect on default baud rate when console=<virtual console> is set in bootargs. Terminos claims that it is 9600 on first open.
    2. Setting baud rate with terminos claims the right buad is set, but in real it stays on the rate set in u-boot.


    If I repeat the experiment with a different baud rate set in u-boot. That baud rate will be the measured value by the logic analyzer.


    So why is the the speed not set? Why is the first speed read out of the port 9600 and not the one from the u-boot?


  • OK, i have checked the serial driver and found some special handling for the debug port (ttySAC1) on PicoCOM4, that may have had some meaning in the past, but I don't see that it is still required today. This special handling causes the baud rate setting not to function correctly. The following patch will remove this special handling and then the serial port speed should behave as expected.


    Sorry, I was not aware that this special handling existed in the kernel.



    The patch is also attached to this posting. Just go to the top directory of the kernel source and type


    Code
    1. patch -p1 < Remove-special-handling-of-debug-port.patch


    Then recompile the kernel.


    Sorry for the inconvenience.


    Your F&S Support Team

    Files

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • Hello,


    thanks for the patch. I applied it, but didn't made it better. The ttySAC0 doesn't talk at all now. Openening and setting baud in terminos still gives the right answers, but the test message is now not send and simpleserial example doesn't close the port any more.


    On ttySAC1 is sending data out, but the closing of the port hangs the simpleserial example too.


    Any educated guess?


    Christian Moll

  • We will investigate this further, but at the moment we have to bring a Vybrid release on the way.

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • Hello,
    I tried your program with a new Kernel V1.4 and the patch above and it worked.


    All steps I did: I downloaded and installed the newest available Kernel source (V1.4) and the newest toolchain (4.7.2). The above patch was applied in the kernel root path (e.g. ~/linux/linux-2.6.38-f+s-V1.4/). Then I built the kernel with make picocom4_defconfig and make.


    After downloading and starting the kernel on the PicoCOM4, I remounted the rootfilesystem (mount -o remount,rw /) and created a new user telnet (adduser -D telnet) with no password (passwd -d telnet). The telnet client needs to be started on booting. So the file /etc/S70telnetd was created with the following lines:


    Shell-Script
    1. #!/bin/sh
    2. ifconfig eth0 10.0.0.27 up
    3. telnetd


    In the file /etc/inittab I commented the login_tty configuration and removed the console in the uboot. To do this I viewed my enviroment variables with printenv bootargs and then copied everything from bootargs. The content of the bootargs variables is listed below.


    Code
    1. mtdparts=pc4nand0:3m@0x100000(Kernel),-(TargetFS) init=linuxrc root=/dev/mtdblock1 rw rootfstype=jffs2 ethaddr=00:05:51:04:9B:F3


    Then I rebooted the board, logged in via telnet and started your test program. After those steps a serial connection with 115200 baudrate showed “Testmessageâ€. It also worked with ttySAC0.

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • Hello,


    something is different on the two systems. I have done the hole thing today two times with different PicoCOM4 boards. Both have the the buildroot and uboot 1.4 installed. Everything is default.
    Kernel is patched as you described and the inittab is edited. in init.d I removed the S01fssetup.


    I tested on first board without telnet and with it. But I guess it is only for remote access, I normally use the ssh server that is already running.


    If I do so the ttySAC1 doesn't speak at all independent of the set speed. ttySAC0 is working as expected.
    Interesting is that I can run the simpleserial example two times the third time it hangs on closing the interface. I expect its buffer is full or something like that.


    Maybe you can send me your Kernel Image and I can test it.


    Best Christian

  • Hello,


    I’m sorry, but we cannot reproduce your problem.


    Could you please provide us with a step-for-step instruction, what you do, starting with the download of the newest kernel sources. Please also use the newest toolchain (4.7.2) and the provided binaries of the uboot and rootfs.


    Best regards, Micha

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • Hello Micha,


    okay found the problem. I was not started with fresh sources in the last attempt from yesterday. There were the lines


    Code
    1. //Baudrate bug
    2. if(port->line == 0 && (rd_regl(port, S3C2410_UBRDIV) >= 0x1B1)) {
    3. udelay(500);
    4. }


    commented. I managed to do all the patches necessary to run our capacitive touch and display and it seams to run now without a flair.


    Thanks for your help.


    Christian

  • Hello Christian,
    I am glad you found the problem. Good to hear that your system runs now.
    Best regards,
    Micha

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.