1. Trang chủ
  2. » Kỹ Thuật - Công Nghệ

Embedded FreeBSD Cookbook phần 7 pptx

25 212 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 25
Dung lượng 156,27 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

• Installing the JDK for FreeBSD • Defining JNI DIO features • Implementing native C data types in Java • Implementing the JNI native interface layer for the DIO interface library The JD

Trang 1

if (dio_set_int(s) != 0)

{

printf(“set int failed\n”);

} }

Listing 7-7

The int_handler function parses the user input looking for either the enable or disable string to determine the interrupt setting If the user input

is correct, dio_set_int is called to set the interrupt state

The pciint_handler Function

The pciint_handler function is used to set pci interrupts The pciint

command is entered using the following syntax,

s = enable;

}

else if ((strcmp(state, “disable”) == 0) || (strcmp(state,

Trang 2

is correct, dio_set_pciint is called to set the interrupt state

The setpolarity_handler Function

The setpolarity_handler function is used to set the interrupt polarity The set polarity command is entered using the following syntax:

Trang 3

The getpolarity_handler Function

The getpolarity_handler function is used to read the interrupt polarity The get polarity command is entered using the following syntax:

Trang 4

139 Chapter Seven

Remote Management

The getdirection_handler Function

The getdirection_handler function is used to read the direction of a dig­ital IO line The get direction command is entered using the following syntax:

The quit_handler Function

The quit_handler function is used to exit the shell The quit command

is entered using the following syntax

Trang 5

** since this is the program exit we must free the user

** buffer malloced in the main program

The quit command handler releases resources and exits the shell

The help_handler Function

The help_handler function is used to display command help The help

command is entered using the following syntax

The help handler iterates through the command table, displaying the help

string for each command

Trang 6

141 Chapter Seven

Remote Management

The DIOShell Utility

The DIOShell main handles all initialization and allocation of resources, then enters the command parsing loop until the quit command is called The utility initialization amounts to the allocation of a command buffer of BUFFER_MAX bytes Once the buffer is successfully allocated, the parser loop is entered

int main(int argc, char *argv)

{

uint8_t* userp = NULL;

if (strncmp(userp, cmdptr->command,

strlen(cmdptr->com-mand)) == 0) {

cmdptr->functionptr(userp, (char *)NULL);

break;

}

Trang 7

/* since quit handles cleanup and exit we’ll never get here */ exit(0);

The Makefile

BASE=DIOShell

DEST=/usr/local/bin

INCLUDES=-I / /inc

LIBRARIES=-L /usr/local/lib -ldioif

DIOShell: DIOShell.c Makefile

gcc $(INCLUDES) -o $(BASE) $(LIBRARIES) $(BASE).c

After the discussion of OpenSSH we developed a framework used to

implement a basic command line parser and engine that uses callbacks

to implement actions based on user input This framework is used to

implement the DIOShell, a digital IO specific shell for the DIO Appliance

Trang 8

8 143

Overview

The next phase of development in the DIO appliance project is to make the DIO interface Web-aware The first step toward this is to develop a Java Native Interface (JNI) for the DIO interface library The JNI is a programming interface, included in the Java Development Kit (JDK) for FreeBSD, for writing Java native methods for calling C/C++ routines

• Installing the JDK for FreeBSD

• Defining JNI DIO features

• Implementing native C data types in Java

• Implementing the JNI native interface layer for the DIO interface library

The JDK

Before we begin developing the JNI layer for the DIO interface library, our development environment must be configured for Java development Configuring the development environment consists of downloading a copy

of the Java Development Kit and setting a few environment variables

Getting the JDK

The first step in developing the JNI layer is obtaining a copy of the JDK The JDK is not a standard item in the FreeBSD distribution but is available in the FreeBSD ports To obtain the latest copy of the JDK, change the working directory to the the JDK ports directory, /usr/ports/java/jdk and execute the following commands:

Trang 9

The JDK_HOME Environment Variable

Many of the JDK tools, build environment, and run-time environment depend on the JDK_HOME environment variable to run correctly After building and installing the JDK, you’ll want to set your JDK_HOME environ­ment variable to the directory where the JDK was installed using the make install command On my development system, the JDK is installed in

/usr/local/jdk1.1.8 A quick look at my environment using the setenv command shows my JDK_HOME environment variable set

JDK_HOME=/usr/local/jdk1.1.8

A good place to set the JDK_HOME environment variable is in your startup shell scripts My account uses the csh; the following line is added to my

.cshrc script so it is set at logon

setenv JDK_HOME /usr/local/jdk1.1.8

The CLASSPATH Environment Variable

The CLASSPATH environment variable tells the Java Virtual Machine and other Java applications (for example, the Java tools located in the jdk1.1.8/bin

directory) in which directory to find the class libraries, including user-defined class libraries The DIO class libraries are kept in a separate directory in

/usr/local/dio, the directory used to keep the DIO software

# setenv CLASSPATH=/usr/local/dio/class

The CLASSPATH variable is set in the login script

Trang 10

145 Chapter Eight

JNI Layer

The LD_LIBRARY_PATH Environment Variable

LD_LIBRARY_PATH is an environment variable where the system’s library loader looks for shared libraries before looking in the system’s default shared-library directories The default shared-library search path is /lib, /usr/lib, /usr/local/lib

shared-# setenv LD_LIBRARY_PATH=/usr/local/dio/lib

As with the JDK_HOME and CLASSPATH environment variables, the

LD_LIBRARY_PATH variable is set in login startup scripts

Creating the JNI Layer

In this section we are going to develop a JNI layer to read and write digital

IO lines and read the configured direction of a line Since we’ve already developed a C interface to perform these tasks, an intermediate layer is devel­oped, the JNI, which provides the mechanism to call C code from Java code Before we turn the crank and begin emitting mass quantities of Java source code, let’s take a look at the procedure for developing our JNI interface First, we need to identify the features that are going to

be called from Java As previously mentioned, they are

read line, write line, and read direction These three

capabilities have been implemented by the DIO interface

library as dio_set_line, dio_get_line, and

dio_read_direction In addition to the functions,

we are going to implement the enums used by these C

functions Java doesn’t support enums as a native type,

so we’ll need to be a little creative

With the features defined, we’ll take the first step in

developing the JNI layer—defining a Java interface for

the DIO interface library functions The Java interface is

a Java class that uses native functions as the bridge to

call our C DIO interface library The Java functions call

the native functions, which, in turn, call the C functions Figure 8-1

Java

The JNI Layer

C Interface

The JNI Layer

After the Java class is defined, the Java compiler, javac, is run, which pro­duces the java class files Java class files are byte codes typically executed by the Java environment

Trang 11

The Java class files are used as

input to another tool in the

JDK, javah Javah produces a

native header file for functions

that were declared native in the

Java class The generated header

file is used for inclusion in the

C file that implements the

native functions

Finally, once the Java object is

completed, the native imple­

mentation is completed, and

the code is compiled into class

files and shared libraries and

located in the appropriate

directories pointed to by the

LD_LIBRARY_PATH and

CLASSPATH environment

variables, so it can be executed

Java Native Class

Figure 8-2 Structure of JNI Layer

Implementing C enums in Java

Even though Java has borrowed heavily from C++ syntax, some features of the C++ language are not implemented in Java One such feature is enums Since the dio_set_line, dio_get_line and dio_read_direction

functions all use enums, we are going to define corresponding types in Java There have been a few slightly different definitions of enums in the C language Initially they were just integers with no type checking In later definitions, they became proper types but with minimal type algebra For clarity, I’ll define

my intended use of enums, and we’ll proceed with the Java implementation

A C language enum is a list of objects grouped together into a fixed set Each

of the objects within the list have a defined value

In Java, we can create the grouping using a class with a private constructor

By making the constructor private, the creation of class objects is restricted Because we’ve made a class with a private constructor, creation of new objects is limited to that class We can now create the members of the enum within that class Let’s take a look at the DIOLineState class

Trang 12

147 Chapter Eight

JNI Layer

The DIOLineState Class

The C implementation of the line state is an enum with two states, clear and set Let’s take another look at the diolinestate_t, defined in dioif.h in Listing 8-1

typedef enum diolinestate_t

The diolinestate_t enum contains two members, clear with a value of

0 and set with a value of 1

The DIOLineState class in Figure 8-2 provides an implementation of two states scoped by DIOLineState The DIOLineState constructor is private, limiting the instantiation of DIOLineState object to class members In essence we’ve created a name scope, DIOLineState, similar to the C name scope diolinestate_t Now that we’re resolved the naming scope, we have the remaining task of defining the line states Both set and clear are defined as public static final members, making them publicly accessible fixed values of the DIOLineState class

public final class DIOLineState

Trang 13

Using the DIOLineState class defined in Figure 8-2, we’ve created two states scoped by the DIOLineState name that can be used by Java programs,

DIOLineState::set and DIOLineState::clear

The DIOLineNumber Class

As with the DIOLineState class, the DIOLineNumber class uses a private constructor to limit the scope of the member functions for the

DIOLineNumber class The DIOLineNumber class contains a static final method for each of the enum values in the C enum, effectively emulating the

C enum values Listing 8-3 contains a complete listing of the

{

return(number_);

};

Trang 14

The DIOLineDirection Class

The DIOLineDirection class implementation follows the same pattern as the DIOLineNumber and DIOLineState classes defined in the previous sections The class contains two public declarations that represent the values of the line state These values, lineout and linein, directly correspond to the C enum

dio_direction, defined in the DIO Interface library developed in Chapter

5 Listing 8-4 shows our implementation of the DIOLineDirections class

public final class DIOLineDirection

Trang 15

The implementation of the DIOLineDirection class contains a private con­structor limiting the values of the class, and a private variable, direction_, that contains the value of direction, which will be used to pass into the C implementation of the DIO interface

The Java Code

Now that some of our basic data types have been defined, it’s time to define the Java-to-C interface class Perhaps the most important task in defining the JNI class is to first define which features are included For simplicity’s sake,

we will define a Java class that provides the same capabilities provided by the diod daemon, a JNI layer that provides member functions to read, write, and determine the direction of the PCI-DIO24 digital IO lines The interfaces for each of these functions are contained in the DIO interface library; the JNI provides a way to call these functions from Java

Developing the JNI layer requires nothing more than the use of the native attribute keyword The native keyword allows the implementation of the member function to be deferred The actual implementation of the native member functions will occur in a C++ class, defined in a later step

The DIOIfJNI Class

Let’s take a look at the DIOIfJNI class The DIOIfJNI class is used to create a bridge between the Java world and the DIO interface library The first task is

to import the classes we used to implement the DIO interface enums in Java,

DIOLineNumber, DIOLineState, and DIOLineDirection

The Java implementation of each of our functions—read line, write line, and read direction—are similar; they call a native function that calls the DIO interface library and returns any data obtained from the DIO interface library back to the calling function Listing 8-5 contains a subset interface to the DIO interface library and the contents of the file DIOIfJNI.java

Trang 16

151 Chapter Eight

JNI Layer

public native int SetLineNative(int line, int value);

be used to the corresponding C function, GetLineNative, SetLineNative, and GetDirectionNative

Trang 17

Generate the Class Files

With the initial Java class defined, the class needs to be compiled using the Java compiler, javac The output of the Java compiler, the Java class file, is necessary for the next step, so we’ll be unable to proceed without compiling The Java class is compiled using the following command:

# javac DIOIfJNI.java

The output of this command will be the file DIOIfJNI.class The byte codes output from the javac compiler represent the implementation of the DIOIfJNI class When working with native methods, the bytecodes are also used to generate a header file for the native code to be developed We’ll learn more about this in the next step of developing the JNI layer

Generate the Header Files

The Java class file is used as input for the javah tool The javah tool uses the

java.class file and generates ANSI function prototypes for the defined native member functions It is important that the class files reside in a direc­tory contained in the CLASSPATH environment variable

# javah –jni DIOIfJNI

The –jni option in the example tells javah to generate a JNI function proto­type header The output of the javah tool is the file DIOIfJNI.H; Listing 8-6 contains the complete listing of this file DIOIfJNI.h is available for inclusion by the file containing the native source code implementation

* Class: DIOIfJNI

* Method: SetLineNative

* Signature: (II)I

Trang 18

153 Chapter Eight

JNI Layer

JNIEXPORT jint JNICALL Java_DIOIfJNI_SetLineNative

(JNIEnv *, jobject, jint, jint);

/*

* Class: DIOIfJNI

* Method: GetLineNative

* Signature: (I)I

JNIEXPORT jint JNICALL Java_DIOIfJNI_GetLineNative

(JNIEnv *, jobject, jint);

/*

* Class: DIOIfJNI

* Method: GetDirectionNative

* Signature: (I)I

JNIEXPORT jint JNICALL Java_DIOIfJNI_GetDirectionNative

(JNIEnv *, jobject, jint);

One other important note is that the generated header files include the file

jni.h This file contains all the necessary JNI definitions It is important to point the include directory path for the C compiler to the JDK header files We’ll look at this in more detail in the Makefile section of this chapter

The Native Code

Now it’s time to write the implementations of the native functions The native functions represent the bridge from Java to C Native functions are written using C++ and are called by the Java member functions in the DIOIfJNI object These functions, in turn, call directly through to the C implementation of the DIO interface library The primary object of the native functions is to provide the glue to massage Java data types onto C data

Ngày đăng: 08/08/2014, 01:21

TỪ KHÓA LIÊN QUAN