ioctl messages to Beagle SPI port.

187 views
Skip to first unread message

John Dammeyer

unread,
May 19, 2021, 11:44:47 PM5/19/21
to beagl...@googlegroups.com

The spidev_test.c program from the Exploring BeagleBone by Derek Molloy (chp08) tests the SPI port by setting the SPI parameters and then writing out a test block.  The text diagnostics I've added show what the macro was that is sent as part of the ioctl call.  Trying to break down the macro through multiple files turned into a dead end and I'm not exactly sure what the 32 bit word means other than byte count and I believe message type.

The program starts out by sending 6 ioctl messages that configure mode, size and speed.

Here's the call that returns the 0x4006B00 and below the result of the message.

ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);

 

debian@ebb:~/exploringBB/chp08/spi/spidev_test$ ./spidev_test                  

SPI_IOC_WR_MODE = 40016B01

SPI_IOC_RD_MODE = 80016B01

SPI_IOC_WR_BITS_PER_WORD = 40016B03

SPI_IOC_RD_BITS_PER_WORD = 80016B03

SPI_IOC_WR_MAX_SPEED_HZ = 40046B04

SPI_IOC_RD_MAX_SPEED_HZ = 80046B04

spi mode: 0

bits per word: 8

max speed: 500000 Hz (500 KHz)

SPI_IOC_MESSAGE(1) = 40206B00

 

00 00 00 00 00 00

00 00 00 00 00 00

00 00 00 00 00 00

00 00 00 00 00 00

00 00 00 00 00 00

00 00 00 00 00 00

00 00

 

Now.  Switch over to a part of the DisplaySPI program in the Lazarus Free Pascal pxl library the function call looks the same as do the SPI initialization calls to fpioctl.  They are in a different order from the C program.

 

Res := fpioctl(FHandle, SPI_IOC_MESSAGE(1), @Data);

 

Six of the ioctl function calls do not return an error.  The main one to send data has the correct

SPI_IOC_MESSAGE(1) value yet it fails.

 

debian@ebb:~/lazarus/pxl/Samples/FreePascal/SingleBoard/Generic/DisplaySPI$ ./DisplaySPI

UpdateFrequency -- SPI_IOC_WR_MAX_SPEED_HZ is 40046B04

UpdateFrequency -- SPI_IOC_RD_MAX_SPEED_HZ is 80046B04

UpdateBitsPerWord -- SPI_IOC_WR_BITS_PER_WORD is 40016B03

UpdateBitsPerWord -- SPI_IOC_RD_BITS_PER_WORD is 80016B03

UpdateRWMode -- SPI_IOC_WR_MODE is 40016B01

UpdateRWMode -- SPI_IOC_RD_MODE is 80016B01

SPI_IOC_MESSAGE(1) is 40206B00

An unhandled exception occurred at $000330A8:

                                             ESysfsSPITransfer: Cannot transfer <1> data byte(s) through SPI bus.

                                   $000330A8  TSYSFSSPI__TRANSFER,  line 263 of /home/debian/lazarus/pxl/Source/PXL.Sysfs.SPI.pas

                                                   $00032F54  TSYSFSSPI__WRITE,  line 241 of /home/debian/lazarus/pxl/Source/PXL.Sysfs.SPI.pas

 

Is there some documentation out there on the ioctl call and what the actual parameter means in detail with respect to the BeagleBone processor?  The man page states that command is specific to the device.

https://man7.org/linux/man-pages/man2/ioctl.2.html

 

I'm having trouble figuring out why it fails or more specifically where to look next.  I can't step the machine code past the ioctl system call so I'd like to know what is actually going on inside the OS with this call inside the Beagle.

 

Thanks

John

 

"ELS! Nothing else works as well for your Lathe"

Automation Artisans Inc.

www dot autoartisans dot com

 

John Dammeyer

unread,
May 20, 2021, 12:03:24 AM5/20/21
to beagl...@googlegroups.com

So to add this so the research I did isn't repeated.

The control message breaks down as follows:

Top two bits are the direction. The 'k' (0x6B) identifies the SPI type.  The number of bytes is placed into the 32 bit word with the _IOC_NRSHIFT which in itself is also a macro all defined in the asm generic ioctl.h file.

 

       ret = ioctl(fd, _IOC(_IOC_WRITE,('k'),(1),(8), &mode);

#define _IOC(dir,type,nr,size) \

        (((dir)  << _IOC_DIRSHIFT) | \

         ((type) << _IOC_TYPESHIFT) | \

         ((nr)   << _IOC_NRSHIFT) | \

         ((size) << _IOC_SIZESHIFT))

 

The shifts are defined to create this and it's quite convoluted to get there.

SPI_IOC_MESSAGE(1) = 40206B00

 

define _IOC_NRBITS     8

#define _IOC_TYPEBITS   8

 

/*

* Let any architecture override either of the following before

* including this file.

*/

 

#ifndef _IOC_SIZEBITS

# define _IOC_SIZEBITS  14

#endif

 

#ifndef _IOC_DIRBITS

# define _IOC_DIRBITS   2

#endif

 

#define _IOC_NRMASK     ((1 << _IOC_NRBITS)-1)

#define _IOC_TYPEMASK   ((1 << _IOC_TYPEBITS)-1)

#define _IOC_SIZEMASK   ((1 << _IOC_SIZEBITS)-1)

#define _IOC_DIRMASK    ((1 << _IOC_DIRBITS)-1)

 

#define _IOC_NRSHIFT    0

#define _IOC_TYPESHIFT  (_IOC_NRSHIFT+_IOC_NRBITS)

#define _IOC_SIZESHIFT  (_IOC_TYPESHIFT+_IOC_TYPEBITS)

#define _IOC_DIRSHIFT   (_IOC_SIZESHIFT+_IOC_SIZEBITS)

 

#define _IOC_NRSHIFT    0

#define _IOC_TYPESHIFT  (_IOC_NRSHIFT+_IOC_NRBITS)

#define _IOC_SIZESHIFT  (_IOC_TYPESHIFT+_IOC_TYPEBITS)

#define _IOC_DIRSHIFT   (_IOC_SIZESHIFT+_IOC_SIZEBITS)

--
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/02a901d74d2a%246b84f600%24428ee200%24%40autoartisans.com.

Mark Lazarewicz

unread,
May 20, 2021, 1:42:55 AM5/20/21
to beagl...@googlegroups.com
#  I can't step the machine code past the ioctl system call

Hi John

What are using to step? It's been a long time but I remember being able to go as deep as I wanted into the linux OS. The hard part was getting kernel source code setup but i had that working requires debugging from linux build machine  but you don't seem adverse to assembly language. Probally unrelated but each high level language passes it's function parameters to the registers in a certain order. I know because we switched from PLM 86 to C one was right to left the other was reversed I wrote an assembler library to fix this in the 80s.

You should be able to step into into anything in  mixed c and assembler mode.

Sorry if I'm not totally understanding but it sounds like you could get insight if you could step into the ioctl

 if its a function you should be able to . C  Macros you can't but it doesn't look like what that is. 


Mark

John Dammeyer

unread,
May 20, 2021, 2:51:13 AM5/20/21
to beagl...@googlegroups.com

Unlike Delphi or say the 9S12 or PIC debugger the Lazarus shows the source but doesn't seem to have a step ability in machine language.  So I can see what it's doing and even the registers but nothing more.

 

Given that the C code works perfectly and the Pascal stuff sends the same information I suspect the problem isn't with the OS but perhaps pointer formatting or something like that.  

 

Still working on it.  Without these kinds of problems I never really learn how things are put together.  So it's not a bad thing.  Just annoying.  The system can send ioctl messages directly as shown in the log.  But when using the transfer function it dies. 

 

So something between 2017 when this code was released and now there is something slightly different.

 

John

 

 

John Dammeyer

unread,
May 20, 2021, 8:43:05 PM5/20/21
to beagl...@googlegroups.com

The latest version of Buster does this when I look for SPI bus ports.  The older Stretch version doesn't have the 0.0 and 0.1 and everything is scaled up by 1. 

 

On either system the scope doesn't show any activity on the SPI0 pins.  No CS, no CLK no Data Out.

 

The test program from Exploring Beaglebone with the DI connected to the DO does not behave with the table changed from the output stream to input which makes sense since there isn't any output on the MOSI or MISO pins.

 

Any suggestions on how to get SPI working?

 

debian@beaglebone:~$ uname -a

Linux beaglebone 4.19.94-ti-r63 #1buster SMP PREEMPT Fri May 14 16:42:32 UTC 2021 armv7l GNU/Linux

 

debian@beaglebone:~$ ls -l /dev/spi*

crw-rw---- 1 root spi 153, 0 May 20 17:24 /dev/spidev0.0

crw-rw---- 1 root spi 153, 1 May 20 17:24 /dev/spidev0.1

crw-rw---- 1 root spi 153, 2 May 20 17:24 /dev/spidev1.0

crw-rw---- 1 root spi 153, 3 May 20 17:24 /dev/spidev1.1

debian@beaglebone:~$

 

 

debian@ebb:~$ uname -a

Linux ebb 4.14.108-ti-r136 #1stretch SMP PREEMPT Mon Jun 8 15:38:30 UTC 2020 armv7l GNU/Linux

 

debian@ebb:~$ ls -l /dev/spi*

crw-rw---- 1 root spi  153, 0 May 20 16:45 /dev/spidev1.0

crw-rw---- 1 root spi  153, 1 May 20 16:45 /dev/spidev1.1

crw-rw---- 1 root spi  153, 2 May 20 16:45 /dev/spidev2.0

crw-rw---- 1 root spi  153, 3 May 20 16:45 /dev/spidev2.1

 

/dev/spi:

total 0

lrwxrwxrwx 1 root root 12 May 20 16:45 0.0 -> ../spidev1.0

lrwxrwxrwx 1 root root 12 May 20 16:45 0.1 -> ../spidev1.1

lrwxrwxrwx 1 root root 12 May 20 16:45 1.0 -> ../spidev2.0

lrwxrwxrwx 1 root root 12 May 20 16:45 1.1 -> ../spidev2.1

debian@ebb:~$

 

==================================================================================================

 

debian@beaglebone:~/exploringBB/chp08/spi/spidev_test$ ./spidev_test -D /dev/spidev0.0

spi mode: 0

bits per word: 8

max speed: 500000 Hz (500 KHz)

 

00 00 00 00 00 00

00 00 00 00 00 00

00 00 00 00 00 00

00 00 00 00 00 00

00 00 00 00 00 00

00 00 00 00 00 00

00 00

debian@beaglebone:~/exploringBB/chp08/spi/spidev_test$

John Dammeyer

unread,
May 20, 2021, 10:19:40 PM5/20/21
to beagl...@googlegroups.com

Alright.

Doing some more research on the web turned up one page where the user is referencing the original Molloy book and complaining about $SLOTs in chapter six not being relevant but using a current OS which doesn't have $SLOTS.  The new edition of the book does not mention $SLOTS but instead config-pin for GPIO management.

 

The sad thing is that Derek Molloy's book, only in passing refers to enabling the SPI port, and the book, in trying to also deal with the pocket beagle pins leaves out things where repetition is actually beneficial.  Maybe somewhere it says that you have to use config-pin to set up SPI.  I missed it.  I think in Chapter 8 page 363 needs a bit of work.

 

So here's what I did following part of that web page suggestion on the Buster image:

debian@beaglebone:~/exploringBB/chp08/spi/spidev_test$ config-pin  p9.17 spi_cs

Current mode for P9_17 is:     spi_cs

debian@beaglebone:~/exploringBB/chp08/spi/spidev_test$ config-pin  p9.22 spi_sclk

Current mode for P9_22 is:     spi_sclk

debian@beaglebone:~/exploringBB/chp08/spi/spidev_test$ config-pin  p9.21 spi

Current mode for P9_21 is:     spi

debian@beaglebone:~/exploringBB/chp08/spi/spidev_test$ config-pin  p9.18 spi

Current mode for P9_18 is:     spi

 

I hadn't realized that this was needed if the spi device was opened as a fille.  I assumed opening a /dev/spi0.0 would automatically claim the pins for SPI.  So with MOSI connected to MISO and specifying the SPI0 port since SPI1 is used by HDMI I get:

 

debian@beaglebone:~/exploringBB/chp08/spi/spidev_test$ ./spidev_test -D /dev/spidev0.0

spi mode: 0

bits per word: 8

max speed: 500000 Hz (500 KHz)

 

FF FF FF FF FF FF

40 00 00 00 00 95

FF FF FF FF FF FF

FF FF FF FF FF FF

FF FF FF FF FF FF

DE AD BE EF BA AD

F0 0D

 

And that data matches what the scope tells me in the attached photo.  Clock is yellow trace. MOSI is Blue.  Green is CS.

 

Oh and none of this explains why the ioctl regardless of C or Pascal can't handle more than 4096 data bytes while the Python code can when sending a large bitmap to the SPI port.  Nor why, according to this web site

https://learn.adafruit.com/setting-up-io-python-library-on-beaglebone-black/spi

nothing is said about config-pin operations so the python library must do this automatically?

 

Now to try this on the Stretch OS based Beagle.

John

 

From: beagl...@googlegroups.com [mailto:beagl...@googlegroups.com] On Behalf Of John Dammeyer


Sent: May-20-21 5:43 PM
To: beagl...@googlegroups.com

--

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.

tek00000.png

Dennis Lee Bieber

unread,
May 21, 2021, 11:58:15 AM5/21/21
to Beagleboard
On Thu, 20 May 2021 19:19:08 -0700, in gmane.comp.hardware.beagleboard.user
"John Dammeyer" <johnd-5o6dItLo...@public.gmane.org> wrote:


>The sad thing is that Derek Molloy's book, only in passing refers to enabling the SPI port, and the book, in trying to also deal with the pocket beagle pins leaves out things where repetition is actually beneficial. Maybe somewhere it says that you have to use config-pin to set up SPI. I missed it. I think in Chapter 8 page 363 needs a bit of work.

One: you have to look at the default pin-mux tables -- the default for
many is as GPIO.

Two: config-pin is discussed in chapter 6 (which also has a
hard-to-read version of the tables). It doesn't mention SPI explicitly, but
does mention that the tool is used in later chapters.

debian@beaglebone:~$
/opt/source/bb.org-overlays/tools/beaglebone-universal-io/config-pin -i
p9_18
Pin name: P9_18
Function if no cape loaded: gpio
Function if cape loaded: default gpio gpio_pu gpio_pd gpio_input spi i2c
pwm pru_uart
Function information: gpio0_4 default gpio0_4 gpio0_4 gpio0_4 gpio0_4
spi0_d1 i2c1_sda ehrpwm0_tripzone_input pru_uart
Kernel GPIO id: 4
PRU GPIO id: 36
debian@beaglebone:~$



>Oh and none of this explains why the ioctl regardless of C or Pascal can't handle more than 4096 data bytes while the Python code can when sending a large bitmap to the SPI port. Nor why, according to this web site

debian@beaglebone:~$ cat /sys/module/spidev/parameters/bufsiz
4096
debian@beaglebone:~$

https://pypi.org/project/spidev/
"""
writebytes2(list of values)

Similar to writebytes but accepts arbitrary large lists. If list size
exceeds buffer size (which is read from
/sys/module/spidev/parameters/bufsiz), data will be split into smaller
chunks and sent in multiple operations.
"""

>https://learn.adafruit.com/setting-up-io-python-library-on-beaglebone-black/spi
>nothing is said about config-pin operations so the python library must do this automatically?

A lot of that is a bit out-of-date -- references to kernel 3.8! Though
I do have to admit I can't find where in Adafruit_BBIO it might do that
set-up -- it doesn't seem to be done in the above spidev Python interface,
which is used by (now deprecated in favor of blinka/circuitpython)
Adafruit_BBIO... And I can't find a config change in blinka or
Adafruit_PureIO. {PureIO may not invoke the above spidev module, so how
/it/ handles large blocks is unknown}




--
Dennis L Bieber

John Dammeyer

unread,
May 21, 2021, 12:40:06 PM5/21/21
to beagl...@googlegroups.com
Thanks Dennis,


> -----Original Message-----
> From: beagl...@googlegroups.com [mailto:beagl...@googlegroups.com] On Behalf Of Dennis Lee Bieber
> "John Dammeyer" <johnd-5o6dItLo...@public.gmane.org> wrote:
>
>
> >The sad thing is that Derek Molloy's book, only in passing refers to enabling the SPI port, and the book, in trying to also deal with the
> pocket beagle pins leaves out things where repetition is actually beneficial. Maybe somewhere it says that you have to use config-pin
> to set up SPI. I missed it. I think in Chapter 8 page 363 needs a bit of work.
>
> One: you have to look at the default pin-mux tables -- the default for
> many is as GPIO.
>
> Two: config-pin is discussed in chapter 6 (which also has a
> hard-to-read version of the tables). It doesn't mention SPI explicitly, but
> does mention that the tool is used in later chapters.

My posting from
Fri 14/05/2021
RE: [beagleboard] Configure CAN0 with buildroot

talks about using config-pin for CAN bus. I spent so much time a number of years ago learning about SLOTs and spending time even writing my own DTS for a proto board that has a 1-wire sensor. The Logic Supply CAN cape dts was also used.

I can't seem to completely unlearn (if that's the right term) and now still get very confused as to what to use and when.

So I guess I should have remembered that on the 14th of May I did use config-pin for CAN so it must also be needed for SPI.


>
> debian@beaglebone:~$
> /opt/source/bb.org-overlays/tools/beaglebone-universal-io/config-pin -i
> p9_18
> Pin name: P9_18
> Function if no cape loaded: gpio
> Function if cape loaded: default gpio gpio_pu gpio_pd gpio_input spi i2c
> pwm pru_uart

I've done that with the pins. But again my incorrect assumption was that the OS was intelligent enough that if I do:

static const char *device = "/dev/spidev1.0";
fd = open(device, O_RDWR);
if (fd < 0)
pabort("can't open device");

One of two things happen. Either It opens the SPI bus which includes everything that config-pin does or it fails because config-pin wasn't done.
In fact I believe that until the config-pin operations on the SPI pins is done that the /dev/spidev1.0 shouldn't exist. That they are there is incorrect information.

But this is 'human factors engineering" which the Beagle (Linux?) lacks in a big way.


> >Oh and none of this explains why the ioctl regardless of C or Pascal
> >
can't handle more than 4096 data bytes while the Python code can when sending a large bitmap to the SPI port.
...
> debian@beaglebone:~$ cat /sys/module/spidev/parameters/bufsiz
> 4096
> debian@beaglebone:~$

How did you know to look at this file to determine the SPI buf size?

I see that it's a read only file.
debian@ebb:~$ ls -al /sys/module/spidev/parameters/bufsiz
-r--r--r-- 1 root gpio 4096 May 20 16:45 /sys/module/spidev/parameters/bufsiz

The code I'm adapting from a 128x128 display sends out a 512x512 lenna.jpg compressed into a smaller window. Even so any sort of bit map object that is 128x128x16 for example is 32K in size. So no matter what sort of canvas I draw on inside the application, to render it out to an SPI display still requires 9 blocks of 4096 bytes.

I'll look into that. Really don't want to write in Python.

> A lot of that is a bit out-of-date -- references to kernel 3.8! Though
> I do have to admit I can't find where in Adafruit_BBIO it might do that
> set-up -- it doesn't seem to be done in the above spidev Python interface,
> which is used by (now deprecated in favor of blinka/circuitpython)
> Adafruit_BBIO... And I can't find a config change in blinka or
> Adafruit_PureIO. {PureIO may not invoke the above spidev module, so how
> /it/ handles large blocks is unknown}

I was going to suggest that the BBB is now an out of date product but
https://www.digikey.ca/en/products/detail/beagleboard-by-seeed-studio/102110420/12719590
shows over 4000 in stock. So maybe not?

John Dammeyer


> --
> 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...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/beagleboard/peifag10s2ohjmb53f5naa8hcgmtmhc9go%404ax.com.

Robert Nelson

unread,
May 21, 2021, 12:50:32 PM5/21/21
to Beagle Board
The am335x based BBB is going to be around for a long time to come...

Regards,

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

John Dammeyer

unread,
May 21, 2021, 12:54:43 PM5/21/21
to beagl...@googlegroups.com
Gawd, I can't even get the math right. 8 blocks of 4096 make up 32K.

At the moment I suspect one of my 320x240 displays might be toast. Even the Python code doesn't light up the screen and that used to work. But it was way back on an OS with $SLOTs.
John


> -----Original Message-----
> From: beagl...@googlegroups.com [mailto:beagl...@googlegroups.com] On Behalf Of John Dammeyer
> Sent: May-21-21 9:40 AM
> To: beagl...@googlegroups.com
> https://groups.google.com/d/msgid/beagleboard/004f01d74e5f%24e220f7b0%24a662e710%24%40autoartisans.com.

Robert Nelson

unread,
May 21, 2021, 1:03:36 PM5/21/21
to Beagle Board
On Fri, May 21, 2021 at 11:54 AM John Dammeyer <jo...@autoartisans.com> wrote:
>
> Gawd, I can't even get the math right. 8 blocks of 4096 make up 32K.
>
> At the moment I suspect one of my 320x240 displays might be toast. Even the Python code doesn't light up the screen and that used to work. But it was way back on an OS with $SLOTs.

If you want to verify it, the old 3.8.x based kernel is still in apt repo..

John Dammeyer

unread,
May 21, 2021, 2:49:14 PM5/21/21
to beagl...@googlegroups.com
> From: beagl...@googlegroups.com [mailto:beagl...@googlegroups.com] On Behalf Of Robert Nelson
Possibly because there are 4000 in stock and no one's buying them? <Bad Joke>

This BBB project is now on hold for a while because my pick and placed inventory just showed up. I now have a 100 units to finish assembling, testing and programming which is going to take a week or so and that means the Beagles have to go back into their kennel to sleep and I'll forget everything I did and have to start over.

Not only that for the next batch of companion products the AUIPS6041 relay drivers have been discontinued. Not just delayed so that means a new board layout with different parts. Luckily I still have about 200 so I'm good until fall.

John
RIMAssemblyParts.jpg

Dennis Lee Bieber

unread,
May 21, 2021, 10:06:40 PM5/21/21
to Beagleboard
On Fri, 21 May 2021 09:39:34 -0700, in gmane.comp.hardware.beagleboard.user
"John Dammeyer" <johnd-5o6dItLo...@public.gmane.org> wrote:

>static const char *device = "/dev/spidev1.0";
> fd = open(device, O_RDWR);
> if (fd < 0)
> pabort("can't open device");
>
>One of two things happen. Either It opens the SPI bus which includes everything that config-pin does or it fails because config-pin wasn't done.

Hypothesis: The "device" (driver) is loaded -- but the pin-mux does not
have the pins connected to the internal port(s) used by the driver... So
the driver is basically dumping output into the "bit-bucket".

It can't really take control -- since the same pins are used by I2C
mode, if opening the "device" did the pin-mux one could really mess up data
transfers (open "I2C" start transfer, then open SPI using the same pins).

>> >Oh and none of this explains why the ioctl regardless of C or Pascal
>> >
>can't handle more than 4096 data bytes while the Python code can when sending a large bitmap to the SPI port.
>...
>> debian@beaglebone:~$ cat /sys/module/spidev/parameters/bufsiz
>> 4096
>> debian@beaglebone:~$
>
>How did you know to look at this file to determine the SPI buf size?

https://www.kernel.org/doc/Documentation/spi/spidev
"""
- There's a limit on the number of bytes each I/O request can transfer
to the SPI device. It defaults to one page, but that can be changed
using a module parameter.

- Because SPI has no low-level transfer acknowledgement, you usually
won't see any I/O errors when talking to a non-existent device.
"""

along with the source for the Python spidev module, which explicitly
mentions that parameter... Though just doing

sudo find / -iname "spidev"

and exploring what each result contains (or to bypass one layer)

debian@beaglebone:~$ ls -R `sudo find / -iname "spidev"`
/sys/bus/spi/drivers/spidev:
bind module spi0.0 spi0.1 spi1.0 spi1.1 uevent unbind

/sys/class/spidev:
spidev0.0 spidev0.1 spidev1.0 spidev1.1

/sys/devices/platform/ocp/48030000.spi/spi_master/spi0/spi0.0/spidev:
spidev0.0

/sys/devices/platform/ocp/48030000.spi/spi_master/spi0/spi0.0/spidev/spidev0.0:
dev device power subsystem uevent

/sys/devices/platform/ocp/48030000.spi/spi_master/spi0/spi0.0/spidev/spidev0.0/power:
async runtime_active_kids runtime_status
autosuspend_delay_ms runtime_active_time runtime_suspended_time
control runtime_enabled runtime_usage

/sys/devices/platform/ocp/48030000.spi/spi_master/spi0/spi0.1/spidev:
spidev0.1

/sys/devices/platform/ocp/48030000.spi/spi_master/spi0/spi0.1/spidev/spidev0.1:
dev device power subsystem uevent

/sys/devices/platform/ocp/48030000.spi/spi_master/spi0/spi0.1/spidev/spidev0.1/power:
async runtime_active_kids runtime_status
autosuspend_delay_ms runtime_active_time runtime_suspended_time
control runtime_enabled runtime_usage

/sys/devices/platform/ocp/481a0000.spi/spi_master/spi1/spi1.0/spidev:
spidev1.0

/sys/devices/platform/ocp/481a0000.spi/spi_master/spi1/spi1.0/spidev/spidev1.0:
dev device power subsystem uevent

/sys/devices/platform/ocp/481a0000.spi/spi_master/spi1/spi1.0/spidev/spidev1.0/power:
async runtime_active_kids runtime_status
autosuspend_delay_ms runtime_active_time runtime_suspended_time
control runtime_enabled runtime_usage

/sys/devices/platform/ocp/481a0000.spi/spi_master/spi1/spi1.1/spidev:
spidev1.1

/sys/devices/platform/ocp/481a0000.spi/spi_master/spi1/spi1.1/spidev/spidev1.1:
dev device power subsystem uevent

/sys/devices/platform/ocp/481a0000.spi/spi_master/spi1/spi1.1/spidev/spidev1.1/power:
async runtime_active_kids runtime_status
autosuspend_delay_ms runtime_active_time runtime_suspended_time
control runtime_enabled runtime_usage

/sys/module/spidev:
coresize holders initstate parameters sections uevent
drivers initsize notes refcnt taint

/sys/module/spidev/drivers:
spi:spidev

/sys/module/spidev/holders:

/sys/module/spidev/notes:

/sys/module/spidev/parameters: <<<<<
bufsiz <<<<<

/sys/module/spidev/sections:
__jump_table __mcount_loc __param __verbose
debian@beaglebone:~$



--
Dennis L Bieber

John Dammeyer

unread,
May 21, 2021, 10:37:06 PM5/21/21
to beagl...@googlegroups.com
> From: beagl...@googlegroups.com [mailto:beagl...@googlegroups.com] On Behalf Of Dennis Lee Bieber
> On Fri, 21 May 2021 09:39:34 -0700, in gmane.comp.hardware.beagleboard.user
> "John Dammeyer" <johnd-5o6dItLo...@public.gmane.org> wrote:
>
> >static const char *device = "/dev/spidev1.0";
> > fd = open(device, O_RDWR);
> > if (fd < 0)
> > pabort("can't open device");
> >
> >One of two things happen. Either It opens the SPI bus which includes everything that config-pin does or it fails because config-pin
> wasn't done.
>
> Hypothesis: The "device" (driver) is loaded -- but the pin-mux does not
> have the pins connected to the internal port(s) used by the driver... So
> the driver is basically dumping output into the "bit-bucket".
>
> It can't really take control -- since the same pins are used by I2C
> mode, if opening the "device" did the pin-mux one could really mess up data
> transfers (open "I2C" start transfer, then open SPI using the same pins).
>
Hmmm. The open() function returns a handle. If it's open already I don't believe the OS allows (or should allow) another task to open the same file. So a hardware device is not like a read only file that can be opened more than once. It's an _exclusive_ r/w phantom file that uses specific code to access it.

This is a standard requirement for any sort of RTOS that requires access to a scarce resource. Since the hardware is a scarce resource both the SPI and I2C and even GPIO need to be 'acquired'. Pascal has a technique for that called assignfile()
https://smartpascal.github.io/help/assets/assignfile.htm

Let's call it AssignIO(). This requests and locks the scarce resource in prep for an open. Odds are unless you have some fancy hardware multiplexing it would stay assigned for the entire program. But nothing stops you from doing a ReleaseIO() and then setting a GPIO bit to mux in the I2C logic and then an AssignIO() for the I2C.

This is all fairly standard RTOS stuff.

John
> --
> 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/v2pgag101omfhqgj1h5p4o03b3ilskegli%404ax.com.

Mark Lazarewicz

unread,
May 22, 2021, 12:14:37 AM5/22/21
to beagl...@googlegroups.com
#Let's call it AssignIO().  This requests and locks #the scarce resource in prep for an open.  Odds are #unless you have some fancy hardware #multiplexing it would stay assigned for the entire #program.  But nothing stops you from doing a #ReleaseIO() and then setting a GPIO bit to mux in #the I2C logic and then an AssignIO() for the I2C.

Take a barebones or Green Hills Integrity RTOS.

Muxing is done in GPIO_Init and some registers are locked and can only be unlocked in ARM  supervisor mode.

GHS Integrity can be run in supervisor mode or virtual mode which uses the MMU and MPU. 

The intent is a bad application can't crash the processor each address space can run an application and won't bring down the processor as in VxWorks AE 653+ Arinc 653) they want that in flight control it's life critical.

I didn't know Linux user space let you remux pins.

The challenge with these SOCs the barebones startup code started getting very complex depending on what pins and peripheral you needed .
I saw that with starterware code for barebones tons of clock and pin and board set-up Data so the code supported everything possible.

In a supervisor mode system the startup code makes sure every pin is configuration won't cause a forging hammer to turn on ie it was safe. You added a peripheral or changed board's the code changed.

In the Linux world all these board.c files got to be too much when most users didn't care about hardware hence these device trees.

The problem in my opinion it's all keeps changing tree's to overlay to sysfs in user space. Config pins changing books out dated. 

I mean hell if you can keep abreast it's job security as it's seems the average Joe can't even a simple i2c device working. Just keep changing things.

That is my biggest gripe against Linux beforehand if I wanted to add something I looked at GPIO init.c and immediately knew what was hooked up.

And yes if I wanted to reconfigure something on the fly I could if I was running in supervisor mode other wise a IO Device ( GHS kernel driver's) abstracted the HW from the PC application programmer type that couldn't use a scope and was only safe writing algorithms.

Flexibility comes at a cost. I'm struggling to stay informed and today saw yet another wiki or blog or book or cookbook that talked about GPIO on Linux.

Something that takes 1 hour to get working ( toggle GPIO) in barebones or RTOS really should not be as difficult as I see people asking about .DTS files almost daily.

I realize a .DTS is no different than a c array holding pin muxing Data 

I think the average user has no clue if it is  uboot passing these to these hardware dependencies in.dts  to the kernel or who loads an overlay.

One final ramble
 I was researching FreeRtos on the Beaglebone bone today I was struck by the average free  RTOS user  is very ARM low level processor cognizant knowledgeable and I saw a readme says see the TRM to see 3 GPIO interrupts being generated to trigger task context switches and how little code was actually involved in a FreeRtos kernel Port some with lwip stack etc 

I mention this because  if the goal of embedded Linux is to abstract hardware so the user doesn't need any knowledge  I'm afraid they might change all this again right when I think I was starting to understand it and make another version of a book necessary 🙈




--
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/v2pgag101omfhqgj1h5p4o03b3ilskegli%404ax.com.

John Dammeyer

unread,
May 25, 2021, 12:46:00 PM5/25/21
to beagl...@googlegroups.com

So I've solved the problem with the

 

ESysfsSPITransfer: Cannot transfer <1> data byte(s) through SPI bus. 

 

The C versions with the spi_ioc_transfer structure declared inside the transfer() function work on both the Beagle and Pi3. 

 

Here's the BBB version from and you can see the code is identical for both the Pi and the Beagle.

https://github.com/derekmolloy/exploringBB/blob/version2/chp08/spi/spidev_test/spidev_test.c

==============================================================================================
uint8_t rx[ARRAY_SIZE(tx)] = {0, };
    struct spi_ioc_transfer tr = {
        .tx_buf = (unsigned long)tx,
        .rx_buf = (unsigned long)rx,
        .len = ARRAY_SIZE(tx),
        .delay_usecs = delay,
        .speed_hz = speed,
        .bits_per_word = bits,
    };



    ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);

    if (ret < 1)
        pabort("can't send spi message");

==============================================================================

Here's the Pi version from exploringPi Chp08 spidev_test.c

struct spi_ioc_transfer tr = {
       
.tx_buf = (unsigned long)tx,
       
.rx_buf = (unsigned long)rx,
       
.len = ARRAY_SIZE(tx),
       
.delay_usecs = delay,
       
.speed_hz = speed,
       
.bits_per_word = bits,
   
};

    ret
= ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
   
if (ret < 1)
        pabort(
"can't send spi message");
==============================================================================

Both identical.

 

So now let's look at the Lazarus Free Pascal version from inside the pxl library PXL.Sysfs.SPI and see if there's anything different.

 

  Data.tx_buf := PtrUInt(WriteBuffer);
  Data.rx_buf := PtrUInt(ReadBuffer);
  Data.len := BufferSize;
  Data.delay_usecs := 0;
  Data.speed_hz := FFrequency;
  Data.bits_per_word := FBitsPerWord;



  Res := fpioctl(FHandle, SPI_IOC_MESSAGE(1), @Data);

  if Res < 0 then
    raise ESysfsSPITransfer.Create(Format(SCannotSPITransferBytes, [BufferSize]));
==============================================================================

 

Doesn't seem like there's any difference yet the Lazarus version fails.  After more searching on the net I stumbled onto a posting in a Pi forum where someone else was having similar problems.  A reply to his question was an example that was working but unfortunately that link was "404 not found".  However the original poster did state what the difference between the working code and his and his solution.

 

Now the Pascal version succeeds without an error.  I've yet to check if SPI data is showing up in hardware but I imagine it will.  The good thing is the runtime error is now gone.

  FillByte(Data, Sizeof(Data), 0);  // Without this FillByte() fpioctl fails.

  Data.tx_buf := PtrUInt(WriteBuffer);
  Data.rx_buf
:= PtrUInt(ReadBuffer);
  Data.len
:= BufferSize;
  Data.delay_usecs
:= 0;
  Data.speed_hz
:= FFrequency;
  Data.bits_per_word
:= FBitsPerWord;

  Res
:= fpioctl(FHandle, SPI_IOC_MESSAGE(1), @Data);
 
if Res < 0 then
   
raise ESysfsSPITransfer.Create(Format(SCannotSPITransferBytes, [BufferSize]));

It's likely the C compiler clears this structure when it's declared or extends 0's out on an assignment that isn't done by the FreePascal compiler.  And that it was required in that Pi forum posting for C code suggests it's perhaps even somewhat random.  Compiler flags maybe?

 

So that's the solution for this run time error.  Clear the data structure before initializing parameters and calling ioctl().

 

If I get a chance today I'll see if SPI data is actually coming out of the processor but based on the sample application behavior it likely is.

 

John

 

Dennis Lee Bieber

unread,
May 25, 2021, 1:39:11 PM5/25/21
to Beagleboard
On Tue, 25 May 2021 09:45:39 -0700, in gmane.comp.hardware.beagleboard.user
"John Dammeyer" <johnd-5o6dItLo...@public.gmane.org> wrote:


>
>Here's the BBB version from and you can see the code is identical for both the Pi and the Beagle.
>https://github.com/derekmolloy/exploringBB/blob/version2/chp08/spi/spidev_test/spidev_test.c
>==============================================================================================
>uint8_t rx[ARRAY_SIZE(tx)] = {0, };
> struct spi_ioc_transfer tr = {
> .tx_buf = (unsigned long)tx,
> .rx_buf = (unsigned long)rx,

Somewhat confusing code -- one has to track upwards in the code... C
arrays are a synonym for pointers, so he's using unsigned long to store a
pointer to the array.

I'm not downloading the source again to see how the buffers are
defined...
>
> Data.tx_buf := PtrUInt(WriteBuffer);
> Data.rx_buf := PtrUInt(ReadBuffer);

... just notice this explicitly asks for a pointer (given my stale C
history, I'd tend to read that as a pointer to an unsigned integer of some
size... But the C version has the buffers defined as uint8_t (new in
C99/C++11) with is an 8-bit unsigned (equivalent to old unsigned char).

Does FreePascal have size differentiation?



>It's likely the C compiler clears this structure when it's declared or extends 0's out on an assignment that isn't done by the FreePascal compiler. And that it was required in that Pi forum posting for C code suggests it's perhaps even somewhat random. Compiler flags maybe?

"""
-fno-zero-initialized-in-bss

If the target supports a BSS section, GCC by default puts variables
that are initialized to zero into BSS. This can save space in the resulting
code.
"""

is the closest GCC option I saw. The OS may do zeroing when it allocates a
block of memory to the application, but that wouldn't affect stack usage --
and the C code is allocating the structure on the stack. I presume Pascal
is doing the same (since it allows recursion). Not seeing the declaration
of "Data" means I can't be certain -- FreePascal may have keywords to force
allocation on heap..



--
Dennis L Bieber

John Dammeyer

unread,
May 25, 2021, 3:55:59 PM5/25/21
to beagl...@googlegroups.com

I agree, the C code uses the equivalent of the WITH statement in Pascal to assign parameters during structure declaration.  Once you 'get' how it works it's fairly readable.

 

My understanding is both systems place the variables on the heap.  Only the small micro-controllers with limited stack space (recall some of the PIC16 series had a 2 word call stack).  Other systems in the micro-controller area might limit the stack to 256  bytes due to paging schema.

 

The record (struct) is essentially the same in C or Pascal.

  spi_ioc_transfer = record

    tx_buf: UInt64;

    rx_buf: UInt64;

    len: LongWord;

    speed_hz: LongWord;

    delay_usecs: Word;

    bits_per_word: Byte;

    cs_change: Byte;

    pad: LongWord;

  end;

 

The C one with some extra information about the requirements of the structure is here:

https://github.com/spotify/linux/blob/master/include/linux/spi/spidev.h

 

In both cases the requirement is that they are 32 bytes in length hence the pad at the end. 

Filling it with zero's first implies that the transition of the address of a BYTE buffer to unsigned 64 bit is probably being corrupted in some unexpected way.   With Pascal, generally, globals are initialized to 0's as are C variables unless you add the flag to not initialize in the C startup code.  Locals on the stack are not for both languages.

 

The pxl library was last updated in 2017 and there are photos and fritzing diagrams on how to connect hardware so that the image on the displays is created by the example programs (both Pi and BBB).  That it worked in 2017 and now doesn't means something in either the OS and the ioctl() interface has changed or the FreePascal compiler is doing something different.

 

And that other link that I now can't find anymore shows that even for the Pi3 a C program without the fill structure with 0's will fail in exactly the same way.  Don't remember the date.  May well have been roughly the same revision OS which means the issue might well have been in the ioctl() at the OS level for SPI bus.

 

As the attached screen shot shows, SPI packets are now longer than 1 or 2 bytes on a Beaglebone with code written in Pascal.  It's finally behaving.

 

For now I'm going to consider this 'fixed' and I will pass on the information to the pxl library source. 

 

BTW.  For the Pi to make this work I have to either run it with sudo from the command line or run Lazarus with sudo.  The help everyone provided on the Beagle  to make my user part of the gpio group means the code can run and be debugged from within the IDE.

 

Thanks

John

 

 

> -----Original Message-----

> From: beagl...@googlegroups.com [mailto:beagl...@googlegroups.com] On Behalf Of Dennis Lee Bieber

> Sent: May-25-21 10:39 AM

> To: Beagleboard

> Subject: [beagleboard] Re: ioctl messages to Beagle SPI port.

> --

> 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

tek00000.png

Dennis Lee Bieber

unread,
May 25, 2021, 9:34:15 PM5/25/21
to Beagleboard
On Tue, 25 May 2021 12:55:32 -0700, in gmane.comp.hardware.beagleboard.user
"John Dammeyer" <johnd-5o6dItLo...@public.gmane.org> wrote:


>My understanding is both systems place the variables on the heap. Only the small micro-controllers with limited stack space (recall some of the PIC16 series had a 2 word call stack). Other systems in the micro-controller area might limit the stack to 256 bytes due to paging schema.

Unless things have changed in the last decade or two, the normal
behavior of variables defined within a C function is that they were
allocated on the stack. I believe to get them into the heap or BSS space
required them to be declared "static"... Or to use malloc() (and kin) to
allocate the structure space from the heap (I think C++ "new" is equivalent
to a heap allocation).

https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&ved=2ahUKEwi_n8HplubwAhUEH80KHTvaDnMQFnoECCgQAA&url=https%3A%2F%2Fwww.seas.upenn.edu%2F~cit593%2Fcit593f09%2Flectures%2Fstructs.pdf&usg=AOvVaw1TWuW67QkVCNXBNHnhbVan
"""
We define a variable using our new data type as follows:

struct w_type day;

Memory is now allocated (on stack), and we can access
individual fields of this variable
"""

Or http://www.avabodh.com/cin/structure.html which has a sample of assembly
output, which sure looks like stack-relative access to me...

>
>The record (struct) is essentially the same in C or Pascal.
> spi_ioc_transfer = record
> tx_buf: UInt64;
> rx_buf: UInt64;
> len: LongWord;
> speed_hz: LongWord;
> delay_usecs: Word;
> bits_per_word: Byte;
> cs_change: Byte;
> pad: LongWord;
> end;

Something else to consider -- alignment. C compilers may add padding
between elements to match some architecture idea of ease-of-access (on a
four-byte alignment, a single byte/char field will have three bytes of
padding added to put following data on a 4-byte increment). cf the avabodh
page.


>BTW. For the Pi to make this work I have to either run it with sudo from the command line or run Lazarus with sudo. The help everyone provided on the Beagle to make my user part of the gpio group means the code can run and be debugged from within the IDE.

Sounds like the R-Pi may not have set the same group memberships.
Though mine seems to have gpio and spi set...

pi@rpi3bplus-1:~$ groups
pi adm dialout cdrom sudo audio video plugdev games users input netdev
lpadmin gpio i2c spi
pi@rpi3bplus-1:~$



--
Dennis L Bieber

John Dammeyer

unread,
May 25, 2021, 10:17:10 PM5/25/21
to beagl...@googlegroups.com
Hi Dennis,
I tried on the groups site to edit this post and change what I wrote.
I meant to say both systems _do_not_ place local variables on the heap. In fact I'm not sure that static are placed on the heap since that could cause all sorts of fragmentation issues.

The advantage of static is you can have
void
RunTimeDisplayThread(void) {
static int32 spc = 0;

The map file shows it as static in the data area
spc 0x0001d8 data static P:\ELeadscrew\PIC18Code\src\ELeadscrew.c

Which means it's initialized in the startup file along with all the other globals. The difference between globals and the statics is the statics are private and not accessible outside the function.


>
> Something else to consider -- alignment. C compilers may add padding
> between elements to match some architecture idea of ease-of-access (on a
> four-byte alignment, a single byte/char field will have three bytes of
> padding added to put following data on a 4-byte increment). cf the avabodh
> page.

It's a good point you make there. However then the SizeOf function might well return something different in size to make everything fit. I've also heard of systems re-arranging the members of a record to suit. In pascal to make that happen you defined it as packed.

Now that I know the solution I'll take some time and capture what the memory looks like with and without the FillByte function.

>
>
> >BTW. For the Pi to make this work I have to either run it with sudo from the command line or run Lazarus with sudo. The help
> everyone provided on the Beagle to make my user part of the gpio group means the code can run and be debugged from within the
> IDE.
>
> Sounds like the R-Pi may not have set the same group memberships.
> Though mine seems to have gpio and spi set...
>
> pi@rpi3bplus-1:~$ groups
> pi adm dialout cdrom sudo audio video plugdev games users input netdev
> lpadmin gpio i2c spi
> pi@rpi3bplus-1:~$

This one has this:
pi@raspberrypi:~/projects/lazarus/TC $ groups
pi adm dialout cdrom sudo audio video plugdev games users input netdev lpadmin gpio i2c spi

To blink the LED the python program doesn't need sudo. Which makes sense given the groups.

Because this example program uses the high speed gpio the fault happens much sooner on the Pi without the sudo.

pi@raspberrypi:~/projects/lazarus/TC $ ./TC
An unhandled exception occurred at $00084EE4:
ERPiOpenFile: Cannot not open file </dev/mem> for memory mapping.
$00084EE4 TFASTSYSTEMCORE__CREATE, line 451 of /home/pi/projects/lazarus/pxl/Source/PXL.Boards.RPi.pas
$00010410 main, line 95 of TC.lpr

I'll build that project on the Beagle and see what happens.
John

> --
> 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...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/beagleboard/ra9rag5p83r4p3kgl8bmt19u9asiipd5b9%404ax.com.

John Dammeyer

unread,
May 25, 2021, 10:45:16 PM5/25/21
to beagl...@googlegroups.com
> Because this example program uses the high speed gpio the fault happens much sooner on the Pi without the sudo.
>
> pi@raspberrypi:~/projects/lazarus/TC $ ./TC
> An unhandled exception occurred at $00084EE4:
> ERPiOpenFile: Cannot not open file </dev/mem> for memory mapping.
> $00084EE4 TFASTSYSTEMCORE__CREATE, line 451 of /home/pi/projects/lazarus/pxl/Source/PXL.Boards.RPi.pas
> $00010410 main, line 95 of TC.lpr
>
> I'll build that project on the Beagle and see what happens.
> John

OK. Hadn't noticed until I tried it on the Beagle that it uses PXL.Boards.RPi.pas which has the definitions for the high speed I/O. The Beagle doesn't appear to have that feature as there is no PXL.Boards.BBB.pas file. Looks like Beagle I/O has to go through the file system.

So this particular SPI program is _not_ portable from the Pi to the Beagle and therefore I will stop talking about it on this Beagleboard forum.

John


Dennis Lee Bieber

unread,
May 25, 2021, 11:54:57 PM5/25/21
to Beagleboard
On Tue, 25 May 2021 19:16:51 -0700, in gmane.comp.hardware.beagleboard.user
"John Dammeyer" <johnd-5o6dItLo...@public.gmane.org> wrote:

>Hi Dennis,
>I tried on the groups site to edit this post and change what I wrote.

While the master copy appears to be a Google Groups entry, it seems to
be propagated outward since gmane is able to copy it and provide NNTP
access (which is how I'm reading -- but about a year ago submitted replies
via gmane were getting rejects from the main group, so I've had to email
replies to Google...).

NNTP spec does offer a CANCEL command to delete posts... BUT most
servers have disabled that (too easy to spoof a user and delete posts one
objects to, perhaps).

Since the messages are on distributed servers, they are essentially
"fire and forget" -- there is nothing one can do once they've hit send...

>It's a good point you make there. However then the SizeOf function might well return something different in size to make everything fit. I've also heard of systems re-arranging the members of a record to suit. In pascal to make that happen you defined it as packed.
>

My concern was that the C code might be packing things differently from
FreePascal, which could mean some of the arguments will not be where the
kernel expects to find them.

OTOH: I believe ARM Cortex architecture is defined to use byte
alignment (even if word/longword alignment is how the memory bus operates),
so both C and Pascal should be generating packed structures.

>Because this example program uses the high speed gpio the fault happens much sooner on the Pi without the sudo.
>
>pi@raspberrypi:~/projects/lazarus/TC $ ./TC
>An unhandled exception occurred at $00084EE4:
> ERPiOpenFile: Cannot not open file </dev/mem> for memory mapping.
> $00084EE4 TFASTSYSTEMCORE__CREATE, line 451 of /home/pi/projects/lazarus/pxl/Source/PXL.Boards.RPi.pas
> $00010410 main, line 95 of TC.lpr
>

That may be devolving to the similar timing problem as earlier -- if it
is doing memory mapping to get to GPIO rather than using the sysfs access,
it may take time to get memory privileges set up.

https://man7.org/linux/man-pages/man4/mem.4.html

Hmmm, it appears that /dev/mem is a udev victim. Freshly booted a BBB gave

crw-r----- 1 root root 1, 1 Dec 31 1999 mem

but repeating the command a few seconds later shows

crw-r----- 1 root kmem 1, 1 May 25 23:45 /dev/mem

(note that the first is using the system default date, while the second is
after the system synched clocks).

Making the R-Pi user a member of group kmem might improve things; the
Beagle already has kmem for user

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


--
Dennis L Bieber

Dennis Lee Bieber

unread,
May 26, 2021, 12:01:07 AM5/26/21
to Beagleboard
On Tue, 25 May 2021 19:44:55 -0700, in gmane.comp.hardware.beagleboard.user
"John Dammeyer" <johnd-5o6dItLo...@public.gmane.org> wrote:


>
>OK. Hadn't noticed until I tried it on the Beagle that it uses PXL.Boards.RPi.pas which has the definitions for the high speed I/O. The Beagle doesn't appear to have that feature as there is no PXL.Boards.BBB.pas file. Looks like Beagle I/O has to go through the file system.

Well -- it might be possible to clone the R-Pi version and redefine all
the memory and bitmap addresses to match the BBB <G>, and then modify
whatever code detects the platform...

>
>So this particular SPI program is _not_ portable from the Pi to the Beagle and therefore I will stop talking about it on this Beagleboard forum.

Technically, I think the "program" source is portable, but not binaries
-- the device access is different between the two, but the end result
should be the same.

See my previous response regarding the R-Pi kmem group membership.


--
Dennis L Bieber

John Dammeyer

unread,
May 26, 2021, 12:02:18 AM5/26/21
to beagl...@googlegroups.com
And yet more progress using the pxl library and Lazarus with the rewritten code from the pxl Blinky.pas example and adafruit_max31855.py. SPI bus operation. Source code attached.

debian@ebb:~/lazarus/TC$ ./TC
Reading temperature, press any key to exit...
Temperature: 21.25C 70.25F
Temperature: 21.25C 70.25F
Temperature: 21.25C 70.25F
Temperature: 21.5C 70.7F
Temperature: 21.25C 70.25F

John
TC.lpr

John Dammeyer

unread,
May 26, 2021, 12:13:19 AM5/26/21
to beagl...@googlegroups.com
Hi Dennis,
I will investigate that further. Wanted to get the SPI bus Type K Thermocouple module working first. Baby steps.
The code is slightly different from the Pi but not radically so. I used '/dev/spi/0.0' since there is no '/dev/spidev0.0' on my Beagle.


>
> My concern was that the C code might be packing things differently from
> FreePascal, which could mean some of the arguments will not be where the
> kernel expects to find them.
>
> OTOH: I believe ARM Cortex architecture is defined to use byte
> alignment (even if word/longword alignment is how the memory bus operates),
> so both C and Pascal should be generating packed structures.
>
> >Because this example program uses the high speed gpio the fault happens much sooner on the Pi without the sudo.
> >
> >pi@raspberrypi:~/projects/lazarus/TC $ ./TC
> >An unhandled exception occurred at $00084EE4:
> > ERPiOpenFile: Cannot not open file </dev/mem> for memory mapping.
> > $00084EE4 TFASTSYSTEMCORE__CREATE, line 451 of /home/pi/projects/lazarus/pxl/Source/PXL.Boards.RPi.pas
> > $00010410 main, line 95 of TC.lpr
> >
>
> That may be devolving to the similar timing problem as earlier -- if it
> is doing memory mapping to get to GPIO rather than using the sysfs access,
> it may take time to get memory privileges set up.
>
> https://man7.org/linux/man-pages/man4/mem.4.html
>
> Hmmm, it appears that /dev/mem is a udev victim. Freshly booted a BBB gave
>
> crw-r----- 1 root root 1, 1 Dec 31 1999 mem
>
> but repeating the command a few seconds later shows
>
> crw-r----- 1 root kmem 1, 1 May 25 23:45 /dev/mem
>
> (note that the first is using the system default date, while the second is
> after the system synched clocks).
>
I get the same /dev/mem value. I thought about adding time delays in there but that would just be me hacking away at trying things without knowing why. Normally for me a waste of time.

> Making the R-Pi user a member of group kmem might improve things; the
> Beagle already has kmem for user

The Code works on the Pi but not on the Beagle using the PXL.DevicePi or whatever it was named. There may be other processor specific items in that unit that just won't work with direct memory access. When I have some time I'll take a closer look at how hardware is access directly on the Pi compared to the BBB. It would be useful to have a DeviceBBB. However even with belonging to the kmem group it's really not happy with /dev/mem so something else is up there.

I did notice that the delay periods were rock solid.

John Dammeyer

unread,
May 26, 2021, 12:31:07 AM5/26/21
to beagl...@googlegroups.com
> From: beagl...@googlegroups.com [mailto:beagl...@googlegroups.com] On Behalf Of Dennis Lee Bieber
> On Tue, 25 May 2021 19:44:55 -0700, in gmane.comp.hardware.beagleboard.user
> "John Dammeyer" <johnd-5o6dItLo...@public.gmane.org> wrote:
>
>
> >
> >OK. Hadn't noticed until I tried it on the Beagle that it uses PXL.Boards.RPi.pas which has the definitions for the high speed I/O. The
> Beagle doesn't appear to have that feature as there is no PXL.Boards.BBB.pas file. Looks like Beagle I/O has to go through the file
> system.
>
> Well -- it might be possible to clone the R-Pi version and redefine all
> the memory and bitmap addresses to match the BBB <G>, and then modify
> whatever code detects the platform...
>
That would have to be done.

> >
> >So this particular SPI program is _not_ portable from the Pi to the Beagle and therefore I will stop talking about it on this
> Beagleboard forum.
>
> Technically, I think the "program" source is portable, but not binaries
> -- the device access is different between the two, but the end result
> should be the same.
>

Well almost. In the uses section PXL.Devices.RPi or PCL.Devices.BBB would be one area set up with an
{$IFDEF}

Same with the path to the SPI.

And the code was designed to run more than 1 SPI device which is why they were inclining to perhaps two or three SEL lines and a decoder to deal with more than one. The comment in the code as I recall was to leave the actual physical SPI0 CS disconnect since it can't be disabled and used as gpio with the SPI active. Although it did seem like it with the config-pins function. At least on the Beagle.

Tomorrow I'll take a closer look at the structures and write a dump utility to compare the two. That should give a clue as to where the system ioctl is hiccupping.
John


Reply all
Reply to author
Forward
0 new messages