Other Parts Discussed in Thread: AM3358
Tool/software: Linux
Our goal is to read a digital stream using PRU0 and its GPIO read support within AM335x Linux PDK 02.00.00.00.
We have setup CCS and are building and running PRU firmware ok. We followed the detailed instructions on this page to setup TI PRU ICSS
We were able to confirm pruss_remoteproc and RPMsg support to our kernel (menuconfig) and everything builds fine. We followed this page:
If we renamed our firmware to the default:
/lib/firmware/am335x-pru0-fw ... remoteproc loaded and ran it at device start - no problem. In the terminal (after insmod pruss_remoteproc) we saw:
We then started to look into Linux user-level API support for PRU0 interaction and came to understand that we may need to switch to UIO. Examples provided in the hands on lab:
http://processors.wiki.ti.com/index.php/PRU_Training:_Hands-on_Labs
.. directly referenced additional modules to press_remoteproc that we could not get to work (RPMsg).
During startup of pruss_remoteproc and other modules there were warnings that the released version of these modules were "experimental". We considered updating to 02.00.01.07 - where pruss_remoteproc and other PRU modules were "built-in" (no special setup required as per the link above). Migrating up to 02.00.01.07 is not trivial for us. We also noticed that most online examples used the "older" option of UIO support for manual app load and start of PRU firmware and quite a simple API interface to reading and writing PRU memory. So, we pursued getting UIO support for PRU load/start/interaction.
To add software support for UIO we were able to use menuconfig to setup "uio.ko" and "uio_pdrv_genirq.ko" (manual load). However, we could not build uio_pruss as the "Texas Instruments PRUSS driver" option was not visible under menuconfig. uio_pruss was expected under a "Userspace I/O drivers" group (or similar). Reviewing the kconfig file showed:
config UIO_PRUSS tristate "Texas Instruments PRUSS driver" depends on ARCH_DAVINCI_DA850 select GENERIC_ALLOCATOR help PRUSS driver for OMAPL138/DA850/AM18XX devices PRUSS driver requires user space components, examples and user space driver is available from below SVN repo - you may use anonymous login gforge.ti.com/.../ More info on API is available at below wiki processors.wiki.ti.com/.../PRU_Linux_Application_Loader To compile this driver as a module, choose M here: the module will be called uio_pruss.
... which indicated no AM335x support, but reviewing other sources:
https://github.com/hvaibhav/am335x-linux/blob/master/drivers/uio/uio_pruss.c,
.. indicated that we could use the uio_pruss.c with our PDK for am335x. Therefore, we manually changed our Makefile to always generate uio_pruss.ko (from sources already within the PDK).
We can issue insmod on uio.ko and then we can then issue insmod on the uio_press.ko and uio_pdrv_genirq.ko and all modules load and run without any error indication. lsmod shows:
Module Size Used by uio_pruss 2583 0 uio_pdrv_genirq 3209 0 uio 8926 2 uio_pruss,uio_pdrv_genirq
We also built the libprussdrv driver (online sources) and we can link and make calls into this prussdrv lib just fine, but it accesses:
/dev/uio/uio0 and this /dev entry is not available. We have also read that /sys/class/uio should be visible after UIO support is up - but we cannot see it either.
We wonder if there is an error in how the driver supporting /dev is accessing our modules (i.e. module code issue) or if the /dev folder support has an issue with our device tree settings? uio_pruss was built from sources within the PDK, not from sources obtained elsewhere. We just had to change Makefile data. uio and uio_pdrv_genirq were built by simply changing menuconfig. So, we expect that the sources for modules are ok. Thier loading without error backs this up. To update the device tree, we made the following changes to am335x-bone-common.dtsi:
{ cpus { cpu@0 { cpu0-supply = <&dcdc2_reg>; }; }; memory { device_type = "memory"; reg = <0x80000000 0x10000000>; /* 256 MB */ }; vmmcsd_fixed: fixedregulator@0 { compatible = "regulator-fixed"; regulator-name = "vmmcsd_fixed"; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; }; pruss_uio: pruss@4a300000 { status = "okay"; compatible = "ti,pruss-v2"; ti,hwmods = "pruss"; ti,deassert-hard-reset = "pruss", "pruss"; reg = <0x4a300000 0x080000>; ti,pintc-offset = <0x20000>; interrupt-parent = <&intc>; interrupts = <20 21 22 23 24 25 26 27>; }; };
... and:
&am33xx_pinmux { pinctrl-names = "default"; pinctrl-0 = <&clkout2_pin>; ... adc_pru_pins: pinmux_pru_pru_pins { pinctrl-single,pins = < 0x1a0 ( PIN_INPUT | MUX_MODE6 ) /* (B12) ADC SCLK (B12) can be mapped (mode 6) to support pr1_pru0_pru_R31_4 (PRU0 Input) */ 0x1a4 ( PIN_INPUT | MUX_MODE6 ) /* (C13) ADC FSYNC (C13) can be mapped (mode 6) to support pr1_pru0_pru_R31_5 (PRU0 Input) */ 0x1a8 ( PIN_INPUT | MUX_MODE6 ) /* (D13) ADC FSYNC (C13) can be mapped (mode 6) to support pr1_pru0_pru_R31_5 (PRU0 Input) */ >; }; };
... and:
&pruss { status = "disabled"; }; &pruss_uio { pinctrl-names = "default"; pinctrl-0 = <&adc_pru_pins>; status = "okay"; };
I originally specified "pruss: pruss@4a300000" within my dtsi file and I got a devicetree error notification on compile: "duplicate pruss object". I then saw that there was a pruss node within am33xx.dtsi This suggested a problem with having 2 "pruss@4a300000" entries. So, I changed my reference to "pruss_uio: pruss@4a300000" and adding the &pruss { status = "disabled"; }; as shown above. The "duplicate" error was fixed.
Another important note: we have not removed pruss_remoteproc support from the kernel as we expect that it will be needed for other modules. For example,we are getting the following upon device start:
[ 5.236866] remoteproc0: powering up wkup_m3 [ 5.277917] remoteproc0: Booting fw image am335x-pm-firmware.elf, size 219803
Could this be an issue or is there an issue with our devicetree entries, or are we missing a step to getting /dev/uio0?
Thanks,
Mark J