无网不进  
软硬件开发

http://blog.csdn.net/mwlwlm/article/details/52735700

嵌入式系统针对GPIO的开发,大部分都是采用c/c++进行开发,也有在树莓派上针对GPIO的java开发包,但必须要用树莓派平台,但友善之臂Friendarm的板子并不支持,只能自己想办法,在这里我们用Jni技术,直接调用友善之臂Friendarm的驱动包接口

1.首先下载友善之臂Friendarm的开发包Matrix,并编译

apt-get update && apt-get install git git clone https://github.com/friendlyarm/matrix.git

2 . 针对NanoPC T3修改common.h, common.c两个文件 
可能T3比较新,官方的开发包并没有包含对T3的初始化的支持,所以需要修改这两个文件 
在common.h中增加BOARD_NANOPI_T3 的宏定义 
这里写图片描述 
在common.c getBoardType函数中增加T3的识别 
这里写图片描述 
在gpio.c initPinGPIO函数中增加T3的初始化代码,T3和M3的一样,copy过来就可以 
这里写图片描述 
在pwm.c initPwmGPIO函数中增加T3的初始化代码,T3和M3的一样,copy过来就可以 
这里写图片描述

  1. 生成Java Jni类包装C语音库的函数,并实现c语言代码,并编译打包 
    java代码如下:
public class FriendarmLib {

    static
    {
        System.loadLibrary("friendarm");////调用的动态链接库文件名为libfriendarm.so;
    }

    ///////////common
    public native static int boardInit();

    public native static int initPinGPIO(int board);
    public native static int pintoGPIO(int pin);
    public native static int exportGPIOPin(int pin);
    public native static int unexportGPIOPin(int pin);

    // GPIO_LOW or GPIO_HIGH
    public native static int setGPIOValue(int pin, int value);
    public native static int getGPIOValue(int pin);

    // GPIO_IN or GPIO_OUT
    public native static int setGPIODirection(int pin, int direction);
    public native static int getGPIODirection(int pin);

    //PWM GPIO
    public native static int initPwmGPIO(int board);
    public native static int PWMPlay(int pin, int freq, int duty);
    public native static int PWMStop(int pin);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

在FriendarmLib.java目录下执行javac FriendarmLib.java在此目录下编译生成 FriendarmLib.class文件。 
在src目录下执行javah com.diego.jni.FriendarmLib在src目录下生成com_diego_jni_FriendarmLib.h文件;注意的是一定在src目录下,javah后面是包路径。

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_diego_jni_FriendarmLib */

#ifndef _Included_com_diego_jni_FriendarmLib
#define _Included_com_diego_jni_FriendarmLib
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_diego_jni_FriendarmLib
 * Method:    boardInit
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_com_diego_jni_FriendarmLib_boardInit
  (JNIEnv *, jclass);

/*
 * Class:     com_diego_jni_FriendarmLib
 * Method:    initPinGPIO
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_com_diego_jni_FriendarmLib_initPinGPIO
  (JNIEnv *, jclass, jint);

/*
 * Class:     com_diego_jni_FriendarmLib
 * Method:    pintoGPIO
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_com_diego_jni_FriendarmLib_pintoGPIO
  (JNIEnv *, jclass, jint);

/*
 * Class:     com_diego_jni_FriendarmLib
 * Method:    exportGPIOPin
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_com_diego_jni_FriendarmLib_exportGPIOPin
  (JNIEnv *, jclass, jint);

/*
 * Class:     com_diego_jni_FriendarmLib
 * Method:    unexportGPIOPin
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_com_diego_jni_FriendarmLib_unexportGPIOPin
  (JNIEnv *, jclass, jint);

/*
 * Class:     com_diego_jni_FriendarmLib
 * Method:    setGPIOValue
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_diego_jni_FriendarmLib_setGPIOValue
  (JNIEnv *, jclass, jint, jint);

/*
 * Class:     com_diego_jni_FriendarmLib
 * Method:    getGPIOValue
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_com_diego_jni_FriendarmLib_getGPIOValue
  (JNIEnv *, jclass, jint);

/*
 * Class:     com_diego_jni_FriendarmLib
 * Method:    setGPIODirection
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_diego_jni_FriendarmLib_setGPIODirection
  (JNIEnv *, jclass, jint, jint);

/*
 * Class:     com_diego_jni_FriendarmLib
 * Method:    getGPIODirection
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_com_diego_jni_FriendarmLib_getGPIODirection
  (JNIEnv *, jclass, jint);

/*
 * Class:     com_diego_jni_FriendarmLib
 * Method:    initPwmGPIO
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_com_diego_jni_FriendarmLib_initPwmGPIO
  (JNIEnv *, jclass, jint);

/*
 * Class:     com_diego_jni_FriendarmLib
 * Method:    PWMPlay
 * Signature: (III)I
 */
JNIEXPORT jint JNICALL Java_com_diego_jni_FriendarmLib_PWMPlay
  (JNIEnv *, jclass, jint, jint, jint);

/*
 * Class:     com_diego_jni_FriendarmLib
 * Method:    PWMStop
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_com_diego_jni_FriendarmLib_PWMStop
  (JNIEnv *, jclass, jint);

#ifdef __cplusplus
}
#endif
#endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109

com_diego_jni_FriendarmLib.h文件是项目中,供C语言调用的头文件,只需要实现此头文件中定义的接口函数,就可以了。com_diego_jni_FriendarmLib.c文件的代码如下:

/*
 * com_diego_jni_FriendarmLib.c
 *
 *  Created on: Oct 3, 2016
 *      Author: william
 */
#include <stdio.h>
#include "com_diego_jni_FriendarmLib.h"
#include "common.h"
#include "libfahw-gpio.h"
#include "libfahw-filectl.h"
#include "libfahw-pwm.h"

/*
 * Class:     com_diego_jni_FriendarmLib
 * Method:    boardInit
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_com_diego_jni_FriendarmLib_boardInit
  (JNIEnv * env, jclass jc){
    //printf("******this is in c file\n");
    return (jint)boardInit();
}

/*
 * Class:     com_diego_jni_FriendarmLib
 * Method:    initPinGPIO
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_com_diego_jni_FriendarmLib_initPinGPIO
  (JNIEnv * env, jclass jc, jint board){
    return (jint)initPinGPIO(board);
}

/*
 * Class:     com_diego_jni_FriendarmLib
 * Method:    pintoGPIO
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_com_diego_jni_FriendarmLib_pintoGPIO
  (JNIEnv * env, jclass jc, jint pin){
    return (jint)pintoGPIO(pin);
}

/*
 * Class:     com_diego_jni_FriendarmLib
 * Method:    exportGPIOPin
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_com_diego_jni_FriendarmLib_exportGPIOPin
  (JNIEnv * env, jclass jc, jint pin){
    return (jint)exportGPIOPin(pin);
}

/*
 * Class:     com_diego_jni_FriendarmLib
 * Method:    unexportGPIOPin
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_com_diego_jni_FriendarmLib_unexportGPIOPin
  (JNIEnv * env, jclass jc, jint pin){
    return (jint)unexportGPIOPin(pin);
}

/*
 * Class:     com_diego_jni_FriendarmLib
 * Method:    setGPIOValue
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_diego_jni_FriendarmLib_setGPIOValue
  (JNIEnv * env, jclass jc, jint pin, jint value){
    return (jint)setGPIOValue(pin,value);
}

/*
 * Class:     com_diego_jni_FriendarmLib
 * Method:    getGPIOValue
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_com_diego_jni_FriendarmLib_getGPIOValue
  (JNIEnv * env, jclass jc, jint pin){
    return (jint)getGPIOValue(pin);
}

/*
 * Class:     com_diego_jni_FriendarmLib
 * Method:    setGPIODirection
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_diego_jni_FriendarmLib_setGPIODirection
  (JNIEnv * env, jclass jc, jint pin, jint direction){
    return (jint)setGPIODirection(pin,direction);
}

/*
 * Class:     com_diego_jni_FriendarmLib
 * Method:    getGPIODirection
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_com_diego_jni_FriendarmLib_getGPIODirection
  (JNIEnv * env, jclass jc, jint pin){
    return (jint)getGPIODirection(pin);
}

/*
 * Class:     com_diego_jni_FriendarmLib
 * Method:    initPwmGPIO
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_com_diego_jni_FriendarmLib_initPwmGPIO
  (JNIEnv * env, jclass jc, jint board){
    return (jint)initPwmGPIO(board);
}

/*
 * Class:     com_diego_jni_FriendarmLib
 * Method:    PWMPlay
 * Signature: (III)I
 */
JNIEXPORT jint JNICALL Java_com_diego_jni_FriendarmLib_PWMPlay
  (JNIEnv * env, jclass jc, jint pin, jint freq, jint duty){
    return (jint)PWMPlay(pin,freq,duty);
}

/*
 * Class:     com_diego_jni_FriendarmLib
 * Method:    PWMStop
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_com_diego_jni_FriendarmLib_PWMStop
  (JNIEnv * env, jclass jc, jint pin){
    return (jint)PWMStop(pin);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134

将com_diego_jni_FriendarmLib.h上传到友善之臂Friendarm T3主板~/matrix/lib/includes目录。 
将com_diego_jni_FriendarmLib.c上传到友善之臂Friendarm T3主板~/matrix/lib目录。 
修改~/matrix/lib目录下Makefile文件的编译段,增加jvm相关头文件的包含目录,修改后的代码如下: 
这里写图片描述
接下来执行在~/matrix/lib目录下执行make命令,在/matrix/lib/.obj目录下会生成所有的.o文件, 注意.obj目录是隐藏目录,在lib目录下执行cd .obj目录即可进入此目录,执行ls目录可以看到所有生成的.o 文件 
这里写图片描述
打包动态链接.so文件,执行如下命令: 
gcc -Wall -rdynamic -shared -o libfriendarm.so com_diego_jni_FriendarmLib.o common.o gpio.o pwm.o filectl.o 
注意这里需要用的目标文件.o 文件全部打包进去,否则调用会出错。执行完成后会生成libfriendarm.so文件 
这里写图片描述
执行mv libfriendarm.so /usr/lib命令将libfriendarm.so文件移动到java的搜索目录下。 
接下来就可以在java中调用官方的c语言包,调用的示例代码如下:

try{
            int i=FriendarmLib.boardInit();
            System.out.println("****** the result for gpio is :"+i);
        }catch(Exception e){
            e.printStackTrace();
            System.exit(0);
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

执行后输出入下: 
这里写图片描述 
输出信息中T3的主板是NANOPI3和M3是一样的,官方应该及时更新库文件。

4.在本例中只用到了GPIO,和PWM所以只打包了相应的接口函数,可以按照此方法打包其他需要的接口,在Java中调用;如果方便,还是使用树莓派的比较方便,有开源项目pi4j 项目专门针对树莓派的硬件接口提供Java调用接口。友善之臂的板子性能不错,但需要加强针对生态的建设,另外要吐槽的是,虽然板子集成了蓝牙,但蓝牙不能用,官方也不解决。

版权声明:本文为博主原创文章,未经博主允许不得转载。
posted on 2018-01-10 18:22  无网不进  阅读(236)  评论(0编辑  收藏  举报