xeno_16550A driver install on Debian 3.8.13-bone67

Dear forum,

I have struggled for 4 days and I am out of ideas/suggestions on how to make this xeno_16550A driver work.

  1. I have successfully installed the Xenomai 2.6.4 and the Debian 3.8.13.
  2. Self-developed RTDM driver is working satisfactory.
  3. But when irq numbers are defined for the kernel installed xeno_16550A driver the boot process crashes (attached log).

Questions from Xenomai forum is:

  1. The xeno_16550A driver uses byte access, have you checked the AM33xx TRM to check that this is valid?

  2. Is the interface clock for the serial device you want to use enabled?

From the TRM it seems that the 16550 compliant UART accommodates byte accesses.

When installing and removing serial port drivers I can’t see any associated clock enabling options in the menuconfig.

Please advise.

Best regards
Terje Froysa

Boot_panic_Xeno_16550A.txt (21.4 KB)

I haven't tried getting the UARTs working with Xenomai, but have some
general suggestions if you haven't tried them already, mostly focused on
making sure the UART is actually enabled in the device-tree:

* Do you have the UART enabled in the default device-tree being loaded
by U-Boot? This should setup the clocks and other house-keeping
required to make the UART actually work at the hardware level.

* Can you build the Xenomai driver as a loadable module and try to load
it after the system boots? If so, this will make it much easier to test
variations on the running system.

* Have you tried booting without the Xenomai serial module enabled and
talking directly to the memory region used by the UART (via mmap() of
/dev/mem or similar)? This could help you get your device tree properly
setup so you know the UART is enabled before trying to boot the kernel
with the serial driver enabled.

* If it's a device-tree problem, you can boot with a working kernel and
crawl through the live device-tree (via /proc/device-tree/ocp/serial*/)
and make sure everything is as you expect.

Hi Charles,

Thanks a lot for your quick reply and reflected suggestions.
I will check them out point-by-point and check out if I find any flaws in my configurations.

Best regards
Terje Froysa

Hello Charles,

I have now carefully checked your suggestions.

  • I have checked that the UART dtbo are loaded at boot-time (by uEnv.txt)

  • I have built (and booted) the kernel with the xeno_16550A as loadable module.

  • I have checked the functionality of the /dev/ttyOx by running physical loop-back data traffic.
    The sudo cat /proc/tty/driver/OMAP-SERIAL reports the correct amount of traffic and the sent data is echoed correctly in another terminal window.

  • I have crawled the /proc/device-tree/ocp/serial* and cannot find any discrepancies.

Everything seem correct.
But the UARTs are now occupied by the omap_serial driver.
According to Xenomai (http://xenomai.org/serial-16550a-driver/) the driver should be disabled by the setserial command.
I can’t get this command working. It reports the serial port but changing it results in error (regardless of the ttyO -number):

debian@beaglebone:~$ setserial /dev/ttyO2
/dev/ttyO2, UART: undefined, Port: 0x0000, IRQ: 74

debian@beaglebone:/boot$ sudo setserial /dev/ttyO2 uart none
Cannot set serial info: Invalid argument

Consequently, I cannot load the xeno_16550A.ko module.
I have browsed the net for the same problem, but have not found relevant subjects.
There are no shared irq’s in my problem (closest subject I found).

Do you have any idea for a solution?

Best regards
Terje Froysa

Hello again,

:

setserial /dev/ttyOx usart none

I started to look at /lib/modprobe.d/aliases.conf

I wonder if it is possible to set the xeno_16550A as an alias to the major number 248 (ttyOx):

alias char-major-248-1 xeno_16540A
alias char-major-248-2 xeno_16540A
alias char-major-248-4 xeno_16540A

Would this be a feasible solution for installing the xeno_16550A driver instead of the omap_usart driver?

Best regards
Terje

Tried with an alias for the ttyO4:

alias char-major-248-4 xeno_16550A

But no reaction or error messages in dmesg, nor a change in driver link:

lrwxrwxrwx 1 root root 0 Nov 12 13:41 /sys/dev/char/248:4/device/driver → …/…/…/bus/platform/drivers/omap_uart

Do the aliases require the kernel module to be included in the kernel or am I barking up the wrong tree?

Please advice anyone…

Regards
Terje

I _think_ the problem may be that if you don't enable the serial port in
the device-tree than Xenomai encounters a bus error when accessing the
address range (not entirely unexpected, since the UART's clock is
probably turned off). But if you enable the UART in the device tree,
Linux takes control of the port and Xenomai can't access it.

Other than asking for advice on the Xenomai list, you might try booting
with the Xenomai kernel and a device tree that _disables_ the UART
you're trying to use. I would expect trying to load the xeno_16550A
module to fail (as it does when you boot the kernel with the module
enabled), but you should be able to manually setup the required
low-level hardware configuration at which point you ought to be able to
load the driver.

Or in other words, I think you need to perform the hardware setup from
the TI UART driver prior to loading the Xenomai serial driver.

Thanks Charles,

I appreciate your ideas.
I seem stuck “between a rock and a hard place” with very little substantial experiences to collect from the communities.

I will try a couple of permutations more before I may revert to using the standard Linux drivers.

I also got some comments from Xenomai (Gilles Chanteperdrix) below.

Regards
Terje Froysa

At first sight, I would say that the omap_serial driver does not implement the necessary support (probably some ioctls), for what setserial is trying to do.

I see several ways out:

  • implement the missing support in omap serial so that you can use the “setserial none” command;

  • try and use the 8250 driver instead of the omap_serial driver, since the omap serial devices are 8250 compatible, this driver supports the necessary ioctls for the “setserial none” command to work. At some point in time, I know using this serial driver for the kernel console worked, but I do not know if it was by chance (u-boot enables the clock, so the driver does not have to enable it), and if it still works;

  • do not enable any uart in the kernel configuration, neither omap_serial, nor 8250, and arrange for the clocks to be started before loading the xeno_16550a driver.

Ironically, the "omap_serial" branched from the 8250 driver around 3
years ago, currently linux-omap developers are working on merging back
to using the 8250 based driver in a future kernel version (with a big
pile of patches)..

Regards,

Gilles' 3rd option is what I was referring to trying.

The other two options seem workable as well. The best choice depends on
what you're more comfortable working with.

Ok Charles,

It doesn’t seem very promising this comment from Gilles:

I just had a quick look at the omap-serial.c driver and:

  • it does not do anything that I can see to enable its clocks
  • it does NOT use byte access but word access, that is, its registers are 16 bits wide.

Unfortunately, as far as I can tell, the xeno_16550A driver only supports byte access. So, if you want it to work, you have to modify the driver to accept a “regshift” parameter applied to all offsets and use the corresponding readw if regshift is 2 or readl if regshift is 4.

Ok Robert,

If I enable the 8250/16550 in the menuconfig this driver connects to /dev/ttySx.
The ttyO[1,2,4] appears and vanishes with the BB-UARTx dtbo’s

The ttySx devices does not work anyhow (while not enabled via any dtbo)
Is there any method of enabling the ttySx devices if a 8250 driver is preferred?
Or, a method to associate the 8250 driver with the ttyOx devices?

Regards
Terje

To utilize the 8250 driver, you will also need to change the *.dts file.

Search: http://www.spinics.net/lists/linux-omap/

You'll find all the patches required to make it work on mainline, so
you'll also have lots of fun backporting that those..

Regards,

Thanks Robert,

Just the answer I exepected (and lectured to my colleagues).
I think I will try to settle for xenomai rtdm drivers on the GPIO’s and std. Linux drivers on the uarts and spi for the time beeing.

Regards
Terje

Robert,
just for my curiosity and pease of mind:

If the 8250 have been “no mainline” for several years and there are no dtbo’s to enable it.
Why is the ttySx still there and the 8250 by default enabled in the -bone67 ?

Regards
Terje

The history goes like this..

Back in the "board" era, omap used the 8250 driver, then "new"
non-generic features where added enabling omap features, thus making
the "omap-serial" driver. Then came device tree's.. First the
omap-serial driver got it's dts bindings and all omap devices used
them. In the background, 8250 got some more generic enhancements and
generic dts bindings... Fast forward the 8250 now has even shinny-er
better features then the lagging omap-serial driver.. Thus it was
decided to move back, in a release or two..

That ^ may be childlish, but it's the condensed version of pages and
pages of discussions on linux-omap....

Regards,

Thanks Robert,
for taking your time to enlight a newbie.

The fog is slowly lifting…

Regards
Terje

Dear Terje,
Did you find how to use the 8250 driver with * .dts?

Pour utiliser le pilote 8250, vous aurez aussi besoin de modifier le fichier * .dts.

Hello Cédric

Sorry, but I had to give up my ambitions due to time pressure.

I ended up using the standard UART drivers in the Debian environment.

If you are in the same application situation as me, you may consider using standard Linux drivers:

I am implementing a sensor platform where the sensors each issues hardware interrupts that marks the time of measurement.

Sensors are: GPS (1Hz), Barometer (1Hz), Gyro-/Accelero-/Magneto-meter (4Hz-8KHz), Inertial platform (200Hz), SwarmRadio (10Hz?).

UART: GPS + SwarmRadio

I2C: Barometer + Gyro-/Accelero-/Magneto-meter

IMU: SPI

After each GPIO interrupt the data is collected by UART, I2C and SPI.

The most important rea-time task is to relate the hardware interrupts (i.e. the collected data) to a common timer.

I managed to do that by writing kernel RTDMs for the interrupting GPIO-lines.

The sensor tasks issues blocking reads towards the RTDMs that sends the timer-value from the interrupts.

The tasks then uses the standard Linux drivers for collecting data.

So far, the only driver causing marginal situations is the SPI driver in combination with an Inertial Measuring Unit (IMU).

This sensor operates on 200Hz, hence I have to collect its data within 5ms.

The IMU uses 16-bit transfers, but require the chip-select to go in-active for at least 2us between each transfer.

This cannot be handled by the standard SPI driver an forces me to generate separate 16-bit transfer calls to the driver.

Each call gives a 20-30us kernel/user-space punishment and a very jittering total transfer-time.

Bottom line (for me) is that I have to cope with the standard Linux drivers for the time being.

I am now running tests on all interfaces and the only sensors that misses interrupts is the SPI-bus.

I am not sure how degrading these standard drivers is for my real-time requirement, but I hope to reveal this by some long-term testing.

At the moment I am part of the “under-wood” and must rely on the patient support from the “tall trees” (Gilles and Robert).

If time allows later on, I will look into the possibilities of doing some work on the drivers.

First driver to get my attention will be the SPI driver…

Bon chance!

Best regards

Terje

Have you looked into using a PRU for the real time data capture?
There are two PRU units that run independently from the am335x processor.
They are dedicated 200mz 32 bit microcontrollers with 8k program & 8k data.
They also have the ability to interface with the BBB pins - even shift in up to 28 bits at a time.
You can program in C or Assembly and get very tight timing loops to capture data.
The PRU memory is accessible to the am335x, so you can build a buffer of real time data and collect it from Linux when it has time.