4

I'm having trouble with an industrial Linux computer I'm working with to achieve communication over an RS485 bus with multiple connected devices. What I've encountered is that the IO pins used by the RS485 USART driver are set to different levels at startup instead of going to the RS485 idle/tri-state. As a result, the other devices on the bus are blocked for more than 30 seconds while the device boots up, triggering all sorts of external problems. The course of events can be viewed in the attached image, where I've measured the output voltages with an oscilloscope during startup.

My guess is that the actual driver is not started until the voltage levels reach their tri-state levels (e.g. ~2.2V for this device). After that everything works as expected.

I've tried to find any config-files to set the default IO level of the pins at boot (thinking this may be set by the bootloader) to no avail.

Also, I've tried to apply a startup-script to run "early enough" to set DATA- high, but the device in question does not provide any interface to control these pins as regular GPIOs as far as I can tell.

Any help, tips or insights would be much appreciated!

EDIT: I am not an experienced Linux developer, so please highlight if I've left out any important details.

Some specs:

  • ARM920T rev 0 (v41) CPU
  • Proprietary distribution of Linux 2.6
  • Uses Busybox
  • Atmel USART drivers

Extract from boot log:

Linux version 2.6.28.10 (root@) (gcc version 4.1.2) #94 PREEMPT Tue Oct 29 10:22:19 CET 2013
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0003177
/...
.../
RS485 mode for port /dev/ttyS3 enabled
/...
... (I'm guessing the ~30 secs elapse here)
.../
atmel_usart.3: ttyS3 at MMIO 0xfffcc000 (irq = 9) is a ATMEL_SERIAL
atmel_serial.3: Putting the RS485 RTS pin down
/...
...
.../

Full boot log: https://drive.google.com/file/d/0B2XYl1mNCa8jNUZ5V0Nic1hkU0U/view

Similar issue:

Possibly a similar issue is discussed here: UART initialisation: Prevent UART to pull RTS high
But I'm not sure how to proceed with the suggested solution.

RS485 output during startup from my device

Community
  • 1
  • 1
Stenis
  • 118
  • 9
  • Which driver are you using? Is there an external controller/transceiver running the bus? Some more information on the hardware would help. – user2205930 Apr 04 '16 at 07:47
  • Hi! I've added some specs to the OP. I've found Atmel drivers in the filesystem, but I'm unsure of the HW driver (transceiver). I could crack open the casing and have a look around, but I'd rather not since it is sealed. I do wish I had a schematic, but it is not provided by the manufacturer. – Stenis Apr 04 '16 at 08:04
  • @user2205930 which ARM are you using exactly? – KernelPanic Apr 04 '16 at 08:13
  • @KernelPanic ARM920T rev 0 (v41) CPU – Stenis Apr 04 '16 at 08:19
  • 1
    You can get much more info (e.g the boot log) from the SoC serial debug port, so connecting to the serial console is essential to further progress IMO. Serial ports are normally initialized early in the kernel boot, so you need to correlate the RS485 states with system boot activity. You'll probably need to identify the RS-485 transceiver chip that is used, so that you'll know the proper logic for its control inputs (e.g. drive DE low and RE- high). Atmel didn't have too many SoCs that used ARM920T; you probably have a AT91RM9200. – sawdust Apr 04 '16 at 19:09
  • which bootloader are you using? – Samrat Das Apr 05 '16 at 09:14
  • @sawdust Thank you for your comment. I will have to dig a little deeper and see what I can find out. – Stenis Apr 05 '16 at 09:49
  • @SamratDas Unfortunately, I do not know and don't know how to find out. – Stenis Apr 05 '16 at 09:49
  • which board from which company are you using? the BSP you are using is supplied by same vendor? – Samrat Das Apr 05 '16 at 09:55
  • I've managed to do some more digging, finding a program (dmesg) that prints out the boot log. I've added some of the contents to the Q, but not sure how helpful it is more than confirmning that its all handled through the bootloader. I presume RTS is high by default, and is set to low after the ~30 seconds. Is this normal behaviour for UART configured for RS232? – Stenis Apr 07 '16 at 08:50
  • 1
    can you provide some more boot log? I am not sure this action taken during kernel initialization or by any user space program. – Samrat Das Apr 07 '16 at 12:00
  • @SamratDas I've added a link to the full boot log to the Q. It's: https://drive.google.com/file/d/0B2XYl1mNCa8jNUZ5V0Nic1hkU0U/view It also contains more information about the system. – Stenis Apr 07 '16 at 12:24
  • 1
    Your guess of *"the ~30 secs elapse here"* is not reasonable. There should be no reason for a kernel to take that long to get through that phase of initialization. What is the starting point of of this 30 sec delay? Where's the console output that corresponds to this starting point? (e.g. *before* the kernel starts?) You need to put the 'scope and computer monitor next to each other to correlate the events. – sawdust Apr 07 '16 at 18:17
  • @sawdust Sorry for the late response. The 30 seconds is timed from the instance the RS485 pins are initially set. Probably this is right when power is applied to the device, but I'll check that to be sure. Unfortunately I haven't had any success in connecting through a serial cable (using FTDI rs232/USB converter), only getting gibberish although I've set it up correctly. Would probably give me some more information seeing the boot print i real-time and correlating this to the "~30 sec", which as you say is probably not reasonable once the boot printout starts. – Stenis Apr 12 '16 at 07:56

3 Answers3

1

This is little more than wild speculation, but it might be worth adding a start-up script that echoes a NULL character to the device (e.g. /dev/ttyS1 or whatever) as early as possible during start-up. This might be enough to kick the driver into initialising the hardware.

You could also try to locate the driver in the Linux source to look at how it starts up.

Ian Goldby
  • 5,609
  • 1
  • 45
  • 81
  • Thanks for the good advise. However, I couldn't figure out a way to make this early enough (tried from e.g. rcs startup scripts) – Stenis Apr 05 '16 at 09:44
  • 2
    these things also comes into play after kernel booted up, means 10-20 seconds – Samrat Das Apr 05 '16 at 09:53
  • @SamratDas Seems you are correct here. See the bot log I've inserted to the Q - shows that everything happens during boot. – Stenis Apr 07 '16 at 11:22
1

Probably you have access to the source code, so you can investigate who and when mess with the that GPIO. Just grep the kernel source for the atmel gpio controller port addresses to figure out what happen. If you are lucky may be there will be kernel command line option that you can pass from the bootloader to set the line to what you need in advance.

1

this answer may work if you can find required things mentioned below of your board!

Once I also had a same issue on PWM. There I found that my bootloader was responsible for the same, I changed in bootloader configuration and it started working fine.

Check your BSP provided by board vendor or third party (If you have the source), If your bootloader is U-boot you can find it inside U-boot-(source)/include/configs/(your-board).h there you can find configuration for RS484. As per your datasheet for the board you can check for other things which are muxed on the same pin and disable those if not required for boot time and enable RS485.

enabling/disabling can be done by changing the values 0, 1 or 2 as per your configuration and also you can simply disable anything just by commenting // out the line.

Samrat Das
  • 1,781
  • 1
  • 21
  • 33
  • Unfortunately, it doesn't seem I have U-boot (but I can't tell what I have really). There is no such directory and I've grep'd for *.h-files to no avail. Thanks for your suggestions and persistence to help me! – Stenis Apr 07 '16 at 14:03