comp.lang.ada
 help / color / mirror / Atom feed
* GNATCOLL-Mmap example
@ 2020-01-25 21:52 Bob Goddard
  2020-01-28  2:10 ` Stephen Leake
  2020-01-28  8:25 ` Dmitry A. Kazakov
  0 siblings, 2 replies; 15+ messages in thread
From: Bob Goddard @ 2020-01-25 21:52 UTC (permalink / raw)


Does anyone have a small GNATCOLL-Mmap example that I can use on Linux. Just can't see what to do and the "example" in the source  just doesn't work.

I need to map the RPi's GPIO memory addresses so that I can do what I need to do.

Buried in other sources, it suggests that I need to create a new System.memory package, I think...


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: GNATCOLL-Mmap example
  2020-01-25 21:52 GNATCOLL-Mmap example Bob Goddard
@ 2020-01-28  2:10 ` Stephen Leake
  2020-01-28  5:59   ` J-P. Rosen
  2020-01-28  8:25 ` Dmitry A. Kazakov
  1 sibling, 1 reply; 15+ messages in thread
From: Stephen Leake @ 2020-01-28  2:10 UTC (permalink / raw)


On Saturday, January 25, 2020 at 1:52:45 PM UTC-8, Bob Goddard wrote:
> Does anyone have a small GNATCOLL-Mmap example that I can use on Linux. Just can't see what to do and the "example" in the source  just doesn't work.

The full code for my usage is complex. Distilling it down, it becomes something like:

declare
   use GNATCOLL.Mmap;
   File : Mapped_File := Open_Read (file_name);
   Region : Mapped_Region := Read (File);
   Buffer : Str_Access := Data (region);
begin
  --  use Buffer as a string, but there are no bounds, so be careful.
end;

> I need to map the RPi's GPIO memory addresses so that I can do what I need to do.

I doubt Mmap is what you want; that is for mapping disk files to memory. To treat a memory address as a string, just use unchecked_conversion to gnatcoll.mmap.str_access, or something similar (remember a real String has bounds, but this doesn't).

--  Stephe


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: GNATCOLL-Mmap example
  2020-01-28  2:10 ` Stephen Leake
@ 2020-01-28  5:59   ` J-P. Rosen
  0 siblings, 0 replies; 15+ messages in thread
From: J-P. Rosen @ 2020-01-28  5:59 UTC (permalink / raw)


Le 28/01/2020 à 03:10, Stephen Leake a écrit :
> The full code for my usage is complex. Distilling it down, it becomes something like:
> 
> declare
>    use GNATCOLL.Mmap;
>    File : Mapped_File := Open_Read (file_name);
>    Region : Mapped_Region := Read (File);
>    Buffer : Str_Access := Data (region);
> begin
>   --  use Buffer as a string, but there are no bounds, so be careful.
> end;
> 
>> I need to map the RPi's GPIO memory addresses so that I can do what I need to do.
> 
I don't know if that's what you need, but for accessing memory directly
you can use my Storage_Stream package at:
http://www.adalog.fr/en/components.html#Storage_Stream

-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: GNATCOLL-Mmap example
  2020-01-25 21:52 GNATCOLL-Mmap example Bob Goddard
  2020-01-28  2:10 ` Stephen Leake
@ 2020-01-28  8:25 ` Dmitry A. Kazakov
  2020-01-28 18:53   ` Bob Goddard
  2020-01-28 19:11   ` Philip Munts
  1 sibling, 2 replies; 15+ messages in thread
From: Dmitry A. Kazakov @ 2020-01-28  8:25 UTC (permalink / raw)


On 2020-01-25 22:52, Bob Goddard wrote:

> I need to map the RPi's GPIO memory addresses so that I can do what I need to do.

See files under:

    /sys/class/gpio

You can use standard Ada I/O to read and set GPIO pins. E.g.

    /sys/class/gpio/gpio/XXX/value

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: GNATCOLL-Mmap example
  2020-01-28  8:25 ` Dmitry A. Kazakov
@ 2020-01-28 18:53   ` Bob Goddard
  2020-01-28 20:07     ` Dmitry A. Kazakov
  2020-01-31 16:59     ` Björn Lundin
  2020-01-28 19:11   ` Philip Munts
  1 sibling, 2 replies; 15+ messages in thread
From: Bob Goddard @ 2020-01-28 18:53 UTC (permalink / raw)


On Tuesday, 28 January 2020 08:25:25 UTC, Dmitry A. Kazakov  wrote:
> On 2020-01-25 22:52, Bob Goddard wrote:
> 
> > I need to map the RPi's GPIO memory addresses so that I can do what I need to do.
> 
> See files under:
> 
>     /sys/class/gpio
> 
> You can use standard Ada I/O to read and set GPIO pins. E.g.
> 
>     /sys/class/gpio/gpio/XXX/value

This was the way I started, but could not get it to read anything. It just blocks trying to read a single character. My c code works fine using the wiringPi libs.

Stephen Leake:
Mmap is used to read more than just disk files. Opening /dev/mem, or even /dev/gpiomem, is just another file.

Regardless, I got it to work. The moral of the story, is never assume example code in the library source works, or even can compile. I got it running a couple of days ago, and have since spent time banging my head against a wall.

This works, both with System.Mmap & GNATCOLL.Mmap...

with Ada.Unchecked_Conversion;
with Ada.Text_IO;
with GNATCOLL.Mmap; use GNATCOLL.Mmap;
with Ada.Strings.Unbounded;
with Ada.Strings.Unbounded.Text_IO;

procedure Mmaptest is
   package Mmap renames GNATCOLL.Mmap;

   File : Mmap.Mapped_File;
   Reg  : Mmap.Mapped_Region;
   Str  : Mmap.Str_Access;
   Offs : Mmap.File_Size := 0;
   Page : constant Mmap.File_Size := Mmap.File_Size (Mmap.Get_Page_Size);
begin
   File := Mmap.Open_Write ("/tmp/file_on_disk");
   
   while Offs < Mmap.Length (File) loop
      Mmap.Read (File, Reg, Offs, Length => Page, Mutable => False);
      Str := Mmap.Data (Reg);
      Ada.Strings.Unbounded.Text_IO.Put (Ada.Strings.Unbounded.To_Unbounded_String (
                                              Str (Integer (Offs - Mmap.Offset (Reg)) + 1 .. Mmap.Last (Reg)))
                                             );
      Offs := Offs + Page; --  Mmap.File_Size (Mmap.Last (Reg));
   end loop;
   
   Mmap.Free (Reg);
   
   if Reg /= Mmap.Invalid_Mapped_Region then
      Ada.Text_IO.Put_Line ("Mapped region still valid");
   end if;
   
   Mmap.Close (File);
   
   if File /= Mmap.Invalid_Mapped_File then
      Ada.Text_IO.Put_Line ("Mapped file still valid");
   end if;
end Mmaptest;

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: GNATCOLL-Mmap example
  2020-01-28  8:25 ` Dmitry A. Kazakov
  2020-01-28 18:53   ` Bob Goddard
@ 2020-01-28 19:11   ` Philip Munts
  2020-01-28 20:15     ` Dmitry A. Kazakov
  2020-01-28 20:18     ` Philip Munts
  1 sibling, 2 replies; 15+ messages in thread
From: Philip Munts @ 2020-01-28 19:11 UTC (permalink / raw)


Or better yet, use my libsimpleio:

https://github.com/pmunts/libsimpleio

The sysfs API for GPIO is now deprecated.

Phil

On Tuesday, January 28, 2020 at 12:25:25 AM UTC-8, Dmitry A. Kazakov wrote:
> On 2020-01-25 22:52, Bob Goddard wrote:
> 
> > I need to map the RPi's GPIO memory addresses so that I can do what I need to do.
> 
> See files under:
> 
>     /sys/class/gpio
> 
> You can use standard Ada I/O to read and set GPIO pins. E.g.
> 
>     /sys/class/gpio/gpio/XXX/value
> 
> -- 
> Regards,
> Dmitry A. Kazakov
> http://www.dmitry-kazakov.de


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: GNATCOLL-Mmap example
  2020-01-28 18:53   ` Bob Goddard
@ 2020-01-28 20:07     ` Dmitry A. Kazakov
  2020-01-28 20:17       ` Bob Goddard
  2020-01-31 16:59     ` Björn Lundin
  1 sibling, 1 reply; 15+ messages in thread
From: Dmitry A. Kazakov @ 2020-01-28 20:07 UTC (permalink / raw)


On 2020-01-28 19:53, Bob Goddard wrote:
> On Tuesday, 28 January 2020 08:25:25 UTC, Dmitry A. Kazakov  wrote:
>> On 2020-01-25 22:52, Bob Goddard wrote:
>>
>>> I need to map the RPi's GPIO memory addresses so that I can do what I need to do.
>>
>> See files under:
>>
>>      /sys/class/gpio
>>
>> You can use standard Ada I/O to read and set GPIO pins. E.g.
>>
>>      /sys/class/gpio/gpio/XXX/value
> 
> This was the way I started, but could not get it to read anything. It just blocks trying to read a single character. My c code works fine using the wiringPi libs.

If I correctly remember you should rewind the file after each reading.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: GNATCOLL-Mmap example
  2020-01-28 19:11   ` Philip Munts
@ 2020-01-28 20:15     ` Dmitry A. Kazakov
  2020-01-28 20:18     ` Philip Munts
  1 sibling, 0 replies; 15+ messages in thread
From: Dmitry A. Kazakov @ 2020-01-28 20:15 UTC (permalink / raw)


On 2020-01-28 20:11, Philip Munts wrote:
> Or better yet, use my libsimpleio:
> 
> https://github.com/pmunts/libsimpleio
> 
> The sysfs API for GPIO is now deprecated.

It would be nice to have a normal device driver with [asynchronous] 
read/write, ioctl etc. But that is probably too much to expect.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: GNATCOLL-Mmap example
  2020-01-28 20:07     ` Dmitry A. Kazakov
@ 2020-01-28 20:17       ` Bob Goddard
  2020-01-29  8:19         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 15+ messages in thread
From: Bob Goddard @ 2020-01-28 20:17 UTC (permalink / raw)


On Tuesday, 28 January 2020 20:07:56 UTC, Dmitry A. Kazakov  wrote:
> On 2020-01-28 19:53, Bob Goddard wrote:
> > On Tuesday, 28 January 2020 08:25:25 UTC, Dmitry A. Kazakov  wrote:
> >> On 2020-01-25 22:52, Bob Goddard wrote:
> >>
> >>> I need to map the RPi's GPIO memory addresses so that I can do what I need to do.
> >>
> >> See files under:
> >>
> >>      /sys/class/gpio
> >>
> >> You can use standard Ada I/O to read and set GPIO pins. E.g.
> >>
> >>      /sys/class/gpio/gpio/XXX/value
> > 
> > This was the way I started, but could not get it to read anything. It just blocks trying to read a single character. My c code works fine using the wiringPi libs.
> 
> If I correctly remember you should rewind the file after each reading.

It did not get that far. It blocks right at the start.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: GNATCOLL-Mmap example
  2020-01-28 19:11   ` Philip Munts
  2020-01-28 20:15     ` Dmitry A. Kazakov
@ 2020-01-28 20:18     ` Philip Munts
  2020-01-28 22:06       ` Bob Goddard
  1 sibling, 1 reply; 15+ messages in thread
From: Philip Munts @ 2020-01-28 20:18 UTC (permalink / raw)


On Tuesday, January 28, 2020 at 11:11:12 AM UTC-8, Philip Munts wrote:
> Or better yet, use my libsimpleio:
> 
> https://github.com/pmunts/libsimpleio
> 
> The sysfs API for GPIO is now deprecated.
> 

Here is a quick example using libsimpleio:

WITH GPIO.libsimpleio;
WITH RaspberryPi;

PROCEDURE test_gpio IS

  outp : CONSTANT GPIO.Pin :=
    GPIO.libsimpleio.Create(RaspberryPi.GPIO18, GPIO.Output);

BEGIN
  LOOP
    outp.Put(True);
    outp.Put(False);
  END LOOP;
END test_gpio;

On a Raspberry Pi 4, which is what happens to be plugged in today, I measured a 360 kHz square wave at GPIO 18.  Never mess around with memory mapped I/O unless you need insanely high performance.  Then you would probably want to use DMA anyway.

Phil

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: GNATCOLL-Mmap example
  2020-01-28 20:18     ` Philip Munts
@ 2020-01-28 22:06       ` Bob Goddard
  0 siblings, 0 replies; 15+ messages in thread
From: Bob Goddard @ 2020-01-28 22:06 UTC (permalink / raw)


On Tuesday, 28 January 2020 20:18:03 UTC, Philip Munts  wrote:
[...]
> Here is a quick example using libsimpleio:
> 
> WITH GPIO.libsimpleio;
> WITH RaspberryPi;
> 
> PROCEDURE test_gpio IS
> 
>   outp : CONSTANT GPIO.Pin :=
>     GPIO.libsimpleio.Create(RaspberryPi.GPIO18, GPIO.Output);
> 
> BEGIN
>   LOOP
>     outp.Put(True);
>     outp.Put(False);
>   END LOOP;
> END test_gpio;
> 
> On a Raspberry Pi 4, which is what happens to be plugged in today, I measured a 360 kHz square wave at GPIO 18.  Never mess around with memory mapped I/O unless you need insanely high performance.  Then you would probably want to use DMA anyway.

Think I'll use that as a backup, but go down the ioctl route, it is a learning process after all...


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: GNATCOLL-Mmap example
  2020-01-28 20:17       ` Bob Goddard
@ 2020-01-29  8:19         ` Dmitry A. Kazakov
  2020-01-29 21:56           ` Bob Goddard
  0 siblings, 1 reply; 15+ messages in thread
From: Dmitry A. Kazakov @ 2020-01-29  8:19 UTC (permalink / raw)


On 2020-01-28 21:17, Bob Goddard wrote:
> On Tuesday, 28 January 2020 20:07:56 UTC, Dmitry A. Kazakov  wrote:
>> On 2020-01-28 19:53, Bob Goddard wrote:
>>> On Tuesday, 28 January 2020 08:25:25 UTC, Dmitry A. Kazakov  wrote:
>>>> On 2020-01-25 22:52, Bob Goddard wrote:
>>>>
>>>>> I need to map the RPi's GPIO memory addresses so that I can do what I need to do.
>>>>
>>>> See files under:
>>>>
>>>>       /sys/class/gpio
>>>>
>>>> You can use standard Ada I/O to read and set GPIO pins. E.g.
>>>>
>>>>       /sys/class/gpio/gpio/XXX/value
>>>
>>> This was the way I started, but could not get it to read anything. It just blocks trying to read a single character. My c code works fine using the wiringPi libs.
>>
>> If I correctly remember you should rewind the file after each reading.
> 
> It did not get that far. It blocks right at the start.

What about this

       use GNAT.OS_Lib;

       FD     : File_Descriptor;
       Buffer : aliased char;
    begin
       FD := Open_Read ("/sys/class/gpio/gpio/XXX/value", Binary);
       Lseek (FD, 0, Seek_Set);
       if 1 = Read (FD, Buffer'Address, 1) then
          if Buffer = '1' then
             ...

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: GNATCOLL-Mmap example
  2020-01-29  8:19         ` Dmitry A. Kazakov
@ 2020-01-29 21:56           ` Bob Goddard
  2020-01-30  2:45             ` Dennis Lee Bieber
  0 siblings, 1 reply; 15+ messages in thread
From: Bob Goddard @ 2020-01-29 21:56 UTC (permalink / raw)


On Wednesday, 29 January 2020 08:19:11 UTC, Dmitry A. Kazakov  wrote:
[...]
> >>> This was the way I started, but could not get it to read anything. It just blocks trying to read a single character. My c code works fine using the wiringPi libs.
> >>
> >> If I correctly remember you should rewind the file after each reading.
> > 
> > It did not get that far. It blocks right at the start.
> 
> What about this
> 
>        use GNAT.OS_Lib;
> 
>        FD     : File_Descriptor;
>        Buffer : aliased char;
>     begin
>        FD := Open_Read ("/sys/class/gpio/gpio/XXX/value", Binary);
>        Lseek (FD, 0, Seek_Set);
>        if 1 = Read (FD, Buffer'Address, 1) then
>           if Buffer = '1' then
>              ...

Well... the call does not block, but I get spurious info back. It fires 1000 in around 1/4s, when it should be about 50Hz, that being the mains line frequency here.

On read, it should be reset. I tried making it RW, but the write fails.

Ho hum, that dent in the wall is getting bigger.


B


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: GNATCOLL-Mmap example
  2020-01-29 21:56           ` Bob Goddard
@ 2020-01-30  2:45             ` Dennis Lee Bieber
  0 siblings, 0 replies; 15+ messages in thread
From: Dennis Lee Bieber @ 2020-01-30  2:45 UTC (permalink / raw)


On Wed, 29 Jan 2020 13:56:56 -0800 (PST), Bob Goddard
<1963bib@googlemail.com> declaimed the following:

>On Wednesday, 29 January 2020 08:19:11 UTC, Dmitry A. Kazakov  wrote:

>> What about this
>> 
>>        use GNAT.OS_Lib;
>> 
>>        FD     : File_Descriptor;
>>        Buffer : aliased char;
>>     begin
>>        FD := Open_Read ("/sys/class/gpio/gpio/XXX/value", Binary);
>>        Lseek (FD, 0, Seek_Set);
>>        if 1 = Read (FD, Buffer'Address, 1) then
>>           if Buffer = '1' then
>>              ...
>
>Well... the call does not block, but I get spurious info back. It fires 1000 in around 1/4s, when it should be about 50Hz, that being the mains line frequency here.
>

	Since your actual code is not present, one must rely upon crystal
balls...

	If it is an input GPIO, then its value will reflect the state of
whatever is applied to the pin. If you have some voltage reducing filter
tracking your AC power, then that pin will return "1" so long as the
voltage is above whatever the design threshold is.

	Your "1000 in around 1/4s" likely reflects how fast your read loop is
processing.

	If you are trying to track changes in the state of the pin, your loop
may need to incorporate a "lastState" variable, and you only report a state
change when the newly read value is different from the "lastState" (and
then update "lastState" to the new value)

        FD     : File_Descriptor;
        Buffer : aliased char;
	  lastState : char;
     begin
        FD := Open_Read ("/sys/class/gpio/gpio/XXX/value", Binary);
        Lseek (FD, 0, Seek_Set);
        if 1 = Read (FD, Buffer'Address, 1) then
	    if lastState /= Buffer then
             lastState := Buffer;
             if Buffer = '1' then
...

{OR... you figure out IF a state change interrupt can be tied to the GPIO
AND how to define an interrupt handler in Ada for it}


-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
	wlfraed@ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: GNATCOLL-Mmap example
  2020-01-28 18:53   ` Bob Goddard
  2020-01-28 20:07     ` Dmitry A. Kazakov
@ 2020-01-31 16:59     ` Björn Lundin
  1 sibling, 0 replies; 15+ messages in thread
From: Björn Lundin @ 2020-01-31 16:59 UTC (permalink / raw)


Den 2020-01-28 kl. 19:53, skrev Bob Goddard:
> On Tuesday, 28 January 2020 08:25:25 UTC, Dmitry A. Kazakov  wrote:
>> On 2020-01-25 22:52, Bob Goddard wrote:
>>
>>> I need to map the RPi's GPIO memory addresses so that I can do what I need to do.
>>
>> See files under:
>>
>>      /sys/class/gpio
>>
>> You can use standard Ada I/O to read and set GPIO pins. E.g.
>>
>>      /sys/class/gpio/gpio/XXX/value
> 
> This was the way I started, but could not get it to read anything. It just blocks trying to read a single character. My c code works fine using the wiringPi libs.
> 
>


Or you just write a wrapper to wiringPi.
I wrote one for _writing_ to gpio-pins

it is at
https://www.dropbox.com/s/svf6e3as0qyx5nr/gpio.zip?dl=0

and is _very_ simple.

it has no support for reading, but that would be trivial to add


add
   package Linker is
    for Default_Switches ("ada") use ("-L/usr/local/lib",
                                      "-lwiringPi");
   end Linker;

to your gpr-file assuming you are using gnat


call Gpio.Setup first - then set mode of pin

Gpio.Pin_Mode(pin, Gpio.Output);

and the write to it

Gpio.Digital_Write(Pin, False);


I used it to write to a small stepper motor
28YBJ-48 
<https://www.banggood.com/sv/28YBJ-48-DC-5V-4-Phase-5-Wire-Stepper-Motor-With-ULN2003-Driver-Board-p-74397.html>




-- 
Björn


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2020-01-31 16:59 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-25 21:52 GNATCOLL-Mmap example Bob Goddard
2020-01-28  2:10 ` Stephen Leake
2020-01-28  5:59   ` J-P. Rosen
2020-01-28  8:25 ` Dmitry A. Kazakov
2020-01-28 18:53   ` Bob Goddard
2020-01-28 20:07     ` Dmitry A. Kazakov
2020-01-28 20:17       ` Bob Goddard
2020-01-29  8:19         ` Dmitry A. Kazakov
2020-01-29 21:56           ` Bob Goddard
2020-01-30  2:45             ` Dennis Lee Bieber
2020-01-31 16:59     ` Björn Lundin
2020-01-28 19:11   ` Philip Munts
2020-01-28 20:15     ` Dmitry A. Kazakov
2020-01-28 20:18     ` Philip Munts
2020-01-28 22:06       ` Bob Goddard

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox