Interfacing native code to hardware functions

1,979 views
Skip to first unread message
Message has been deleted

jon.schell

unread,
Nov 16, 2010, 6:10:40 PM11/16/10
to android-porting
I am trying to create a simple app for testing that will toggle an LED
on the phone as needed. I have the NDK set up and my c code compiles,
but I don't know how to link it to the actual hardware function that
would set the LED. I'm using the actual source code for the hardware,
it's not in an exposed library. Do I need to create a static library
for it to use? Would it maybe be easier to add an android API for
this somehow rather than using the NDK?

For reference, this is Android 2.1 on a Qualcomm MSM7627.

Jonathan

Mikkel Christensen

unread,
Nov 23, 2010, 5:33:19 AM11/23/10
to android-porting
Hello,

I would use the SimpleJNI sample application [1] as a base reference.
This does the right coupling from Android application to your lower
level hardware interface.

If the LED is already exposed in sysfs you are lucky and it should be
quite easy. Otherwise create a Kernel device driver that does the
exposure of the LED to sysfs.

Then in the /jni/native.cpp function do the proper write to the sysfs
entry like this (note: this depends on how the led is exposed trough
sysfs):

ret = system("echo 1 > /sys/class/leds/red/brightness");

Make sure that you have given the right write permissions to the LED
sysfs entry. This can be done in your init.rc file.

Best regards,
Mikkel Christensen

[1] http://android.git.kernel.org/?p=platform/development.git;a=tree;f=samples/SimpleJNI

Chris Stratton

unread,
Nov 23, 2010, 1:12:43 PM11/23/10
to android-porting
On Nov 23, 5:33 am, Mikkel Christensen <mikkel.christen...@ixonos.com>
wrote:

> If the LED is already exposed in sysfs you are lucky and it should be
> quite easy. Otherwise create a Kernel device driver that does the
> exposure of the LED to sysfs.

If it's already exposed in sysfs, you don't need to use native code.
You should be able to access the special file directly from java if
you have the permissions set right. If they are wrong, you can't
access it from the ndk either.

> Then in the /jni/native.cpp function do the proper write to the sysfs
> entry like this (note: this depends on how the led is exposed trough
> sysfs):
>
> ret = system("echo 1 > /sys/class/leds/red/brightness");

Chaining the echo command seems wasteful. Why not just write to the
special file yourself?

jon.schell

unread,
Nov 24, 2010, 2:10:27 PM11/24/10
to android-porting
Yes, I have the right coupling from the app to the native code. Yes,
I found out about using the sysfs entry. The problem is that
interface is too slow. I believe that I need to send an RPC call
directly to the hardware layer, and that interface is already defined,
but I can't figure out how to link to the function that does the RPC
call. Essentially, I believe that I need to create something in the
actual Android code (as that's where the RPC function exists) that I
can call from either a Java app or native code. This something would
make the RPC call and would essentially become an additional API for
any app that would be an alternative to sysfs, for the LED.

On Nov 23, 2:33 am, Mikkel Christensen <mikkel.christen...@ixonos.com>
wrote:
> Hello,
>
> I would use the SimpleJNI sample application [1] as a base reference.
> This does the right coupling from Android application to your lower
> level hardware interface.
>
> If the LED is already exposed in sysfs you are lucky and it should be
> quite easy. Otherwise create a Kernel device driver that does the
> exposure of the LED to sysfs.
>
> Then in the /jni/native.cpp function do the proper write to the sysfs
> entry like this (note: this depends on how the led is exposed trough
> sysfs):
>
> ret = system("echo 1 > /sys/class/leds/red/brightness");
>
> Make sure that you have given the right write permissions to the LED
> sysfs entry. This can be done in your init.rc file.
>
> Best regards,
>  Mikkel Christensen
>
> [1]http://android.git.kernel.org/?p=platform/development.git;a=tree;f=sa...
>
> On Nov 17, 12:10 am, "jon.schell" <jon.sch...@kyocera.com> wrote:
>
>
>
> > I am trying to create a simple app for testing that will toggle an LED
> > on the phone as needed.  I have the NDK set up and my c code compiles,
> > but I don't know how to link it to the actual hardware function that
> > would set the LED.  I'm using the actual source code for the hardware,
> > it's not in an exposed library.  Do I need to create a static library
> > for it to use?  Would it maybe be easier to add an android API for
> > this somehow rather than using the NDK?
>
> > For reference, this is Android 2.1 on a Qualcomm MSM7627.
>
> > Jonathan- Hide quoted text -
>
> - Show quoted text -

Chris Stratton

unread,
Nov 24, 2010, 5:10:57 PM11/24/10
to android-porting
Can you post the definition of the interface you want to talk to?

Do you have any actual evidence that using this other interface will
be faster?

(Often the way to speed things up when the interface itself is slow is
to hand off larger units of work at a time)

jon.schell

unread,
Nov 29, 2010, 1:09:19 PM11/29/10
to android-porting
I want to use:
pmic_secure_mpp_config_i_sink() which is defined in kernel/arch/arm/
mach-msm/pmic.c

It should be faster as there would be less overhead. If it's not fast
enough, then I would just move most of the code down to the AMSS side
and create my own RPC call that would just pass the data down and let
the AMSS side do the processing. I'm half-expecting to need to do
this, but I need to have all the linkages correct first anyways.

Jonathan
> > > - Show quoted text -- Hide quoted text -

A Curtis

unread,
Dec 29, 2010, 7:36:23 PM12/29/10
to android-porting
Chris,

Have you tried to access sysfs directly frdom Java? I have not been
able to get this to work.

Could you provide a code fragment?

TIA

A Curtis

unread,
Dec 30, 2010, 12:19:43 PM12/30/10
to android-porting
I got this working!

Basically I did not realize that SYSFS was more sophisticated than /
proc and actually supported file permissions.

This is basically what I did to access a GPIO from Java land.

echo "128" >/sys/class/gpio/export
echo "out" > /sys/devices/virtual/gpio/gpio128/direction
chmod 0666 /sys/devices/virtual/gpio/gpio128/value

Now you have GPIO #128 exported in sysfs, configured as an output and
accessible to your Java application.

Anything else that is accessible via sysfs can be handled in a similar
way.

Enjoy!

Dianne Hackborn

unread,
Dec 30, 2010, 2:05:57 PM12/30/10
to ajcur...@gmail.com, android-porting
This of course opens up security holes.




--
Dianne Hackborn
Android framework engineer
hac...@android.com

Note: please don't send private questions to me, as I don't have time to provide private support, and so won't reply to such e-mails.  All such questions should be posted on public forums, where I and others can see and answer them.

Chris Stratton

unread,
Jan 1, 2011, 10:13:04 PM1/1/11
to android-porting
On Dec 30 2010, 12:19 pm, A Curtis <ajcurti...@gmail.com> wrote:

> This is basically what I did to access a GPIO from Java land.
>
> echo "128" >/sys/class/gpio/export
> echo "out" > /sys/devices/virtual/gpio/gpio128/direction
> chmod 0666 /sys/devices/virtual/gpio/gpio128/value

Just FYI, that's not accessing sysfs directly from java, but
apparently issuing shell commands to do so. I can't think of any good
reason you shouldn't be able to accomplish this task using java file i/
o functions directly.

A Curtis

unread,
Jan 2, 2011, 2:07:15 PM1/2/11
to android-porting
The point was to proviide a simple short example of how to export GPIO
for access from Java. Of course the could have been done in Java but
it would be more then 3 lines of code.

A Curtis

unread,
Jan 2, 2011, 3:31:04 PM1/2/11
to android-porting
On second thought there is a difference,

The problem isn't just a sequence of instructions but having
sufficient permission to execute. The Java JVM does not run as root.
So,you need something that runs as root to change permissions to
enable Java access.

IMO a script maybe the best solution since it is easily integrated
into initrc. In fact, that is a large part of what that script does.

On Jan 1, 7:13 pm, Chris Stratton <cs07...@gmail.com> wrote:

Chris Stratton

unread,
Jan 3, 2011, 4:00:20 PM1/3/11
to android-porting
On Jan 2, 3:31 pm, A Curtis <ajcurti...@gmail.com> wrote:
> On second thought there is a difference,
>
> The problem isn't just a sequence of instructions but having
> sufficient permission to execute. The Java JVM does not run as root.

echo isn't setuid root either

> So,you need something that runs as root to change permissions to
> enable Java access.
>
> IMO a script maybe the best solution since it is easily integrated
> into initrc. In fact, that is a large part of what that script does.

Sure, but once you have changed the permissions, subsequent access
directly from java should be as possible as subsequent access by means
of the shell and echo. And a lot more efficient, as you don't have to
create a process or two each time.

I now notice your sequence of shell commands doesn't actually set the
value, so perhaps you already were planning to do the subsequent
access to the value directly from java.

Jerry Naidoo

unread,
Mar 10, 2020, 10:47:15 AM3/10/20
to android-porting
Hello Mikkel,

"Make sure that you have given the right write permissions to the LED
sysfs entry. This can be done in your init.rc file."

Can you elaborate on this a bit more please? I am trying to edit my init.rc file but there are so many sections e.g. on boot.

Where would I insert the commands?

I am assuming I have to insert "write sysfs/gpio/export xxx" or something similar.

Thanks
Jerry
Reply all
Reply to author
Forward
0 new messages