Periodic delay reading analog inputs with C, will PRUs solve it and is it worth it?

233 views
Skip to first unread message

Walter Cromer

unread,
Apr 7, 2021, 11:23:59 AM4/7/21
to BeagleBoard

I'm running a BBB Wireless.  The OS version, version.sh output, etc. are below.

We're sensor outputs on AIN4 and AIN0 with C using the code below.  The intervals between readings is fairly constant at about 350 uS but there is periodically, about every 25 readings, a reading interval of between 4000 and 4800 uS.   Our application can't accept this.  

1) Is there some process the OS is doing periodically to cause this delay and can we eliminate it?

2) Would the PRUs solve this problem and is it worth the effort to learn and apply them?

Thanks for your insights, advice, and help!

Code is in C...and we run it from the Cloud9 IDE.

 void ReadDetectors(long TimeToRead, int CycleNo)

{

   

   

    // initialize local variables

    char Det1Volts_str[1024][6];

    char Det2Volts_str[1024][6];

    long elapsed_us;

    int index;

    index = 0;

    struct timeval tv_start; //start time hack

    struct timeval tv_now; // current time hack

    long total_elapsed_time_us[1024];

    long start_secs;

    long last_secs;

    long last_usecs;

   

    int KeepReading = 1;

   

    FILE* fDet1 = fopen("/sys/bus/iio/devices/iio:device0/in_voltage4_raw", "r");  // top sensor, blue wire

    FILE* fDet2 = fopen("/sys/bus/iio/devices/iio:device0/in_voltage0_raw", "r");  // bottom sensor, purple wire

 

    // get time at entry into the routine

   

    gettimeofday(&tv_now,NULL);

    start_secs = tv_now.tv_sec;

    last_usecs = tv_now.tv_usec;

    elapsed_us = 0;

    total_elapsed_time_us[index] = 0;

 

   while (KeepReading)

  

        {

   

          // update elapsed time

         

          gettimeofday(&tv_now,NULL);

       

          if (tv_now.tv_sec >= last_usecs)

          {

              elapsed_us = tv_now.tv_usec - last_usecs;

          }

          else

          {

              elapsed_us = (1000000 - last_usecs) + tv_now.tv_usec;

          }

          

          total_elapsed_time_us[index] = (tv_now.tv_sec - start_secs)*1000000 + elapsed_us;

          if (total_elapsed_time_us[index] > TimeToRead) KeepReading = 0;// read detectors

       

          fread(&Det1Volts_str[index], 5, 1, fDet1);

          fread(&Det2Volts_str[index], 5, 1, fDet2);

         

          rewind(fDet1);

          rewind(fDet2);

          index += 1;

          if (index >1024) KeepReading = 0;

        }

}

 

debian@beaglebone:/var/lib/cloud9$ uname --a

Linux beaglebone 4.19.94-ti-r42 #1buster SMP PREEMPT Tue Mar 31 19:38:29 UTC 2020 armv7l GNU/Linux

 

debian@beaglebone:/$ sudo opt/scripts/tools/version.sh

git:/opt/scripts/:[b39ec679648a6be8f25f48bd1c9784c1fc5a0c46]

eeprom:[A335BNLTBWA52027BBWG0227]

model:[TI_AM335x_BeagleBone_Black_Wireless]

dogtag:[BeagleBoard.org Debian Buster IoT Image 2020-04-06]

bootloader:[microSD-(push-button)]:[/dev/mmcblk0]:[U-Boot 2019.04-00002-g07d5700e21]:[location: dd MBR]

bootloader:[eMMC-(default)]:[/dev/mmcblk1]:[U-Boot 2018.03-00002-gac9cce7c6a]:[location: dd MBR]

UBOOT: Booted Device-Tree:[am335x-boneblack-uboot-univ.dts]

UBOOT: Loaded Overlay:[AM335X-PRU-RPROC-4-19-TI-00A0]

UBOOT: Loaded Overlay:[BB-ADC-00A0]

UBOOT: Loaded Overlay:[BB-BBBW-WL1835-00A0]

UBOOT: Loaded Overlay:[BB-BONE-eMMC1-01-00A0]

UBOOT: Loaded Overlay:[BB-HDMI-TDA998x-00A0]

UBOOT: Loaded Overlay:[BB-I2C2-RTC-DS3231]

UBOOT: Loaded Overlay:[BB-W1-P9.12-00A2]

kernel:[4.19.94-ti-r42]

nodejs:[v10.15.2]

/boot/uEnv.txt Settings:

uboot_overlay_options:[enable_uboot_overlays=1]

uboot_overlay_options:[uboot_overlay_addr4=/lib/firmware/BB-W1-P9.12-00A0.dtbo]

uboot_overlay_options:[uboot_overlay_pru=/lib/firmware/AM335X-PRU-RPROC-4-19-TI-00A0.dtbo]

uboot_overlay_options:[enable_uboot_cape_universal=1]

uboot_overlay_options:[dtb_overlay=/lib/firmware/BB-I2C2-RTC-DS3231.dtbo]

pkg check: to individually upgrade run: [sudo apt install --only-upgrade <pkg>]

pkg:[bb-cape-overlays]:[4.14.20200403.0-0rcnee0~buster+20200403]

pkg:[bb-wl18xx-firmware]:[1.20200322.0-0rcnee0~buster+20200322]

pkg:[kmod]:[26-1]

pkg:[librobotcontrol]:[1.0.4-git20190227.1-0rcnee0~buster+20190327]

pkg:[firmware-ti-connectivity]:[20190717-2rcnee1~buster+20200305]

groups:[debian : debian adm kmem dialout cdrom floppy audio dip video plugdev users systemd-journal bluetooth netdev i2c gpio pwm eqep remoteproc admin spi iio docker tisdk weston-launch xenomai cloud9ide]

cmdline:[console=ttyO0,115200n8 bone_capemgr.uboot_capemgr_enabled=1 root=/dev/mmcblk0p1 ro rootfstype=ext4 rootwait coherent_pool=1M net.ifnames=0 lpj=1990656 rng_core.default_quality=100 quiet]

dmesg | grep remote

[   11.374832] remoteproc remoteproc0: 4a334000.pru is available

[   11.397684] remoteproc remoteproc1: 4a338000.pru is available

[   58.421621] remoteproc remoteproc2: wkup_m3 is available

[   58.879676] remoteproc remoteproc2: powering up wkup_m3

[   58.879705] remoteproc remoteproc2: Booting fw image am335x-pm-firmware.elf, size 217168

[   58.879995] remoteproc remoteproc2: remote processor wkup_m3 is now up

dmesg | grep pru

[   11.374832] remoteproc remoteproc0: 4a334000.pru is available

[   11.375013] pru-rproc 4a334000.pru: PRU rproc node pru@4a334000 probed successfully

[   11.397684] remoteproc remoteproc1: 4a338000.pru is available

[   11.397867] pru-rproc 4a338000.pru: PRU rproc node pru@4a338000 probed successfully

dmesg | grep pinctrl-single

[    0.929984] pinctrl-single 44e10800.pinmux: 142 pins, size 568

dmesg | grep gpio-of-helper

[    0.943137] gpio-of-helper ocp:cape-universal: ready

lsusb

Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

END

TJF

unread,
Apr 8, 2021, 6:12:41 PM4/8/21
to BeagleBoard
Hi!

Check out libpruio for easy and reliable ADC measurements with accurate timing. I guess RB (ring buffer) mode is your way to go.

Regards

Walter Cromer

unread,
Apr 9, 2021, 8:41:00 AM4/9/21
to BeagleBoard
Thanks!  I believe you are right and I've already started working with this.   I will check out libpruio.   I'm starting to believe it isn't quite as difficult as a I thought it might be.  

Maybe you can answer a quick, related question.  

I'm looking at some example code and there references to ADC_TSC.  I realize this is a reference to the Touchscreen controller which provides the ADC functionality.  And I suspect this refers to the base memory address of the chip but I cannot find where that is defined in any header files anywhere.  It would help me to follow these examples if I knew where that reference was.

Unfortunately, too, the examples are Python and I'm not a Python programmer.    I work in C.  So I'm having to dig through this and learn some Python at the same time.  Not a bad thing but time consuming!

Walter

TJF

unread,
Apr 9, 2021, 9:17:24 AM4/9/21
to BeagleBoard
wal...@edenconceptsllc.com schrieb am Freitag, 9. April 2021 um 14:41:00 UTC+2:
I'm looking at some example code and there references to ADC_TSC.  I realize this is a reference to the Touchscreen controller which provides the ADC functionality.  And I suspect this refers to the base memory address of the chip but I cannot find where that is defined in any header files anywhere.  It would help me to follow these examples if I knew where that reference was.

Find high-level code (FreeBASIC) in files src/pruio/pruio_adc.[bas|bi] and low level code (assembler) in file src/pruio/pruio_adc.p.


Unfortunately, too, the examples are Python and I'm not a Python programmer.    I work in C.  So I'm having to dig through this and learn some Python at the same time.  Not a bad thing but time consuming!

Python examples are in folder src/python. FreeBASIC examples are in folder src/examples. And C examples are in folder src/c_examples. Find an overview at


Regards

Mark Lazarewicz

unread,
Apr 9, 2021, 10:23:26 AM4/9/21
to beagl...@googlegroups.com
1) 
Linux is not a real-time operating system (OS) in and of itself. ... “The idea is to run critical applications like the control loop on VxWorks and then run non-deterministic analytics on Linux.

Hard realtime apps like closed loop positioning used in pressing plants,automation,fighter planes etc etc don't use Linux. Determinism required by safety critical systems certified by FAA would require you found delay measured it to calculate worst case as well as validated software.





2) I say no depends on how much delay is acceptable there are buses between shared memory etc it will improve over using ARM.

Ideal situation is a barebone app designed with minimal interrupt latency followed by an RTOS that's guaranteed to meet latency specs especially one certified by FAA or FDA  of course these are expensive 


--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.
To view this discussion on the web visit
https://groups.google.com/d/msgid/beagleboard/04caf3a3-cd8c-449e-9fd7-9ed6df33f99en%40googlegroups.com
.

Walter Cromer

unread,
Apr 9, 2021, 10:57:32 AM4/9/21
to BeagleBoard
Understood.  Our application won't require FAA or FDA approval but it definitely needs the more deterministic performance of a bare bones app so I'm heading in the direction of the ADC being read by a PRU program and communicating back to the ARM for other processes (UI, reading other non-time-sensitive inputs, etc.).   

pierric...@gadz.org

unread,
Apr 9, 2021, 11:19:47 AM4/9/21
to BeagleBoard
Hi, 
I believe there are some simple ADC-read example directly in the image under /var/lib/cloud9/Techlab/.challenges, or here: https://github.com/beagleboard/cloud9-examples/blob/master/PocketBeagle/TechLab/.challenges/analogIn.pru0.c
They are labeled for PocketBeagle but it's the same ti-am335x chip so they should work easily on the BBB. 
Hope it helps! 
Pierrick 

Mark Lazarewicz

unread,
Apr 9, 2021, 11:58:29 AM4/9/21
to beagl...@googlegroups.com
I'd share your timing requirement needs I've seen people get help in here before after doing this. search group. That way you don't spend time trying to meet a goal not attainable on PRU.

Walter Cromer

unread,
Apr 9, 2021, 12:29:07 PM4/9/21
to BeagleBoard
Thanks, I'll check that out!

Walter Cromer

unread,
Apr 9, 2021, 12:30:53 PM4/9/21
to BeagleBoard
We are still experimenting but our preliminary calculations lead us to believe a reading every 50 microseconds will be sufficient. We can probably get by with 100 microseconds if we have to but I think the BBBw can easily sample at this rate, right?

WC

Pierrick Rauby

unread,
Apr 9, 2021, 12:32:00 PM4/9/21
to beagl...@googlegroups.com

Happy to help; I have worked some with these examples, so feel free to reach out if you have any questions!

Pierrick

 


**********************************************************************
Pierrick Rauby

Graduate Research Assistant

pierric...@gatech.edu
(+33) 640 237 194

Georgia Institute of Technology
George W. Woodruff School of Mechanical Engineering GeorgiaTech Institute of Technology 
771 Ferst Drive, NW, Love Bldg. Room 108
Atlanta, GA 30332-0405
**********************************************************************

Mark Lazarewicz

unread,
Apr 9, 2021, 1:38:37 PM4/9/21
to beagl...@googlegroups.com
Hi

??but I think the BBBw can easily sample at this ????rate, right?

Asking about ARM/linux side ? or 

PRU side 

Polling or Interrupt?

Explain you delay details at least delay duration  and what your app does with data would help.

The calculation I mentioned seeing people reply about were on the PRU.

Keep in mind there's overhead to get Data from PRU to ARM.

The timing becomes critical when you need to react from the  data you  read  quickly. If that's not the case your just talking about how many sample's you use to control right? That's why I would expand a bit on your application.

I've worked on  stuff that read and reacted in 10 microseconds closed loop plastic pressing for example that was easily achieved in 1988 microprocessor speeds 

I've also worked on control loops that ran faster than 1  micro second on a similar processor OMAP L138 in that case the code ran on the DSP I forget the clock speed. In this case the motor control ran every 100 nanosecond I believe but it's used TI RTOS. 

If the delay on Linux isn't acceptable add some details I mentioned hopefully the two guys who calculated PRU latencies will reply or I will find that post if possible.

Again it's probably highly  likely even a polled PRU app can read Data quickly dependant on conversation rates time I'm assuming you need the ARM to get Data in 100 microseconds?

I'm not sure the transfer rate between PRU and ARM us determistic if linux is used .

Hopefully this makes sense if not ask but I'd follow up with more detail

Mark


Dennis Lee Bieber

unread,
Apr 9, 2021, 2:00:07 PM4/9/21
to Beagleboard
On Fri, 9 Apr 2021 09:30:53 -0700 (PDT), in
gmane.comp.hardware.beagleboard.user Walter Cromer
<walterc-2dFtBuzUeF/tpnMUCzy8b...@public.gmane.org> wrote:

>We are still experimenting but our preliminary calculations lead us to
>believe a reading every 50 microseconds will be sufficient. We can probably
>get by with 100 microseconds if we have to but I think the BBBw can easily
>sample at this rate, right?

Well, the SoC reference (SPRS717J) indicates that the ADC should be
capable of 200K samples per second. If I haven't flubbed the math, that
appears to come down to one sample every 5us.

As I recall, the PRU runs on a 200MHz clock, and PRU instructions, for
the most, run in one clock cycle. Should be enough cycles per sample to
handle processing <G>

Of course, it may matter how you have the ADC programmed.



--
Dennis L Bieber

Walter Cromer

unread,
Apr 9, 2021, 2:15:49 PM4/9/21
to BeagleBoard
We are controlling fluid flow by controlling two valves.  (I am being a bit obscure because there are some proprietary processes involved.)

We start the flow and then read two sensors that are 'watching' the fluid for an event.   There is an event 'start' in the fluid and then a following event 'end' that we determine by watching the values from the sensors.   I believe this 'watch' part will be handled by the PRU firmware.  When the event is over, the valves are turned off.  We believe that the ARM will handle the valve control and UI.    The C code running under Linux has completely missed events because of its non-deterministic operation.
The communication between ARM and PRU programs should consist of 

1 - start / stop reading the sensors - considering just flipping a bit in a memory location both can access for this.  ARM will have write access, PRU will just monitor it.  (I don't really know how to do this yet. Still learning.)
2 - raw data collected about the event by the PRU doesn't really have to be accessed by the ARM in normal operation.  (For R&D, we'd probably like to have it though.)  Every sensor reading has to have its corresponding timestamp but all this data can be tossed once it is consumed.   The PRU will need to be able to do some statistics on it like mean, mode, std. dev. 
3 - if conditions are met, the PRU needs to tell the ARM.  considering just flipping a bit in a memory location the PRU can write to and the ARM can only read from for this.

The valve on/off can handle delays of 50 ms with no issue at all.

(I'm an old dog learning new tricks.  Years ago my hands-on experience was with Motorola 68xx and 68xxx series processors so I was comfortable writing directly to memory locations, registers, etc.  It took me a while on returning to this to get comfortable with sysfs but I definitely see the limitations in projects like this one!   Thanks for your patience and help!)

Walter Cromer

unread,
Apr 9, 2021, 2:16:32 PM4/9/21
to BeagleBoard
Thanks Dennis.  That is in sync with my research.

Walter Cromer

unread,
Apr 9, 2021, 2:50:56 PM4/9/21
to BeagleBoard
When I try to run this in Cloud9, I'm getting this error.  I'm not sure where type __far is defined but apparently I'm missing that definition.  I have to copy pru_cfg.h over to /usr/include manually to get this far.  Maybe there are other include files that are missing that it hasn't warned me about?  Sorry be such as neophyte!

/usr/include/pru_cfg.h:242:10: error: unknown type name ‘__far’
 volatile __far pruCfg CT_CFG __attribute__((cregister("PRU_CFG", near), peripheral));
          ^~~~~
/usr/include/pru_cfg.h:242:23: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘CT_CFG’
 volatile __far pruCfg CT_CFG __attribute__((cregister("PRU_CFG", near), peripheral));
                       ^~~~~~
PRU_AnalogReadfromGT.c:15:10: fatal error: pru_intc.h: No such file or directory
 #include <pru_intc.h>
          ^~~~~~~~~~~~
compilation terminated.
make: *** [/var/lib/cloud9/common/Makefile:215: /tmp/cloud9-examples/PRU_AnalogReadfromGT.o] Error 1

On Friday, April 9, 2021 at 11:19:47 AM UTC-4 pierric...@gadz.org wrote:

Mark Lazarewicz

unread,
Apr 9, 2021, 2:54:55 PM4/9/21
to beagl...@googlegroups.com
Plenty of data Walter thanks.

You could write some linux code that reads Data from from PRU ram( I'm not sure if there's several ways to get Data beyond remote messaging and reading the shared ram directly) factor in delay for new sample's to be updated from ADC  at least you could ensure that works in your time frame.

If that seems OK

Then use examples for PRU I'm skeptical about needing to use assembler it's not the PRU read time that's a bottleneck.

I'd be interested in seeing that PRU to ARM transfer rate it should not take alot of time but if Linux is still interfering beyond your needed specific time period you will only have one choice but to find what's exactly doing this  delay and mitigation of that will be your only hope. 

Typically a proof of concept fesigh verification like this is always wise.

If using this  chip is your only option you'd have one option left but I don't think you would like it.

And I'm already well known for suggestioning that option on ARM so I'm not going to mention it.

I do understand the value of having a feature rich OS on ARM that's royalty free but I've been lucky on the 50 or so projects I've worked on this wasn't the issue.

Another project was a Diesel engine controller they did a DVT phase first. Design verification Test

I wish I could help on Linux side but I can't there's plenty of people in here using Linux so I think you can get more ideas and help.

Not Sure how many have used Linux in actual hard realtime systems.

Your application doesn't sound extremely hard realtime so be interested in seeing this have a happy ending.






--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.
To view this discussion on the web visit

Walter Cromer

unread,
Apr 9, 2021, 3:00:25 PM4/9/21
to BeagleBoard
It's a fairly simple application really and that's what makes it frustrating!   We'll get there!  I learn something every day and that's just fine with me.

Mark Lazarewicz

unread,
Apr 9, 2021, 3:33:21 PM4/9/21
to beagl...@googlegroups.com
I believe you will Walter

 I just thought it prudent to mention doing some designs validation coding first. I do think the the through put coding could be done quickly on ARM .  If you're doing the other code functions on PRU you mentioned your going to face the learning curve anyway you asked about. So you might then try some tests using ADC PRU.

Otherwise I'd do the ARM part first

Usually there's always away to shoe horn something.

Regards

Mark


On Fri, Apr 9, 2021 at 2:00 PM, Walter Cromer

Darren Freed

unread,
Apr 9, 2021, 3:49:59 PM4/9/21
to beagl...@googlegroups.com
For my project that used a PRU to sample the onboard ADC, I relied very heavily on the TI PRU_ADC_onChip example code, along with Mark Yoder's most excellent PRU cookbook.  With those two resources, you should be able to do what you're hoping to do.

Good luck!
df

Walter Cromer

unread,
Apr 9, 2021, 4:20:48 PM4/9/21
to BeagleBoard
I would not be nearly as far along if I did not have Mark Yoder's PRU Cookbook!   I'll take a look at the TI documentation.   

Right now, I'm working with some examples from GA Tech and the compiler running in Cloud9 IDE is balking at a __far definition in pru_cfg.h.  I'm searching the GCC documentation and web for some fix for this.  I suspect there must be a compiler switch to cause it to accept these but I don't know what it is or if that's even the solution.     Any help would be appreciated!

Walter

TJF

unread,
Apr 10, 2021, 5:47:41 AM4/10/21
to BeagleBoard
Hi Walter!

A further "old dog" here. Sometimes I'm still working on my old Hades computer with 68060 CPU (loving that box).

In my house I'm using a BBB for a solar system running 24/7. It also controlls two valves (on/off, and four AC pumps in 16 power levels), connected to WLAN by an external USB-Stick. Most temperatures are comming from 1-wire sensors, but ADC is used to fetch samples from a high-temperature sensor on the roof/collector.

You should know that the onboard TSC_ADC_SS sometimes hangs, due to electromagnetical noice. In that case it allways measures/serves the same voltage, regardless of the changing input. There's a way to unblock the subsystem by software. But the better solution is to spend some effort in a decoupled input circruitry.

In a new project I start the controller development on ARM, doing measurements by libpruio. Once the prove of concept is done, I migrate the controller loop to the other PRU for hard real-time capability. libpruio is perfect for that concept, since the measurements are available from both sides, ARM and PRU. All setup is coded only once (on ARM), and only the inner controller loop needs adaption (from ARM to PRU). In that adaption the controller usually gets much better, since you won't repeat the bugs and pitfalls from the POC phase.

The most important initial decision is concerning the kernel driver to use. Drop rproc, and use uio_pruss driver instead. Then data exchange is pretty easy. Ie use DRam[0,1] for PRU-writing and SRam for ARM-writing. A simple and effective concept to avoid writing collisions (and pretty fast as well). uio_pruss driver provides pointers to that memory, while using rproc you've to find a solution by yourself.

Regards

Dennis Lee Bieber

unread,
Apr 10, 2021, 1:20:23 PM4/10/21
to Beagleboard
On Fri, 9 Apr 2021 11:50:56 -0700 (PDT), in
gmane.comp.hardware.beagleboard.user Walter Cromer
<walterc-2dFtBuzUeF/tpnMUCzy8b...@public.gmane.org> wrote:

>When I try to run this in Cloud9, I'm getting this error. I'm not sure
>where type __far is defined but apparently I'm missing that definition. I

>When I try to run this in Cloud9, I'm getting this error. I'm not sure
>where type __far is defined but apparently I'm missing that definition. I

That looks more like a compiler directive than a type in its own right
-- something forcing a pointer type to be a full address, and not a short
relative address. You may need to ask the source of the code what compiler
they were using?


--
Dennis L Bieber

Dennis Lee Bieber

unread,
Apr 10, 2021, 1:58:53 PM4/10/21
to Beagleboard
On Fri, 9 Apr 2021 11:15:49 -0700 (PDT), in
gmane.comp.hardware.beagleboard.user Walter Cromer
<walterc-2dFtBuzUeF/tpnMUCzy8b...@public.gmane.org> wrote:


>1 - start / stop reading the sensors - considering just flipping a bit in a
>memory location both can access for this. ARM will have write access, PRU
>will just monitor it. (I don't really know how to do this yet. Still
>learning.)

Well, since the PRU doesn't have asynchronous interrupts, using a
polling loop on the interrupt bits, that's probably reasonable -- though
I'd hope that RPMsg (since TI pushes it these days) should be usable
without a polling loop itself.

Especially if you can test for an incoming message between actually
reading an ADC sample.

>2 - raw data collected about the event by the PRU doesn't really have to be
>accessed by the ARM in normal operation. (For R&D, we'd probably like to
>have it though.) Every sensor reading has to have its corresponding
>timestamp but all this data can be tossed once it is consumed. The PRU
>will need to be able to do some statistics on it like mean, mode, std. dev.

Which probably need to be transferred to the Linux side -- another
RPMsg message block? <G> Using the same channel as #3 below, just different
message contents (or same message for both?)

>3 - if conditions are met, the PRU needs to tell the ARM. considering just
>flipping a bit in a memory location the PRU can write to and the ARM can
>only read from for this.
>
Ugh... Polling loop sucking up CPU cycles on an OS that already adds
potential process swapping when the loop eats all cycles of a quantum...

Just feels like attempting a (blocking) read on an RPMsg channel would
be cleaner. Linux side waits for PRU to send some message without eating
cycles. However ...

https://www.kernel.org/doc/html/latest/staging/rpmsg.html

... seems to rely upon a callback function for return data on the channel.
Example is too brief to really understand the API -- which does not seem to
have explicit RECV (to complement the SEND calls). Makes it a touch
confusing to me... Is the callback "active' from the moment the channel is
created, or only when a SEND operation was performed (since the channel is
considered bidrectional, I'd expect the callback to be active from the
start -- so either side can act upon a message sent by the other).





--
Dennis L Bieber

Mark Lazarewicz

unread,
Apr 10, 2021, 2:17:26 PM4/10/21
to beagl...@googlegroups.com
Hello TJF

Drop rproc, and use uio_pruss driver instead. Then data exchange is pretty easy. Ie use DRam[0,1] for PRU-writing and SRam for ARM-writing. A simple and effective concept to avoid writing collisions (and pretty fast as well). uio_pruss driver provides pointers to that memory, while using rproc you've to find a solution by yourself.




--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.
To view this discussion on the web visit

Walter Cromer

unread,
Apr 12, 2021, 10:51:43 AM4/12/21
to BeagleBoard
Thanks, TJF!  This sounds like good advice but tough tricks to learn!   The more I think through the architecture of my solution, the more I realize the PRU code needs to do. In our lab evaluation setup, I need the voltages measured by the ADC for analysis to develop base algorithms for detecting the events from the sensors properly.  But once we have that developed, in a production system, the PRU code will apply the logic to the data it is reading and probably should control the valves directly through with the GPIOs.   Otherwise, if we pass the data to the ARM side, Linux could go off and service something else and leave the valves running when they shouldn't be or not running when they should be.    But startup parameters will be selected by the user, so I'm thinking the UI is on ARM and once it has the start-up information, it just passes key info to the PRU code and lets it go do its thing.   

So what is the long-term support for the different options?  I thought remoteproc was the way of the future and uio_pruss drivers were phasing out.   We are on the front end of a new product/solution design and need to pay attention to 'end of life' type issues.   (Of course, the solution must work too!) 

Good to know about the EM interference.  Theoretically, we should be in a low external EM noise environment, however, we are using the BBB Wireless!   I had painful experiences with RF wreaking havoc on a system in graduate school.

Walter Cromer

unread,
Apr 12, 2021, 10:53:22 AM4/12/21
to BeagleBoard
I'll look at that.  I thought remoteproc was the way of the future so I was heading down that path.   And if in production I don't need to do a lot of data transfer, does it make sense to use uio_pruss/libpruio ( I don't know much about these, it's probably evident that I don't know much about remoteproc either) ?

Walter Cromer

unread,
Apr 12, 2021, 4:08:48 PM4/12/21
to BeagleBoard
I'm working through this and learning a lot.  But also realizing how much I have either forgotten or just never knew.   So, can I get a quick primer on what this line of C code is doing?

HWREG(SOC_CM_WKUP_REGS + CM_WKUP_ADC_TSC_CLKCTRL) = 0x02;

Thanks!

Mark Lazarewicz

unread,
Apr 12, 2021, 4:51:52 PM4/12/21
to Walter Cromer, BeagleBoard
Look for a registrer similar name to ADC clk Ctrl in TRM under the ADC section.

That's looks like a C  macro and it's writing 0x02 to that register. Macro  Probably defined in a header file.

 the registers will have different offsets depending on ARM or PRU access

Perhaps revisit init code on ARM you had working and document every bit that's important in ADC set-up and compare that to this PRU code.

Remember getting the Data out of PRU to ARM timings are important. I see you asked me about rproc that I don't use Linux that was TJ comments.

I'm afraid the PRU was marketed to you as the answer by people that don't understand your timing requirement. Lot's of script kiddies and cookbook reader's in this group few system engineer that actually read your intial post

Good luck

Walter Cromer

unread,
Apr 12, 2021, 6:44:09 PM4/12/21
to BeagleBoard
What's really throwing me is the + between what looks like two macro values.   Normally, we see the + on the right sign of the equals, right?  Or am I forgetting something I used to know!?

TJF

unread,
Apr 13, 2021, 5:16:58 AM4/13/21
to BeagleBoard
I'm not a C guy (but prefering FreeBASIC for ligh-level and ASM for PRU code). Just guessing:

As lazarman mentioned HWREG is a preprocessor macro (perhaps using ARM in supervisor mode?)
SOC_CM_WKUP_REGS is the base adress of the wakeup registers in the control module
CM_WKUP_ADC_TSC_CLKCTRL is the offset for the TSC_ADC_SS clock control register

In oder to enable the TSC_ADC_SS the value 0x02 needs to be writen to that register. Afterwards you can read or write the subsystems registers. (libpruio additionally checks read acces to the ID register in order to validate that the subsystem is ready.)
Message has been deleted

pierric...@gadz.org

unread,
Apr 13, 2021, 9:40:59 AM4/13/21
to BeagleBoard
To complete on TJF answer, you can find the address defined by CM_WKUP_ADC_TSC_CLKCTRL in  hw_cm_wkup.h line 101value (0xbc) and in soc_AM335x.h  line 139. 

Walter Cromer

unread,
Apr 13, 2021, 10:00:01 AM4/13/21
to BeagleBoard
After posting this, I realized this was a macro and that it was passing the sum of the two values.  That seemed weird to me.  
Thanks for the confirmations!   It is coming back slowly!

Dennis Lee Bieber

unread,
Apr 13, 2021, 10:54:36 AM4/13/21
to Beagleboard
On Mon, 12 Apr 2021 13:08:48 -0700 (PDT), in
gmane.comp.hardware.beagleboard.user Walter Cromer
<walterc-2dFtBuzUeF/tpnMUCzy8b...@public.gmane.org> wrote:

>What's really throwing me is the + between what looks like two macro
>values. Normally, we see the + on the right sign of the equals, right?
>Or am I forgetting something I used to know!?
>

Why? Take into account the ()s.

From what I can tell, this is adding the ADC register offset to the
base address of the (?) wakeup register block, which is passed as parameter
to HWREG (no doubt some macro that sets up actual access to the SoC
registers and returns a pointer or some such), and then assigns 0x02 into
the register so indicated.


--
Dennis L Bieber

Mark Lazarewicz

unread,
Apr 13, 2021, 11:25:08 AM4/13/21
to beagl...@googlegroups.com
Walter

Your best bet.

Run your whole control loop on the PRU that's as realtime as you get. Use a foreground background loop. Use the ARM like a PC with Linux to access the system via ethernet.

You could also run control on ARM without linux but this way you have all the resources of Linux to access the system.

This assumes your output's from control loop are accessable from PRU.

The point is Linux can only run slow control loops and this way you don't have to debug the delay.

This wasn't obvious to me before as all the hard realtime systems I work on run an RTOS on ARM it has all the resources of Linux but cost $$$$$.

In our system we did that on the DSP the PID did the math on a fast DSP.

ARM is just a gateway to outside world.

Myself I'd debug the PRU with JTAG and CCS you can see exactly what's going on and dump these registers from CCS.

Some people like printf but with a PRU based system you are essentially doing barebones.

There's videos on PRU development doing this online.

Loading code via rproc and using  printf is like burning and erasing an eeprom to test your changes. You wait 45 minutes for it to erase try your code and do it again.

Not for me.

Mark
--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard+unsub...@googlegroups.com.

To view this discussion on the web visit https://groups.google.com/d/msgid/beagleboard/44cb7gtf6pl4d4j3e6oqo57g5n0hobi29c%404ax.com.

Walter Cromer

unread,
Apr 13, 2021, 2:17:00 PM4/13/21
to BeagleBoard
Yeah, I woke up realizing what a dunce I was reading it the way I was.  HWREG equates to (*((volatile unsigned int *) (x)))

Walter Cromer

unread,
Apr 13, 2021, 2:25:06 PM4/13/21
to BeagleBoard
We're designing it the way you suggested.  The nice thing is that basically the control logic has already been written in C on the ARM side.  Now, I just need to get it ported to the PRUs and create the communications between the PRUs and a new ARM app that supervises everything from the user's point of view.  Meaning, taking inputs like start, stop and giving feedback by turning LEDs on and off.  And it needs to take in some basic system configuration data from the cloud periodically that the PRU will consume to adjust it's operation.  

I am making progress.  Part of my problem was using Cloud9 for development.  That's where all my ARM development has been so far.  I have CCS installed on my Windows 10 machine and started working through TI's PRU Hands On Labs.  Unfortunately, the very first one doesn't work because their document is written for CCS running on Linux.   Step 6 says to delete the linker file and add it back with Project->Add Files but that's grayed out.  I've asked TI about that.   But I got it to compile by writing on the Beagle using nano and compiling it there.   I've ready a lot of TI documentation today and learned a lot. 

Here's one more thing I am struggling with though.  It's a mental block I think.  I'm used to controlling GPIOs on the ARM side using sysfs.   It appears that on the PRU, we use __R30 instead but I don't understand how that works.  I read through it this morning and it still isn't sinking in.  If anyone can help make this clearer, I'd appreciate it.

TJF

unread,
Apr 14, 2021, 1:39:56 AM4/14/21
to BeagleBoard
Nano isn't best choice for polyglot applications. I'm using Geany (on PC exchanging source files via virtual file system), while I compile and test under LINUX on the BB.

wal...@edenconceptsllc.com schrieb am Dienstag, 13. April 2021 um 20:25:06 UTC+2:
Here's one more thing I am struggling with though.  It's a mental block I think.  I'm used to controlling GPIOs on the ARM side using sysfs.   It appears that on the PRU, we use __R30 instead but I don't understand how that works.  I read through it this morning and it still isn't sinking in.  If anyone can help make this clearer, I'd appreciate it.

Check out example pruss_toggle.

Walter Cromer

unread,
Apr 14, 2021, 11:02:56 AM4/14/21
to BeagleBoard
My setup is a Windows 10 PC with a Black connected via USB or a Black wireless connected via wi-fi.   So far I have done all the C development on the ARM side with Cloud9 and only occasionally use Nano.  It's met my needs just fine so far but this is getting more complex.  I installed TI's CCS but it (or TI)  prefers to be on a Linux box apparently.

Walter Cromer

unread,
Apr 14, 2021, 11:03:30 AM4/14/21
to BeagleBoard
 The TSC_ADC only has 8 channels.  So why are there 16 STEP registers? 

Walter Cromer

unread,
Apr 14, 2021, 11:58:31 AM4/14/21
to BeagleBoard
So I looked over the libpruio page and it looks great.  My head's spinning a bit between remoteproc, uio, and libpruio options but I'd like to try libpruio.  
I don't want to break remoteproc if I set up to use libpruio.  Will that happen?

Also, I'm running Buster (version.sh) at the bottom of this post 
The instructions refer to Jessie.  Are the Debian packages referred to compatible with Buster?  Here's what I am referring to.

The easy way to benefit from libpruio is to install the Debian packages. They're not in mainline, yet. So you have to add a PPA (Personal Package Archive) to your package management sources. On the default Debian operating system, edit the file sudo nano /etc/apt/sources.list and add the lines:

deb http://beagle.tuks.nl/debian jessie/ deb-src http://beagle.tuks.nl/debian jessie/

Then grep the keyring by (mind the '-' character at the end)

wget -qO - http://beagle.tuks.nl/debian/pubring.gpg | sudo apt-key add -

Once prepared, you can update your package manager database

sudo apt-get update

debian@beaglebone:/$ sudo opt/scripts/tools/version.sh
git:/opt/scripts/:[b39ec679648a6be8f25f48bd1c9784c1fc5a0c46]
eeprom:[A335BNLT00C04417BBBK1847]
model:[TI_AM335x_BeagleBone_Black]
dogtag:[BeagleBoard.org Debian Buster IoT Image 2020-04-06]
bootloader:[microSD-(push-button)]:[/dev/mmcblk0]:[U-Boot 2019.04-00002-g07d5700e21]:[location: dd MBR]
bootloader:[eMMC-(default)]:[/dev/mmcblk1]:[U-Boot 2018.03-00002-gac9cce7c6a]:[location: dd MBR]
UBOOT: Booted Device-Tree:[am335x-boneblack-uboot-univ.dts]
UBOOT: Loaded Overlay:[AM335X-PRU-RPROC-4-19-TI-00A0]
UBOOT: Loaded Overlay:[BB-ADC-00A0]
UBOOT: Loaded Overlay:[BB-BONE-eMMC1-01-00A0]
UBOOT: Loaded Overlay:[BB-HDMI-TDA998x-00A0]
UBOOT: Loaded Overlay:[BB-I2C2-RTC-DS3231]
UBOOT: Loaded Overlay:[BB-W1-P9.12-00A2]
kernel:[4.19.94-ti-r61]
nodejs:[v10.15.2]
/boot/uEnv.txt Settings:
uboot_overlay_options:[enable_uboot_overlays=1]
uboot_overlay_options:[uboot_overlay_addr4=/lib/firmware/BB-W1-P9.12-00A0.dtbo]
uboot_overlay_options:[uboot_overlay_pru=/lib/firmware/AM335X-PRU-RPROC-4-19-TI-00A0.dtbo]
uboot_overlay_options:[enable_uboot_cape_universal=1]
uboot_overlay_options:[dtb_overlay=/lib/firmware/BB-I2C2-RTC-DS3231.dtbo]
pkg check: to individually upgrade run: [sudo apt install --only-upgrade <pkg>]
pkg:[bb-cape-overlays]:[4.14.20210401.0-0~buster+20210401]
pkg:[bb-wl18xx-firmware]:[1.20200322.0-0rcnee0~buster+20200322]
pkg:[kmod]:[26-1]
pkg:[librobotcontrol]:[1.0.4-git20190227.1-0rcnee0~buster+20190327]
pkg:[firmware-ti-connectivity]:[20190717-2rcnee1~buster+20200305]
groups:[debian : debian adm kmem dialout cdrom floppy audio dip video plugdev users systemd-journal bluetooth netdev i2c gpio pwm eqep remoteproc admin spi iio docker tisdk weston-launch xenomai cloud9ide]
cmdline:[console=ttyO0,115200n8 bone_capemgr.uboot_capemgr_enabled=1 root=/dev/mmcblk0p1 ro rootfstype=ext4 rootwait coherent_pool=1M net.ifnames=0 lpj=1990656 rng_core.default_quality=100 quiet]
dmesg | grep remote
[   66.835497] remoteproc remoteproc0: wkup_m3 is available
[   67.240120] remoteproc remoteproc0: powering up wkup_m3
[   67.240151] remoteproc remoteproc0: Booting fw image am335x-pm-firmware.elf, size 217148
[   67.240404] remoteproc remoteproc0: remote processor wkup_m3 is now up
[   69.894313] remoteproc remoteproc1: 4a334000.pru is available
[   69.907897] remoteproc remoteproc2: 4a338000.pru is available
[15549.657580] remoteproc remoteproc1: powering up 4a334000.pru
[15549.665009] remoteproc remoteproc1: Booting fw image am335x-pru0-fw, size 30880
[15549.665035] remoteproc remoteproc1: header-less resource table
[15549.675909] remoteproc remoteproc1: Boot failed: -22
[15602.811891] remoteproc remoteproc1: powering up 4a334000.pru
[15602.812184] remoteproc remoteproc1: Booting fw image am335x-pru0-fw, size 30880
[15602.812202] remoteproc remoteproc1: header-less resource table
[15602.823804] remoteproc remoteproc1: Boot failed: -22
[15801.464252] remoteproc remoteproc1: powering up 4a334000.pru
[15801.464540] remoteproc remoteproc1: Booting fw image am335x-pru0-fw, size 30880
[15801.464559] remoteproc remoteproc1: header-less resource table
[15801.475947] remoteproc remoteproc1: Boot failed: -22
[15835.561165] remoteproc remoteproc1: powering up 4a334000.pru
[15835.561459] remoteproc remoteproc1: Booting fw image am335x-pru0-fw, size 30880
[15835.561478] remoteproc remoteproc1: header-less resource table
[15835.575362] remoteproc remoteproc1: Boot failed: -22
[15973.384568] remoteproc remoteproc1: powering up 4a334000.pru
[15973.384866] remoteproc remoteproc1: Booting fw image am335x-pru0-fw, size 30880
[15973.384884] remoteproc remoteproc1: header-less resource table
[15973.395805] remoteproc remoteproc1: Boot failed: -22
[15996.157221] remoteproc remoteproc1: powering up 4a334000.pru
[15996.157504] remoteproc remoteproc1: Booting fw image am335x-pru0-fw, size 30880
[15996.157523] remoteproc remoteproc1: header-less resource table
[15996.171335] remoteproc remoteproc1: Boot failed: -22
[16031.348941] remoteproc remoteproc1: powering up 4a334000.pru
[16031.349226] remoteproc remoteproc1: Booting fw image am335x-pru0-fw, size 30880
[16031.349244] remoteproc remoteproc1: header-less resource table
[16031.359886] remoteproc remoteproc1: Boot failed: -22
[26382.806806] remoteproc remoteproc1: powering up 4a334000.pru
[26382.807380] remoteproc remoteproc1: Booting fw image am335x-pru0-fw, size 94376
[26382.820350] remoteproc remoteproc1: registered virtio0 (type 7)
[26382.820370] remoteproc remoteproc1: remote processor 4a334000.pru is now up
dmesg | grep pru
[   69.894313] remoteproc remoteproc1: 4a334000.pru is available
[   69.894508] pru-rproc 4a334000.pru: PRU rproc node pru@4a334000 probed successfully
[   69.907897] remoteproc remoteproc2: 4a338000.pru is available
[   69.908098] pru-rproc 4a338000.pru: PRU rproc node pru@4a338000 probed successfully
[15549.657580] remoteproc remoteproc1: powering up 4a334000.pru
[15549.665009] remoteproc remoteproc1: Booting fw image am335x-pru0-fw, size 30880
[15602.811891] remoteproc remoteproc1: powering up 4a334000.pru
[15602.812184] remoteproc remoteproc1: Booting fw image am335x-pru0-fw, size 30880
[15801.464252] remoteproc remoteproc1: powering up 4a334000.pru
[15801.464540] remoteproc remoteproc1: Booting fw image am335x-pru0-fw, size 30880
[15835.561165] remoteproc remoteproc1: powering up 4a334000.pru
[15835.561459] remoteproc remoteproc1: Booting fw image am335x-pru0-fw, size 30880
[15973.384568] remoteproc remoteproc1: powering up 4a334000.pru
[15973.384866] remoteproc remoteproc1: Booting fw image am335x-pru0-fw, size 30880
[15996.157221] remoteproc remoteproc1: powering up 4a334000.pru
[15996.157504] remoteproc remoteproc1: Booting fw image am335x-pru0-fw, size 30880
[16031.348941] remoteproc remoteproc1: powering up 4a334000.pru
[16031.349226] remoteproc remoteproc1: Booting fw image am335x-pru0-fw, size 30880
[26382.806806] remoteproc remoteproc1: powering up 4a334000.pru
[26382.807380] remoteproc remoteproc1: Booting fw image am335x-pru0-fw, size 94376
[26382.814125] pruss 4a300000.pruss: configured system_events[63-0] = 00000000,00030000
[26382.814148] pruss 4a300000.pruss: configured intr_channels = 0x00000005 host_intr = 0x00000005
[26382.820370] remoteproc remoteproc1: remote processor 4a334000.pru is now up
[26382.891327] virtio_rpmsg_bus virtio0: creating channel rpmsg-pru addr 0x1e
[26382.946821] rpmsg_pru virtio0.rpmsg-pru.-1.30: new rpmsg_pru device: /dev/rpmsg_pru30
dmesg | grep pinctrl-single
[    0.942975] pinctrl-single 44e10800.pinmux: 142 pins, size 568
dmesg | grep gpio-of-helper
[    0.956726] gpio-of-helper ocp:cape-universal: ready
lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
END
On Wednesday, April 14, 2021 at 1:39:56 AM UTC-4 TJF wrote:

Mark Lazarewicz

unread,
Apr 14, 2021, 1:13:25 PM4/14/21
to beagl...@googlegroups.com
Walter

Just trying to be a guiding light. Why not get the control loop working on PRU first.?

Your being pulled into to many directions. I know how that feels I've been there.

Once the ADC and output works worry about getting Data over to ARM.

Too many new things will kill you. Master the PRU coding first and on second thought forget the CCS JTAG suggestions I gave.

I'm getting dizzy reading all the suggestions you received. 

What's working what's the architecture?

Too many chef's the soup will boil away.

Thanks 👍

Mark

--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.

To view this discussion on the web visit

Walter Cromer

unread,
Apr 14, 2021, 1:46:52 PM4/14/21
to BeagleBoard
Definitely agree.  My head is spinning.  I am very appreciative of all the help and suggestions!

Dennis Lee Bieber

unread,
Apr 14, 2021, 4:00:14 PM4/14/21
to Beagleboard
On Tue, 13 Apr 2021 11:25:06 -0700 (PDT), in
gmane.comp.hardware.beagleboard.user Walter Cromer
<walterc-2dFtBuzUeF/tpnMUCzy8b...@public.gmane.org> wrote:

>We're designing it the way you suggested. The nice thing is that basically
>the control logic has already been written in C on the ARM side. Now, I
>just
>Here's one more thing I am struggling with though. It's a mental block I
>think. I'm used to controlling GPIOs on the ARM side using sysfs. It
>appears that on the PRU, we use __R30 instead but I don't understand how
>that works. I read through it this morning and it still isn't sinking in.
>If anyone can help make this clearer, I'd appreciate it.
>
More details of what is confusing you would help.

R30 (output)/R31 (input) registers are mapped as one GPIO per bit
https://elinux.org/Ti_AM33XX_PRUSSv2#Beaglebone_PRU_connections_and_modes
and those bits/GPIOs you are using will need to be properly pin-muxed in
u-Boot uEnv.txt.

As for using the registers... For input it should just be a case of
bitwise AND on the register content and test for result of 0/not 0
(assuming you are testing just one input at a time...). {Treat the
following as pseudo-code; I've not done any PRU programming, and am getting
stale with C]

inputX = 0 != (__R31 & (1 << desired_bit))

For output, you likely will need to maintain a copy (can the output
register be read by C code? -- if it can, forget the copy). You would AND
the inverse of the desired bit (to retain the other bits, but clear the
desired bit to 0) then OR the desired bit with the wanted value and write
the register with the combined result.

to set
__R30 = (__R30 & ^(1 << desired_bit)) | (1 << desired_bit)
to clear
__R30 = __R30 & ^(1 << desired_bit)

You'll likely want to prebuild the (1^^desired_bit) as constants for
each input/output of interest.


--
Dennis L Bieber

Dennis Lee Bieber

unread,
Apr 14, 2021, 4:13:16 PM4/14/21
to Beagleboard
On Wed, 14 Apr 2021 08:03:30 -0700 (PDT), in
gmane.comp.hardware.beagleboard.user Walter Cromer
<walterc-2dFtBuzUeF/tpnMUCzy8b...@public.gmane.org> wrote:

> The TSC_ADC only has 8 channels. So why are there 16 STEP registers?

So far as I can make out, since each step config includes the
input/channel, it means one can sample the same channel multiple times
during a sequence.


--
Dennis L Bieber

Mark Lazarewicz

unread,
Apr 14, 2021, 4:59:40 PM4/14/21
to beagl...@googlegroups.com
That reference Dennis provided especially the block diagram showing everything about both PRU have access to is essential and a good thing to really consume.

Note each PRU has instruction ram and data RAM.

Instruction ram is where a debugger or rproc loads your pru program.

Keep in mind any ADC register you used on ARM has a different address on PRU if you're porting code from ARM be careful.

That document Dennis linked to also explains the ARM does muxing. That's defined ar setting a pins function as in GPIO or ADC etc etc. So PRU can access the ADC register direct as in those Macro's you were asking about.

Lastly the memory map shows shared RAM

I'm almost positive that's the area the ARM can access so that's your gateway between the PRU and ARM. 

Be careful rproc may be using a chunk of that but theoretically you could write your results and ARM could read it but you need a queue and a Way to ensure only one side is accessing the Data.

This can be done many ways unless you're really comfortable you might look for something else to transfer data.

I know the rproc for x15 carves out shared memory and all this done I think in the device tree.

Here's the magic area 

0x0001_0000Data 12KB RAM 2 (Shared)

I'd start with a PRU  cookbook  ADC working example get that running then start asking about alternatives.

Maybe send back your ADC values to ARM while you change voltage input.

Dice the job up into manageable chunk's

Keep in mind you have no OS on PRU a main.c program will run once and exit.

Start getting familiar with every address important in your application on PRU and that document and exactly what you have to debug when PRU crashes
Printf etc etc

Baby steps Warren the tortoise slow and steady always wins the race.

--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard+unsub...@googlegroups.com.

TJF

unread,
Apr 15, 2021, 1:00:02 AM4/15/21
to BeagleBoard
wal...@edenconceptsllc.com schrieb am Mittwoch, 14. April 2021 um 17:58:31 UTC+2:
So I looked over the libpruio page and it looks great.  My head's spinning a bit between remoteproc, uio, and libpruio options but I'd like to try libpruio.  
I don't want to break remoteproc if I set up to use libpruio.  Will that happen?

libpruio will never run under rproc, since rproc isn't powerful enough (same issue with maschinekit). Only uio_pruss driver will meet its needs.
 
Also, I'm running Buster (version.sh) at the bottom of this post 
The instructions refer to Jessie.  Are the Debian packages referred to compatible with Buster?  Here's what I am referring to.

The easy way to benefit from libpruio is to install the Debian packages. They're not in mainline, yet.

RobertCNelson started to add the packages in mainline years ago. Ask him why he never finished.

For kernel 4.19 you'll have to add a symlink, since a sysfs path changed. (Compiling from source may be a good option.)
 
Start your project by a working example. Then add features step by step. You cannot test your PRU mainloop before you got hardware IO running.
  1. install libpruio
  2. get pruss_toggle example running
  3. add a second output
  4. learn to read ADC values in RB mode (first from ARM side, then from PRU)
  5. learn to exchange data between ARM and PRU
  6. finally put all together in your PRU mainloop (perhaps test on ARM before)
Regards

Mark Lazarewicz

unread,
Apr 15, 2021, 1:55:39 AM4/15/21
to beagl...@googlegroups.com
  1. learn to read ADC values in RB mode (first from ARM side, then from PRU)
  2. learn to exchange data between ARM and PRU
  3. finally put all together in your PRU mainloop (perhaps test on ARM before)
Hello TJF
I thought he had an unacceptable delay reading ADC from ARM?
Just trying to understand how libpruio fixes this and if it did why even bother with PRU?

--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.

To view this discussion on the web visit

TJF

unread,
Apr 15, 2021, 2:24:55 AM4/15/21
to BeagleBoard
lazarman schrieb am Donnerstag, 15. April 2021 um 07:55:39 UTC+2:
I thought he had an unacceptable delay reading ADC from ARM?
Just trying to understand how libpruio fixes this and if it did why even bother with PRU?

In RB mode libpruio fetches ADC data at accurate timing (no delays) in to a ring buffer. The ARM can read/evaluate the data later.

@Walter
Inspired by lazarman, just another thought: perhaps you don't need a PRU mainloop at all. Perhaps you can meet your needs by ARM code using the libpruio trigger features in MM mode.
  1. Configure your trigger event (up to four events can get chained up).
  2. Open valves.
  3. Start MM mode, synchronously waiting for trigger.
  4. Close valves.
  5. ?Perhaps evaluate pre-trigger values?
  6. Repeat from step 2.

Walter Cromer

unread,
Apr 15, 2021, 9:15:43 AM4/15/21
to BeagleBoard
I'm sticking with remoteproc for now.  I spent most of yesterday reading TI's documentation and the Beaglebone Black SRM in detail and believe I have a much better handle on how this works now.  
My plan is to allocate memory space in pru0's RAM for the data storage and then have an ARM program read it from there.    Our production solution does not need to share this data with the ARM side.  We only need this during R&D so I'm not worried about the two sides clobbering each other on the production system.

But, now, of course, nothing that used to work is working!  I had started out with the PRUCookbook and had P9_11 blinking an LED.  Now, nothing.  dmesg shows the PRU starting and stopping and the firmware file in /lib/firmware is new based on ls -l output so I'm fairly certain that the code got compiled and copied over to the right directory.  The PRUCookbook example that blinks USR3 works and I can change the blinking frequency and change it to blink USR2 instead and all that works.  But the example to blink P9_11 won't and neither will another one to blink P9_27.   The only thing I know I changed is that the PRUCookbook directories were all owned by root and group root.  They weren't originally like that but got changed somehow.  Yesterday I did a chown -R debian:debian on PRUCookbook to change them so Debian could edit files in those directories.  I wouldn't think this would matter since all the real remoteproc action happens in other directories.  

I also started working with CCS some and trying to get it going.   Somewhere along the way, something deleted all the files and folders in my local WIndows machine's Documents folder.  I'm running anti-virus and anti-malware on the WIndows box.

Just when I thought I was going to start really moving forward!!!

Mark Lazarewicz

unread,
Apr 15, 2021, 9:55:41 AM4/15/21
to beagl...@googlegroups.com
Beaglebone Black SRM

Have not seen this can you share a link

Thanks

Mark

--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.
To view this discussion on the web visit
Message has been deleted

Walter Cromer

unread,
Apr 15, 2021, 10:13:19 AM4/15/21
to BeagleBoard
I think this is a better version.   Than what I posted a few minutes ago ( Ideleted that post).

Walter Cromer

unread,
Apr 15, 2021, 12:35:20 PM4/15/21
to BeagleBoard
Just to close the loop on this question, I learned from TI's E2E forum how the A/D channels and steps relate.  
Basically, the steps allow the configuration of how the channels are read.  There are only 8 channels but you can create a sequence of up to 16 steps to read them.

Here's my explanation.

So, STEPENABLE lets me enable the steps that I want to be executed.  (I missed that concept before.)

So if I had an application that had a sensor A that needs to be read every 10ms and sensor B that only needs to be read every minute, I could wire channel 1 to sensor A and assign it to step 1 and wire channel 2 to sensor B and assign it to step 2. 

Then at startup, when I want to read both sensors, I enable steps 1 and 2 but not 3-16.  This saves time on the read as channels 3-7 aren't needed and steps 3-16 aren't needed so I don't use them.  Then after the initial read when I don't need to read sensor B until a minute passes, I can change STEPENABLE so only step 1 is enabled and execute a read every 10 ms.  Only sensor A would be read.  Then at one minute intervals, I change STEPENABLE so steps 1 & 2 are enabled and when read is triggered, sensors A and B are read. 

BTW - I don't have a real-world application like this but I guess someday I could.

This is a very flexible system!

Darren Freed

unread,
Apr 15, 2021, 4:00:41 PM4/15/21
to beagl...@googlegroups.com
Have you set the pins with config-pin to pruout or pruin?  This caught me out a few times when I was learning PRU.


--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.

TJF

unread,
Apr 16, 2021, 1:47:24 AM4/16/21
to BeagleBoard
wal...@edenconceptsllc.com schrieb am Donnerstag, 15. April 2021 um 18:35:20 UTC+2:
So, STEPENABLE lets me enable the steps that I want to be executed.  (I missed that concept before.)

So if I had an application that had a sensor A that needs to be read every 10ms and sensor B that only needs to be read every minute, I could wire channel 1 to sensor A and assign it to step 1 and wire channel 2 to sensor B and assign it to step 2. 

Then at startup, when I want to read both sensors, I enable steps 1 and 2 but not 3-16.  This saves time on the read as channels 3-7 aren't needed and steps 3-16 aren't needed so I don't use them.  Then after the initial read when I don't need to read sensor B until a minute passes, I can change STEPENABLE so only step 1 is enabled and execute a read every 10 ms.  Only sensor A would be read.  Then at one minute intervals, I change STEPENABLE so steps 1 & 2 are enabled and when read is triggered, sensors A and B are read.

There're 17 steps, one charge step and 16 sample steps. Each step configures not only the multiplexer (chanel 0-7), but also an open delay and a sample delay, as well as an avaraging number. That's explained at AdcUdt::setStep(), including a hint where to find further information in the ARM TRM.

In order to write to the STEPENABLE register you've to stop the sequencer, write the new value and restart the sequencer again. This is 3 times L3 operation, which need at least 3 PRU cycles each (perhaps more in case of heavy travel). How do you what to ensure accurate ADC timing?

The outnumber of step registers isn't thought of macroscopic asymmetry (in your case sample channel A and B at 10 ms and ignore the B value for a minute). It's made for microscopic asymmetry, ie when you want to sample A twice as often as B.

Mark Lazarewicz

unread,
Apr 16, 2021, 3:01:56 AM4/16/21
to beagl...@googlegroups.com
Hello TJF

Looks very powerful and code is very generic and well thought out. I thought you couldn't code?🤣

I'm on tablet forgive my laziness where are the ADC examples located in c language if possible 

Looks like you support multiple languages nice.


I'm guessing  below reference you mentioned is the am335x TRM or are you referring to the ARM intellectual property for ADC?

It's also possible to directly write to the step configuration in AdcSet::St_p by writing to the member variables Confg and Delay. See ARM Reference Guide, chapter 12 for details on ADC configurations.

Thanks. Did you write this library? It's quite a bit to wrap ones mind around. How long dis this take to develop. 

I've got a basic  understanding of how RPMSG works I'd like to understand how libpruio handles the data exchange. 

I'm wondering why Walter isn't using RPMSG  he's talking about using the other unused  PRU memory to store data and have ARM read it. I'm trying to see if that's doable for my own understanding. Certainly would not be good if that PRU loaded code from ARM. The Linux part I'm unfamiliar with. From my reading it sounds like starting PRU is manually done from linux command line. 

Loading and debugging PRU code seems to me to be slow and time consuming compared to jtag.

Lastly in the unlikely event a modified libpruio example crashes what is the debug mechanisms beyond dmsg saying dude you crashed go recompile and reload. Are console output echoed back.

Thanks in advance also any data sharing examples in libpruio?
Mark

--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.

To view this discussion on the web visit

TJF

unread,
Apr 16, 2021, 3:57:31 AM4/16/21
to BeagleBoard
lazarman schrieb am Freitag, 16. April 2021 um 09:01:56 UTC+2:
Looks very powerful and code is very generic and well thought out. I thought you couldn't code?🤣
Even a blind hen sometimes finds a grain of corn. I'm not a programming expert, but I've a ton of hands-on experience in developing realtime closed loop controllers.
 
I'm on tablet forgive my laziness where are the ADC examples located in c language if possible
See https://users.freebasic-portal.de/tjf/Projekte/libpruio/doc/html/ChaExamples.html

C examples including ADC: 1.c, io_input.c, rb_file.c

Since I don't know how to generate graphical screen output in C (or Python), I didn't transform the further ADC examples (ie MM mode). They're FreeBASIC only. (Feel free to help out here.)

I'm guessing  below reference you mentioned is the am335x TRM or are you referring to the ARM intellectual property for ADC?

It's also possible to directly write to the step configuration in AdcSet::St_p by writing to the member variables Confg and Delay. See ARM Reference Guide, chapter 12 for details on ADC configurations.
Just click on the text "ARM Reference Guide, chapter 12". It's a link to the document I'm refering to.
 
Thanks. Did you write this library? It's quite a bit to wrap ones mind around. How long dis this take to develop. 
The main tasks were to get the FreeBASIC compiler running on ARM, to develop the CMake support for that language and to create a filter for Doxygen. Then the first version was less than three month. Find details at

https://users.freebasic-portal.de/tjf/Projekte/libpruio/doc/html/ChaChangelog.html
 
I've got a basic  understanding of how RPMSG works I'd like to understand how libpruio handles the data exchange. 

I'm wondering why Walter isn't using RPMSG  he's talking about using the other unused  PRU memory to store data and have ARM read it. I'm trying to see if that's doable for my own understanding. Certainly would not be good if that PRU loaded code from ARM. The Linux part I'm unfamiliar with. From my reading it sounds like starting PRU is manually done from linux command line. 

Loading and debugging PRU code seems to me to be slow and time consuming compared to jtag.

Lastly in the unlikely event a modified libpruio example crashes what is the debug mechanisms beyond dmsg saying dude you crashed go recompile and reload. Are console output echoed back.
Again: libpruio does not use, and will never use rproc/rpmsg.
 
Thanks in advance also any data sharing examples in libpruio?
pruss_add.c, pruss_toggle.c
And, of course, libpruio itself.

Regards

Walter Cromer

unread,
Apr 16, 2021, 6:43:46 AM4/16/21
to beagl...@googlegroups.com
Yes.  It’s throwing an error when I do that. I don’t think it was before but I could be mistaken.  I can’t even query the options with configure-pin.  It makes me wonder if the pins I’m choosing are in use by something else like video or audio.  I will check this today. 


--
Thanks,

Walter Cromer, MS, PMP, PMI-ACP, CSM
Chief Idea Officer and Founder
Eden Concepts LLC
w: http://edenconceptsllc.com
m: 865-719-8881

Walter Cromer

unread,
Apr 16, 2021, 8:18:08 AM4/16/21
to BeagleBoard
As I get a better understanding and experience this may change, but right now I don't think it can handle the volume of data we need to move between systems.  And, that volume is only needed during R&D.  The production system will not need to keep that data.

So, my plan is to instance arrays on the ARM side and use RPMSG to pass the addresses to the PRU.  The PRU code will translate that to ARM addresses.   As the data is collected it will be stored in arrays local to the PRUs (in the 8k or 12k memory spaces).  When the time-sensitive data collection is completed, the PRU array will contain the data.  Then we'll just copy it over the ARM addresses.

My assumption is that since the ARM instances the arrays in memory, Linux will not overwrite those locations so they'll be 'safe'.  I'll probably use RPMSG to alert ARM that the data is going to be transferred and wait on an 'ack' from the ARM before copying it over. 

Seems like it should work.

Walter Cromer

unread,
Apr 16, 2021, 8:23:57 AM4/16/21
to BeagleBoard
I'm 100% sure it wasn't doing this before because I worked through the exercises in Mark Yodre's PRUCookbook and this command

config-pin P9_31 pruout 

worked before

Now it gives

debian@beaglebone:/var/lib/cloud9/PRUCookbook/docs/05blocks/code$ config-pin P9_31 pruout
ERROR: open() for /sys/devices/platform/ocp/ocp:P9_31_pinmux/state failed, No such file or directory

I get the same error when I execute this as root.


Mark Lazarewicz

unread,
Apr 16, 2021, 9:23:35 AM4/16/21
to beagl...@googlegroups.com
Hello Walter

I think so nice novel approach. Since the 2nd PRU is started manualy from command line in Linux you shouldnt get clobbered as thats what that memory is for the PRU code and Resource Tables from my reading. Id guess address  translation is required.  shared RAM could be used as well I know that works thinks are much simpler when ARM is in supervisor mode no userland but I digress.
I saw your latest post I think that issue has come up before maybe search the group I might be wrong maybe poke around in the OCP dir see whats there. How these directories get created should be documented perhaps in some Linux readme none of this tribal knowledge exists in barebone arm its straight C code muxing. Searching E2E I saw a thread blaming Linux for CCS/JTAG issues on PRU theres definately many angry confused users out there I appreciate the difficulty in supporting a complex chip but sorting all this can be daunting. I installed CCCS 10 Win10 for a TI simple Link radio project and Im seeing grayed out feature Id rather avoid CCS on Linux. I've installed CCS on at least a dozen projects on windows never had issues I am still confused as at one point some  features and Processors were not free. These wikis in the past have been very helpful I see some migration going on with that documentation a bit scary. Lastly I found some PRU examples digging in E2E  Im more apt to start with those vs cookbook they mention CCS6. If I delve into Linux/PRU it would be the RPMsg examples and I have a sneaky hunch the command line build example may work fine using sdk linux but from past experience the CCS/JTAG require xml and gel files to hold the ARM core off and do muxing and low level setup of memory.

Hopefully I can share something useful. Does Cookbook have RPMsg examples? 



Mark

Message has been deleted

Dennis Lee Bieber

unread,
Apr 16, 2021, 1:36:16 PM4/16/21
to Beagleboard
On Thu, 15 Apr 2021 09:35:20 -0700 (PDT), in
gmane.comp.hardware.beagleboard.user Walter Cromer
<walterc-2dFtBuzUeF/tpnMUCzy8b...@public.gmane.org> wrote:


>So if I had an application that had a sensor A that needs to be read every
>10ms and sensor B that only needs to be read every minute, I could wire
>channel 1 to sensor A and assign it to step 1 and wire channel 2 to sensor
>B and assign it to step 2.
>
>Then at startup, when I want to read both sensors, I enable steps 1 and 2
>but not 3-16. This saves time on the read as channels 3-7 aren't needed
>and steps 3-16 aren't needed so I don't use them. Then after the initial
>read when I don't need to read sensor B until a minute passes, I can change
>STEPENABLE so only step 1 is enabled and execute a read every 10 ms. Only
>sensor A would be read. Then at one minute intervals, I change STEPENABLE
>so steps 1 & 2 are enabled and when read is triggered, sensors A and B are
>read.
>

Seems like a lot of fiddling around with step enables, and assumes ADC
reading is a one-shot operation. I'd likely just create a process loop with
major frame of 1 minute, minor frame of 10ms (use a "frame counter" that
you increment after every read), and read both sources each time -- but
only report the one-minute source at top of major frame; counter at 60000
if my calculations are right).

The ADC configurations supports continuous mode in which, after all
enabled steps are processed, it loops back to the top and restarts the step
sequence. Note:

"
12.3.4 One-Shot (Single) or Continuous Mode

When the sequencer finishes cycling through all the enabled steps, the
user can decide if the sequencer should stop (one-shot), or loop back and
schedule the step again (continuous).

If one-shot mode is selected, the sequencer will take care of disabling
the step enable bit after the conversion. If continuous mode is selected,
it is the software’s responsibility to turn off the step enable bit.
"
... if doing one-shot, you don't have to turn off the second step enable...
You have to, instead, turn ON the steps you want active before doing the
reads -- every time.

Also pertinent -- as soon as any step is enabled, the ADC goes out of
IDLE to handle enabled steps. There is a master Enable in the CTRL register
-- to synchronize the reads, you'd likely have to set it to 0, program the
steps, then set it to 1 to start the ADC.




--
Dennis L Bieber

jeff....@gmail.com

unread,
Apr 16, 2021, 2:40:43 PM4/16/21
to BeagleBoard
Really interesting post!!  

But I can't seem to find this thread on the new Beaglebone forums webpage over here: https://forum.beagleboard.org/

Am I missing something or just loosing my mind?

Mark Lazarewicz

unread,
Apr 16, 2021, 2:51:04 PM4/16/21
to beagl...@googlegroups.com
Hi Jeff

I have it open on my PC in gmail I'll send you a link to your personal email. Strange stuff going on in my Yahoo client. And searching the group on Google group's took me a few tries to find this so no your not crazy Jeff. Key words seem important I'd imagine this group's archive is huge. Give me 5 minutes and check your email. I'm at the point where I can't offer much help without doing some actual work with CCS and JTAG mainly as a refresher for myself 

Cheers

Mark

--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.
To view this discussion on the web visit

Mark Lazarewicz

unread,
Apr 16, 2021, 2:59:19 PM4/16/21
to 'Mark Lazarewicz' via BeagleBoard

Robert Nelson

unread,
Apr 16, 2021, 2:59:39 PM4/16/21
to Beagle Board
On Fri, Apr 16, 2021 at 1:40 PM jeff....@gmail.com
<jeff....@gmail.com> wrote:
>
> Really interesting post!!
>
> But I can't seem to find this thread on the new Beaglebone forums webpage over here: https://forum.beagleboard.org/
>
> Am I missing something or just loosing my mind?

No, the last sync of the classic BeagleBoard group ran 18 days ago.
Jason is still Beta Testing the other smaller "Beagle" community
sections before the main channel get's fully enabled.. Give it a few
more weeks. ;)

Regards,

--
Robert Nelson
https://rcn-ee.com/

jeff....@gmail.com

unread,
Apr 16, 2021, 3:11:28 PM4/16/21
to BeagleBoard
Ok thank you sir!! (but I probably am still losing my mind :-) )  

The daily emails (and Mark's email) gets us to the latest posts in the meantime.. 

Walter Cromer

unread,
Apr 16, 2021, 5:03:09 PM4/16/21
to BeagleBoard
Dennis - It was just an example that, for me, made it clearer to me the relationship between A/D channels and steps.  This isn't something we're doing in this application.

WC

On Friday, April 16, 2021 at 1:36:16 PM UTC-4 Dennis Bieber wrote:

Mark Lazarewicz

unread,
Apr 17, 2021, 9:13:10 PM4/17/21
to BeagleBoard
<<I have CCS installed on my Windows 10 machine and started working through TI's PRU Hands On Labs.  Unfortunately, the very first one doesn't <<work because their document is written for CCS running on Linux.   Step 6 says to delete the linker file and add it back with Project->Add Files but <<that's grayed out.  I've asked TI about that.

FYI
I just successfully built a simple PRU example in CCS on  win 8 following TI's PRU Hands On Labs
All kinds of examples including complete ADC code  following the guide I was not able to import the RPMsg adavanced ccs projects I found
They even have ARM RTOS to PRU RPMsg(stoked)

may try that with a later version of CCS on win 10

Now the fun part
Choosing a board ( I have BB white or black or am335x EVM) actually finding the power cords and then  choosing one of 3 jtags I own (USB JTAG on the target over  is sweet  g FTDI USB Hi-Speed Devices to a JTAG TAP 
 and single stepping through source code and setting breakpoints 
I cant wait the guide even discussed stopping Linux from hosing jtag

The Docs are very good

The time I spent I learned alot about the Linker cmd file layout and understand the exact address and memory map of PRU  I stopped short of generating a map file 

I couldnt even imagine putting around manually loading pru code from Linux big time waster

Uhmm TI says if you are using a new chip CCS is highly recommended they also punted on VM machine support but its documented for 32 bit windows using Virtualbox and Ubuntu 14.04 or 18.04 LTS that shelves that for my win 10 box 
BUT
I think its time to turn this brand new Windoze 10 laptop into a REAL workstation a dual Boot Ubuntu native install 
hmm seems like a hassle I could build TI RTOS on win10 maybe do both 
So many choices very happy with documention I have found on E2E

Im expecting jtag on pru redirects print commands to a CCS window but why do that when you can examine and watch variables if CCS/JTAG supports a trace buffer I will be in Hog heaven find out tommorrow.

Anyway Linux is not required for CCS and its slow and inferior to Windows 10 version

Mark

On Tuesday, April 13, 2021 at 1:25:06 PM UTC-5 wal...@edenconceptsllc.com wrote:
We're designing it the way you suggested.  The nice thing is that basically the control logic has already been written in C on the ARM side.  Now, I just need to get it ported to the PRUs and create the communications between the PRUs and a new ARM app that supervises everything from the user's point of view.  Meaning, taking inputs like start, stop and giving feedback by turning LEDs on and off.  And it needs to take in some basic system configuration data from the cloud periodically that the PRU will consume to adjust it's operation.  

I am making progress.  Part of my problem was using Cloud9 for development.  That's where all my ARM development has been so far.  I have CCS installed on my Windows 10 machine and started working through TI's PRU Hands On Labs.  Unfortunately, the very first one doesn't work because their document is written for CCS running on Linux.   Step 6 says to delete the linker file and add it back with Project->Add Files but that's grayed out.  I've asked TI about that.   But I got it to compile by writing on the Beagle using nano and compiling it there.   I've ready a lot of TI documentation today and learned a lot. 

Here's one more thing I am struggling with though.  It's a mental block I think.  I'm used to controlling GPIOs on the ARM side using sysfs.   It appears that on the PRU, we use __R30 instead but I don't understand how that works.  I read through it this morning and it still isn't sinking in.  If anyone can help make this clearer, I'd appreciate it.

On Tuesday, April 13, 2021 at 11:25:08 AM UTC-4 lazarman wrote:
Walter

Your best bet.

Run your whole control loop on the PRU that's as realtime as you get. Use a foreground background loop. Use the ARM like a PC with Linux to access the system via ethernet.

You could also run control on ARM without linux but this way you have all the resources of Linux to access the system.

This assumes your output's from control loop are accessable from PRU.

The point is Linux can only run slow control loops and this way you don't have to debug the delay.

This wasn't obvious to me before as all the hard realtime systems I work on run an RTOS on ARM it has all the resources of Linux but cost $$$$$.

In our system we did that on the DSP the PID did the math on a fast DSP.

ARM is just a gateway to outside world.

Myself I'd debug the PRU with JTAG and CCS you can see exactly what's going on and dump these registers from CCS.

Some people like printf but with a PRU based system you are essentially doing barebones.

There's videos on PRU development doing this online.

Loading code via rproc and using  printf is like burning and erasing an eeprom to test your changes. You wait 45 minutes for it to erase try your code and do it again.

Not for me.
On Tue, Apr 13, 2021 at 9:54 AM, Dennis Lee Bieber
On Mon, 12 Apr 2021 13:08:48 -0700 (PDT), in

gmane.comp.hardware.beagleboard.user Walter Cromer
<walterc-2dFtBuzUeF/tpnMUCzy8b...@public.gmane.org> wrote:

>What's really throwing me is the + between what looks like two macro
>values.  Normally, we see the + on the right sign of the equals, right? 
>Or am I forgetting something I used to know!?
>

    Why? Take into account the ()s.

    From what I can tell, this is adding the ADC register offset to the
base address of the (?) wakeup register block, which is passed as parameter
to HWREG (no doubt some macro that sets up actual access to the SoC
registers and returns a pointer or some such), and then assigns 0x02 into
the register so indicated.


--
Dennis L Bieber
--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard+unsub...@googlegroups.com.

To view this discussion on the web visit https://groups.google.com/d/msgid/beagleboard/44cb7gtf6pl4d4j3e6oqo57g5n0hobi29c%404ax.com.

TJF

unread,
Apr 18, 2021, 2:09:43 AM4/18/21
to BeagleBoard
Hi Mark,

you're the master of reversed order! You want to code a main loop before IO is working. You want to CCS/JTAG variables before your first LOC is running. Did you ever finish a project?

When a subsystem is off (not clocked) the PRU can still read or write its registers. Readings are always zero and writings go to Nirvana, no error message, no exeption. How should a debugger help in this case?

Mark Lazarewicz schrieb am Sonntag, 18. April 2021 um 03:13:10 UTC+2:
Anyway Linux is not required for CCS and its slow and inferior to Windows 10 version

LINUX is stable and reliable. Anyway, CSS is not required for PRU development. Since I aim to open up the full PRUSS power (I've payed for), I continue ignoring all that CSS bloat (!! a linker for a 2k instruction space !!).

Regards

Mark Lazarewicz

unread,
Apr 18, 2021, 10:49:22 AM4/18/21
to BeagleBoard
TJF I Dont agree and neither do companies that have sold 10k products that sounds finished to me 

unfortunately CCS doesnt support Basic language so I can see why your worried and I wish you the best of luck getting libpruio inluded in the kernel sincerely.

Linux is great I just dont use it for hard realtime I an in line with TI marketing see below link. The reason the PRU is there is to allow linux as a gateway and hard realtime is done on the PRU. The original poster's project IS NOT hard REAL Time perhaps you can help him get his project working on ARM since thats all you understand.

  Ensuring real-time predictability  
 
The fact that TI also supports QNX , Intergrity and Nucleeus see here https://www.ti.com/tool/TMDSSK3358
shows TI knows what real customers want besides Linux 

I wont insult you like you attempted  to do to me as I consider the source someone who does not develop just pays for solutions you have zero credibility.

Anyway my code is up and running and for the group I will offer another path the AM335X has touch screen and onboard FTDI jtag and isntructions for using CCS on it and Beagle Bone Black. Add up the cost of a JTAG and touch screen its actually reasonable its here


I repeat again from TI a great company with great engineers read this its actually related to the posters original question unlike this angry uncalled for  post . who you want to believe Texas Instrumentr or TJF? 

BTW Rproc and RPMsg is supported by TI in Linux kernel and TI RTTOS its also documented well not Doxygen comments lifted from code 

Some real latencies and exact access times in block diagram no snake oil 


CCS/JTAG is an option not for everyone but recommended for board bring up you know the real work that engineers do..... not some bean counter who doesn't actually do the work 

The user can make his own choices I'm just trying to be helpful

Mark

TJF

unread,
Apr 19, 2021, 1:45:57 AM4/19/21
to BeagleBoard
Hi Mark,

let me first point out that this discussion isn't in my mother tongue. Sometimes I read your statements several times still not understanding what exactly you mean.

Mark Lazarewicz schrieb am Sonntag, 18. April 2021 um 16:49:22 UTC+2:
who you want to believe Texas Instrumentr or TJF?

I believe none of them. The hardware is reality. I make experiments (ask the hardware) to find out what's really correct.

There isn't one great TI company. Hardware engineers made a great AM335x CPU design. It's not bug free, but well usable. And software engineers do everything to block the hardware benefits.

So the question should be: blinking a led, do you want to follow an CCS example (changing with each new kernel version) or an libpruio example published years before (2014, still working)? Do you want to learn from coders making small examples only, or are you interested in hands-on experience form people who did already fill up the IRam of both PRUSS?

You're lucky, I'm waiting for feedback before starting my next project. So I've time to waste of good mojo.

Mark Lazarewicz

unread,
Apr 19, 2021, 12:17:05 PM4/19/21
to beagl...@googlegroups.com
Hello Thomas

My experience is  not only way

We pick the processor then the tools ( RTOS,JTAG. Compiler/ IDE if the stuff doesn't work or if vendor's don't support properly we don't use their product( I determine this usually). Like you I expect answers 🤠



So pick chip, OS then architecture then FINALLY from Hardware System's engineer document IO is assigned and documented  in table and layed out in board 

Low level Coder starts pin muxing coding  and Interrupt and drivers. Application is divided in to tasks or threads by software architect at same time 

I do board support so JTAG for me is something I insist on. ( New hardware).

I like IDE one that allows RTOS awareness Greenhills has one of the Best I have used CCS maybe a dozen time's projects used their DSP

I am familiar with CCS but have worked where you build by command line and make files.

These are huge fortune 200 companies so money is no problems for tools.

One big Medical company my title was tool's software. I played around. I'm a mercenary hired gun. If I don't like their approach and  they lie or waste my time I tactfully explain bad ideas.

A few times I know there design  approach will fail I mention to them at beginning then  I do what I'm told. then it fails they get angry 🤣 

What's a$$ backwards to you is ( your last email) is normal.

For what you do linux makes sense buy hardware don't need JTAG or CCS.


 here in lies the flaw when you use free software the approach to IPC may be less than ideal but getting it fixed no one cares with an RTOS it costs $50K you get support and attention. or Else

In open source you get ignored and runaround in circles and your support is this group which isn't support.

This approach is for hobbyists with big dreams and no budget.

I will say many jobs are using Linux I see them daily doesn't mean I have to. There are free alternative but why bother if Linux works for you and this IPC is flawed you have my attention.

This is another part of my job. Improve RTOS supplied BSP driver's add new ones and find the crap that's not hard real time flawed. 

An example Green Hill's Integrity BSP for omapl138 had examples code of IPC between ARM and DSP given to customer as I mentioned the PhD design fast queues didn't use it improved it made it fast like what your doing.

Now TI had driver's and code and .h files and Green Hills had their own .c .h files doing same thing.

I think TI did custom first stage loader not sure.
It did what about and mlo does on Linux but much better.

There's no one way to design thing's perhaps you can share what's flawed in Rpmsg in details if that's true so you don't get sued call it RP Don't Worky nice.🤣🤏 and bring attention to it's limitations. You sound like smart Guy maybe it's true.

In closing these dev board's or hobby boards serve a purpose. The EVM ones the HW design was very good but I have issues with long term support I'm not going to mention in this group ( poor practice) the early .org boards by Gerald very nice he's gone.

The open source community won't support or don't care about JTAG at least in this group but TI does.
You really have no choices in this group beyond Linux. 

Barebones and RTOS on these boards isn't a concern on this group so I'm wasting my time but it's sometimes good reading. BTW good luck even if you demonstrate this IPC  isn't ideal because that's not the Agenda here. 

It's marketing getting student to Love Linux and this board.

Unfortunately that's not the Real world not ever be used in Missles,Satellites or air.

Boeing and Lockheed have the best engineering in United States. Both of these company uses TI DSP chips they don't use Linux my friend.

Linux is good but not a fix all for everything and getting ignored is something big company won't tolerate just the hobbyists  they have no choices the dire hard open source will save the world fanatic are attracted to all the glamour like sheep.

Then one day they show up in this group posting it don't Worky help me LoL 😆

Great group it's focus is easy building of mainstream linux and keep buying more boards.

What's the next board coming? Was nice when Gerald was onboard nice guy very talented and always had time for questions you see the best  engineer don't feel threatened by questions and are willing to help there's some exception some of the best are over worked micro managed by manager's who have no technical skill and want to advance in company. Good engineer's leave those environments.

Mark

--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.

To view this discussion on the web visit

Mark Lazarewicz

unread,
Apr 19, 2021, 4:22:55 PM4/19/21
to beagl...@googlegroups.com
Here's a job they used to use TI chips but I see they now use NXP. I like NXP chips and the support is good they have ARM based chips this old  old Freescale architecture. 

Linux support

Job Ad


embedded system OS device drivers
Software development experience with designs featuring modern ARM SoC packages (e.g. Board support packages, driver development, and/or JTAG Emulation)
Software development experience with the NXP i.MX SoC family is desirable
Development experience with the Linux OS is desirable
Ability to interpret hardware schematics, circuit designs, and datasheets
Proficiency with C, C++
Proficiency with multi-threaded, multi-core design and/or real-time operating systems



My message here is if  you can't get answers from a vendor buy from someone else who listens.

This assumes you have some leverage and buy chips in quantity.

Again this forum is good for hobbyists the problem is these hobbyists go to TI E2E forum asking for source code for proprietary software and have zero intention of buying chips in bulk.

These are same low caliber engineers who come to this group with a board and Free Linux asking questions like.

It no works kindly revert to me a solution 🤑🤪🤭🤔

They want CCS and JTAG on resume perhaps you can hire them on next project they use Linux because it's free. Only one problem you need to train them at work and pay them too. They also use this group for training purposes they demand solution's, tutorial and source code.

Uhmm Okay I go back to documenting issues I finding on Eval boards I purchased and wasting time on tool's that are deprecated so I can waste my time in this group educating on tool's that are needed by hiring manager but not on resumes.

Maybe Walter will need help on CCS but doubtful at least I'm aware of the state of development

Reply all
Reply to author
Forward
0 new messages