FFI calls to functions that expect pointers to write results into

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

FFI calls to functions that expect pointers to write results into

timrowledge
I haven’t been able to uncover *any* decent doc for FFI calls, so any pointers would be nice.

In particular, given a C function def
void piBoardId (int *model, int *rev, int *mem, int *maker, int *overVolted)
What on earth do I do ?

        #<cdecl: void 'piBoardId' (long * long * long * long* long* ) module: 'wiringPi’>
seems to be the basic incantation but so far I see nothing that might explain to me what would make it actually work.

Really basic stuff like
piBoardRev
"Read the revision code of the Pi. ."
"ScratchWiringPiInterface new piBoardRev"
        #<cdecl: long 'piBoardRev' (void ) module: 'wiringPi'>
        ^self externalCallFailed

seems fine, as does
digitalRead: pin
"Read the value of a given Pin, returning HIGH or LOW"
"ScratchWiringPiInterface new digitalRead: 1"
        #<cdecl: long 'digitalRead' (long ) module: 'wiringPi'>
        ^self externalCallFailed

What has my assorted googling missed?

tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
Useful random insult:- Wasn't fully debugged before being released.



Reply | Threaded
Open this post in threaded view
|

Re: FFI calls to functions that expect pointers to write results into

Levente Uzonyi-2
For each variable allocate some bytes on the external heap using an
ExternalAddress, and wrap into an ExternalData, then pass the ExternalData
as the argument. Something like this:

| modelData modelValue ... |
modelData := ExternalData
  fromHandle: (ExternalAddress gcallocate: 4)
  type: ExternalType long asPointerType.
...
self piBoardId: modelData ...
modelValue := modelData getHandle signedLongAt: 1

Or you can create an ExternalStructure with a single field, and declare
the arguments as pointers to that type instead of long.

Levente

On Wed, 4 Feb 2015, tim Rowledge wrote:

> I haven’t been able to uncover *any* decent doc for FFI calls, so any pointers would be nice.
>
> In particular, given a C function def
> void piBoardId (int *model, int *rev, int *mem, int *maker, int *overVolted)
> What on earth do I do ?
>
> #<cdecl: void 'piBoardId' (long * long * long * long* long* ) module: 'wiringPi’>
> seems to be the basic incantation but so far I see nothing that might explain to me what would make it actually work.
>
> Really basic stuff like
> piBoardRev
> "Read the revision code of the Pi. ."
> "ScratchWiringPiInterface new piBoardRev"
> #<cdecl: long 'piBoardRev' (void ) module: 'wiringPi'>
> ^self externalCallFailed
>
> seems fine, as does
> digitalRead: pin
> "Read the value of a given Pin, returning HIGH or LOW"
> "ScratchWiringPiInterface new digitalRead: 1"
> #<cdecl: long 'digitalRead' (long ) module: 'wiringPi'>
> ^self externalCallFailed
>
> What has my assorted googling missed?
>
> tim
> --
> tim Rowledge; [hidden email]; http://www.rowledge.org/tim
> Useful random insult:- Wasn't fully debugged before being released.
>
>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: FFI calls to functions that expect pointers to write results into

timrowledge

On 04-02-2015, at 2:34 PM, Levente Uzonyi <[hidden email]> wrote:

> For each variable allocate some bytes on the external heap using an ExternalAddress, and wrap into an ExternalData, then pass the ExternalData as the argument. Something like this:

Thanks; I also found X11Display>queryPointer: which does something similar but a tad simpler by just using WordArrays. I think for quick in-and-out calls that should be ok but if there is any chance whatsoever of the pointer sticking around than an external object is going to be quite important. Assuming we don’t want any Earth shattering KaBooms.

I’m still hoping someone can point me to some readable doc about all this.

tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
Do you like me for my brain or my baud?



Reply | Threaded
Open this post in threaded view
|

Re: FFI calls to functions that expect pointers to write results into

David T. Lewis
On Wed, Feb 04, 2015 at 05:48:05PM -0800, tim Rowledge wrote:
>
> On 04-02-2015, at 2:34 PM, Levente Uzonyi <[hidden email]> wrote:
>
> > For each variable allocate some bytes on the external heap using an ExternalAddress, and wrap into an ExternalData, then pass the ExternalData as the argument. Something like this:
>
> Thanks; I also found X11Display>queryPointer: which does something similar but a tad simpler by just using WordArrays. I think for quick in-and-out calls that should be ok but if there is any chance whatsoever of the pointer sticking around than an external object is going to be quite important. Assuming we don?t want any Earth shattering KaBooms.
>

WordArrays hold 32-bit values by definition. That does not sound like a good way to store pointers.

> I?m still hoping someone can point me to some readable doc about all this.
>

I can't say that I have ever seen any documentation other than examples in the image.

<OT>
Is there some reason that you would not just write a plugin for this?
</OT>

Dave
 

Reply | Threaded
Open this post in threaded view
|

Re: FFI calls to functions that expect pointers to write results into

timrowledge

On 04-02-2015, at 7:27 PM, David T. Lewis <[hidden email]> wrote:
>
> WordArrays hold 32-bit values by definition. That does not sound like a good way to store pointers.

Not so much storing pointers as providing somewhere to be pointed *to* so the ffi call can write answers according to the pointers it passes out.

>
>> I?m still hoping someone can point me to some readable doc about all this.
>>
>
> I can't say that I have ever seen any documentation other than examples in the image.

I can’t say I’ve even found any there, worst luck.

>
> <OT>
> Is there some reason that you would not just write a plugin for this?
> </OT>

It may well come to that, but at the moment I’m playing around and an ffi call is (usually) easy. I can make an led blink and read a button now! Pretty cool, eh?


tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
Why do we want intelligent terminals when there are so many stupid users?



Reply | Threaded
Open this post in threaded view
|

Re: FFI calls to functions that expect pointers to write results into

David T. Lewis
On Wed, Feb 04, 2015 at 08:06:37PM -0800, tim Rowledge wrote:
>
> On 04-02-2015, at 7:27 PM, David T. Lewis <[hidden email]> wrote:
> >
> > <OT>
> > Is there some reason that you would not just write a plugin for this?
> > </OT>
>
> It may well come to that, but at the moment I?m playing around and an ffi call is (usually) easy. I can make an led blink and read a button now! Pretty cool, eh?
>

Yes :-)
 

Reply | Threaded
Open this post in threaded view
|

Re: FFI calls to functions that expect pointers to write results into

Herbert König
In reply to this post by timrowledge

Am 05.02.2015 um 05:06 schrieb tim Rowledge:
> It may well come to that, but at the moment I’m playing around and an ffi call is (usually) easy. I can make an led blink and read a button now! Pretty cool, eh?
>
Hi,
I'm blinking LED's and read buttons via the Linux file interface (that
broke with one of the last updates to Raspbian).
Are you willing to share what you are doing? Need a tester?

I use I2C through OSProcess and i2ctools, are you working on that too?

Cheers,

Herbert

Reply | Threaded
Open this post in threaded view
|

Re: FFI calls to functions that expect pointers to write results into

douglas mcpherson
I’ve done similar things too. I created a GPIOPin class which uses an abstract GPIOAccessor class to actually perform the access. I have two concrete subclasses of GPIOAccessor, one uses the file interface like you did for portability (so it works on the BeagleBone Black for example), and the other uses an FFI I developed based on a library called libbcm2835 IIRC.

For I2C I took a similar approach. I developed an abstract I2CBus class which has two concrete subclasses depending on access method. One uses the portable SMBus file i/o style of accessing I2C, the other is an FFI interface again using libbcm2835.

The /dev/mem interfaces (the ones using FFI) are not portable and only work on the RPi, but they are /much/ faster.

I’ve got flashing LEDS, buttons and many kinds of I2C sensors hooked up; even a kind of mini weather station I demoed at Camp Smalltalk Vancouver Island. I planned to release this months ago but got tied up with other stuff. I also was trying to decide whether to publish as an FFI library or go ahead and write a plugin. I decided a plugin would be better, but haven’t got around to writing it.

I believe Tim has followed a similar FFI approach, except instead of using libbcm2835 he is using WiringPi. I think long term we should use WiringPi since it has a lot of traction in the RPi community, but perhaps make a plugin based on it for ease of distribution.

I am happy to share all this .. I just got bogged down trying to figure out the best way to release it.

Best,
Doug

> On Feb 4, 2015, at 22:54, Herbert König <[hidden email]> wrote:
>
>
> Am 05.02.2015 um 05:06 schrieb tim Rowledge:
>> It may well come to that, but at the moment I’m playing around and an ffi call is (usually) easy. I can make an led blink and read a button now! Pretty cool, eh?
>>
> Hi,
> I'm blinking LED's and read buttons via the Linux file interface (that broke with one of the last updates to Raspbian).
> Are you willing to share what you are doing? Need a tester?
>
> I use I2C through OSProcess and i2ctools, are you working on that too?
>
> Cheers,
>
> Herbert
>


Reply | Threaded
Open this post in threaded view
|

Re: FFI calls to functions that expect pointers to write results into

Herbert König
Hey Doug,

that's great.

My approach is a RasPiGPIO class which keeps track of the opened Pins
and I2C buses. Then I have RasPiIoPin and RasPiI2C which do the actual
I/O. I2C goes through OSProcess which I use to call the I2Ctools.

A Smalltalk process polls one I/O pin every 100 ms where I generate
interrupts in Hardware. Only then I deal with the other pins or I2C.

The update of Raspbian which accommodated the RPi B2 broke may file
interface to the GPIO pins by making the files for a freshly exported
pin only accessible to root. So I'd have to export the pin, chmod its
files as root and then deal with the the pins normally.

Do you need root permissions in your approach? Does an upgraded Raspbian
break your approach?

I think before I want a speedier /dev/mem interface I'd try to get I/O
events into Squeak. But not for this project.

If you like to discuss further (I do very much) we can take this to email.

Cheers,

Herbert


Am 05.02.2015 um 08:18 schrieb Douglas McPherson:

> I’ve done similar things too. I created a GPIOPin class which uses an abstract GPIOAccessor class to actually perform the access. I have two concrete subclasses of GPIOAccessor, one uses the file interface like you did for portability (so it works on the BeagleBone Black for example), and the other uses an FFI I developed based on a library called libbcm2835 IIRC.
>
> For I2C I took a similar approach. I developed an abstract I2CBus class which has two concrete subclasses depending on access method. One uses the portable SMBus file i/o style of accessing I2C, the other is an FFI interface again using libbcm2835.
>
> The /dev/mem interfaces (the ones using FFI) are not portable and only work on the RPi, but they are /much/ faster.
>
> I’ve got flashing LEDS, buttons and many kinds of I2C sensors hooked up; even a kind of mini weather station I demoed at Camp Smalltalk Vancouver Island. I planned to release this months ago but got tied up with other stuff. I also was trying to decide whether to publish as an FFI library or go ahead and write a plugin. I decided a plugin would be better, but haven’t got around to writing it.
>
> I believe Tim has followed a similar FFI approach, except instead of using libbcm2835 he is using WiringPi. I think long term we should use WiringPi since it has a lot of traction in the RPi community, but perhaps make a plugin based on it for ease of distribution.
>
> I am happy to share all this .. I just got bogged down trying to figure out the best way to release it.
>
> Best,
> Doug
>
>> On Feb 4, 2015, at 22:54, Herbert König <[hidden email]> wrote:
>>
>>
>> Am 05.02.2015 um 05:06 schrieb tim Rowledge:
>>> It may well come to that, but at the moment I’m playing around and an ffi call is (usually) easy. I can make an led blink and read a button now! Pretty cool, eh?
>>>
>> Hi,
>> I'm blinking LED's and read buttons via the Linux file interface (that broke with one of the last updates to Raspbian).
>> Are you willing to share what you are doing? Need a tester?
>>
>> I use I2C through OSProcess and i2ctools, are you working on that too?
>>
>> Cheers,
>>
>> Herbert
>>
>


Reply | Threaded
Open this post in threaded view
|

Re: FFI calls to functions that expect pointers to write results into

douglas mcpherson

> On Feb 5, 2015, at 06:24, Herbert König <[hidden email]> wrote:
>
> Hey Doug,
>
> that's great.
>
> My approach is a RasPiGPIO class which keeps track of the opened Pins and I2C buses. Then I have RasPiIoPin and RasPiI2C which do the actual I/O. I2C goes through OSProcess which I use to call the I2Ctools.

Yes, interesting. I also used OSProcess when I was initially experimenting.

My design was similar: GPIOPin keeps track of open pins and attempts to close no-longer needed resources with functionality on the class side. The GPIO access was implemented in a separate hierarchy which as I mentioned has 2 concrete subclasses, one for sysfs based file i/o access and one for /dev/mem via FFI.

For I2C, a class representing an I2CBus and another representing a I2CDevice which gets subclassed for different devices. An I2CDevice gets associated with a particular instance of I2CBus.

>
> A Smalltalk process polls one I/O pin every 100 ms where I generate interrupts in Hardware. Only then I deal with the other pins or I2C.
>
> The update of Raspbian which accommodated the RPi B2 broke may file interface to the GPIO pins by making the files for a freshly exported pin only accessible to root. So I'd have to export the pin, chmod its files as root and then deal with the the pins normally.
>
> Do you need root permissions in your approach? Does an upgraded Raspbian break your approach?

For manipulating the GPIO files in  sysfs on Raspbian I did not need root. However, when used on BeagleBone Black Ubuntu root was required. That’s Linux for you. I have not tried on a recent Raspbian. The /dev/mem solutions all required root of course.

>
> I think before I want a speedier /dev/mem interface I'd try to get I/O events into Squeak. But not for this project.
>

The /dev/mem provided by the FFI interfaces is immensely faster. For example I hooked up photocell and capacitor on a GPIO as sort of a (very) poor mans ADC to read the resistance of the photocell. Driving the GPIO low and then reversing the GPIO direction and polling continuously until it comes high was a way to measure the relative time it takes the circuit to charge. Doing this using the file i/o GPIO access was impossible since it was far too slow … usually 1 or 2 polls and the GPIO had already returned to a 1. But with /dev/mem, I could get in the range of 200-400 or higher polls before logic high was detected. So the resolution was much much better. Of course, one could enable an interrupt on the pin but I wasn’t sure how to get that event quickly into Smalltalk.  

> If you like to discuss further (I do very much) we can take this to email.

It would be great to collaborate on and publish a package to wrap GPIO, I2C, and PWM functionalities. I think we should combine our efforts with Tim’s too, as he has been using the wiringPi library via FFI for /dev/mem access, which is probably a better choice than the cobbled together library I used. I think we should include the file i/o based access methods for both GPIO and I2C since it gives some measure of portability to other Linux systems (such as the BeagleBone Black).

>
> Cheers,
>
> Herbert
>
>
> Am 05.02.2015 um 08:18 schrieb Douglas McPherson:
>> I’ve done similar things too. I created a GPIOPin class which uses an abstract GPIOAccessor class to actually perform the access. I have two concrete subclasses of GPIOAccessor, one uses the file interface like you did for portability (so it works on the BeagleBone Black for example), and the other uses an FFI I developed based on a library called libbcm2835 IIRC.
>>
>> For I2C I took a similar approach. I developed an abstract I2CBus class which has two concrete subclasses depending on access method. One uses the portable SMBus file i/o style of accessing I2C, the other is an FFI interface again using libbcm2835.
>>
>> The /dev/mem interfaces (the ones using FFI) are not portable and only work on the RPi, but they are /much/ faster.
>>
>> I’ve got flashing LEDS, buttons and many kinds of I2C sensors hooked up; even a kind of mini weather station I demoed at Camp Smalltalk Vancouver Island. I planned to release this months ago but got tied up with other stuff. I also was trying to decide whether to publish as an FFI library or go ahead and write a plugin. I decided a plugin would be better, but haven’t got around to writing it.
>>
>> I believe Tim has followed a similar FFI approach, except instead of using libbcm2835 he is using WiringPi. I think long term we should use WiringPi since it has a lot of traction in the RPi community, but perhaps make a plugin based on it for ease of distribution.
>>
>> I am happy to share all this .. I just got bogged down trying to figure out the best way to release it.
>>
>> Best,
>> Doug
>>
>>> On Feb 4, 2015, at 22:54, Herbert König <[hidden email]> wrote:
>>>
>>>
>>> Am 05.02.2015 um 05:06 schrieb tim Rowledge:
>>>> It may well come to that, but at the moment I’m playing around and an ffi call is (usually) easy. I can make an led blink and read a button now! Pretty cool, eh?
>>>>
>>> Hi,
>>> I'm blinking LED's and read buttons via the Linux file interface (that broke with one of the last updates to Raspbian).
>>> Are you willing to share what you are doing? Need a tester?
>>>
>>> I use I2C through OSProcess and i2ctools, are you working on that too?
>>>
>>> Cheers,
>>>
>>> Herbert
>>>
>>
>
>


Reply | Threaded
Open this post in threaded view
|

Re: FFI calls to functions that expect pointers to write results into

Herbert König
Hie Doug,
Am 05.02.2015 um 18:00 schrieb Douglas McPherson:
> The /dev/mem provided by the FFI interfaces is immensely faster. For
> example I hooked up photocell and capacitor on a GPIO as sort of a
> (very) poor mans ADC to read the resistance of the photocell. Driving
> the GPIO low and then reversing the GPIO direction and polling
> continuously until it comes high was a way to measure the relative
> time it takes the circuit to charge.
I can appreciate that (EE background :-))
> It would be great to collaborate on and publish a package to wrap
> GPIO, I2C, and PWM functionalities. I think we should combine our
> efforts with Tim’s too, as he has been using the wiringPi library via
> FFI for /dev/mem access, which is probably a better choice than the
> cobbled together library I used. I think we should include the file
> i/o based access methods for both GPIO and I2C since it gives some
> measure of portability to other Linux systems (such as the BeagleBone
> Black).

Definitely yes to all. I'll cook up some documentation, then send you my
code. It's a mere 12K fileout.

Right now I have the problem that it crashes the Pi after about 12
hours, no signs of warning. The Pi is unwilling to start another
process. In the X server I can't open other programs any more and if I
try to SSH into the Pi it says 'The computer is not willing to start a
shell'.

Dunno if it's the latest Raspbian update or my use of OSProcess or GPIO.
So I started everything on a not updated Pi. Half a day between Errors
is not nice to debug :-)) I had two crashes up to now. Tomorrow I'll
know more.

Cheers,

Herbert