Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 25 trang
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
Nội dung
136 Embedded FreeBSD Cookbook } else { printf(“illegal state\n”); return; } 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 enter ed using the following syntax, > pciint value wher e value is either the string enable or disable. void pciint_handler(char* args, uint8_t* p) { char state[32]; DIOintstate_t s; sscanf(args, “%*s %s”, state); if ((strcmp(state, “enable”) == 0) || (strcmp(state, “ENABLE”) == 0)) { s = enable; } else if ((strcmp(state, “disable”) == 0) || (strcmp(state, “DISABLE”) == 0)) { s = disable; 137 Chapter Seven Remote Management } else { printf(“illegal state\n”); return; } if (dio_set_pciint(s) != 0) { printf(“set pciint failed\n”); } } Listing 7-8 The pciint_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_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: > setpol value wher e value is either high or low . void setpolarity_handler(char* args, uint8_t* p) { char state[32]; DIOpolarity_t polarity; sscanf(args, “%*s %s”, state); if ((strcmp(state, “hi”) == 0) || (strcmp(state, “HI”)) == 0) { polarity = activehi; } else if ((strcmp(state, “lo”) == 0) || (strcmp(state, “LO”)) == 0) { polarity = activelo; } 138 Embedded FreeBSD Cookbook else { printf(“invalid polarity\n”); return; } if (dio_set_polarity(polarity) != 0) { printf(“error writing polarity\n”); } } Listing 7-9 The int_handler function parses the user input looking for either the high or low string to determine the interrupt polarity setting. If the user input is correct, dio_set_polarity is called to set the interrupt polarity . The getpolarity_handler Function The getpolarity_handler function is used to r ead the interrupt polarity. The get polarity command is entered using the following syntax: > getpol Getpol takes “not” arguments. void getpolarity_handler(char* args, uint8_t* p) { DIOpolarity_t polarity; if (dio_get_polarity(&polarity) == 0) { printf(“pol = %d\n”, polarity); } else { printf(“error reading polarity\n”); } } Listing 7-10 The getpolarity_handler calls the dio_get_polarity function; if the call is successful, the interrupt polarity is displayed by the DIO shell. 139 Chapter Seven Remote Management The getdirection_handler Function The getdirection_handler function is used to r ead the direction of a dig- ital IO line. The get direction command is entered using the following syntax: > getdir line where line is a value between 0 and 23. void getdirection_handler(char* args, uint8_t* p) { DIOline_t line; DIOdirection_t direction; sscanf(args, “%*s %d”, &line); /* check the parameters */ if ((line < line0) || (line > line23)) { printf(“illegal line number\n”); return; } if (dio_get_direction(line, &direction) == 0) { printf(“line %d %s\n”, direction, (direction == linein ? “in” : “out”)); } else { printf(“error reading direction\n”); } } Listing 7-11 The getdirection_handler function parses the user input looking for the line number. After determining the line, dio_get_direction is called, and the digital IO line direction is displayed, either in or out, depending on the port’s configured direction. The quit_handler Function The quit_handler function is used to exit the shell. The quit command is entered using the following syntax. 140 Embedded FreeBSD Cookbook > quit Quit takes no ar guments. void quit_handler(char* args, uint8_t* p) { /* ** since this is the program exit we must free the user ** buffer malloced in the main program */ free(args); exit(0); } Listing 7-12 The quit command handler r eleases resources and exits the shell. The help_handler Function The help_handler function is used to display command help. The help command is enter ed using the following syntax. > help Help takes no ar guments. void help_handler(char* args, uint8_t* p) { command_t* cmdptr; cmdptr = &commands[0]; while (cmdptr->command != NULL) { printf(“\t%s %s\n”, cmdptr->command, cmdptr->helpstring); cmdptr++; } } Listing 7-13 The help handler iterates thr ough the command table, displaying the help string for each command. 141 Chapter Seven Remote Management The DIOShell Utility The DIOShell main handles all initialization and allocation of r esources, 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; userp = (uint8_t *)malloc(BUFFER_MAX); if (userp == NULL) { printf(“%s: unable to allocate user buffer\n”); exit(-1); } while (1) { command_t* cmdptr; printf(“\n> “); gets(userp); /* parse the users command */ cmdptr = &commands[0]; while (cmdptr->command != NULL) { if (strncmp(userp, cmdptr->command, strlen(cmdptr->com- mand)) == 0) { cmdptr->functionptr(userp, (char *)NULL); break; } cmdptr++; } if (cmdptr->command == NULL) { printf(“ invalid command\n”); } } 142 Embedded FreeBSD Cookbook /* since quit handles cleanup and exit we ’ll never get here */ exit(0); } Listing 7-14 The command parsing loop consists of displaying the > pr ompt, reading the user input, then parsing the command. The command parsing is performed by matching the first string entered by the user to the command element of each entry in the command table. If there is a match, the command handler function is called. All additional parsing and actions are handled by each individual command handler. 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 cp $(BASE) $(DEST) clean: rm -f $(BASE) rm -f $(DEST)/$(BASE) rm -f *.o Summar y This chapter cover ed the basics of installing, building, and configuring OpenSSH, the secure shell, using FreeBSD. The secure shell provides the basic login allowing secure access to the DIO appliance. 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. 8 143 CHAPTER EIGHT JNI Layer Over view The next phase of development in the DIO appliance pr oject 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 Befor e 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: 144 Embedded FreeBSD Cookbook # cd /usr/ports/java/jdk # make # make install # make clean These instructions can be used to update, build and install any of the FreeBSD port packages. The make command r etrieves and builds the latest version of the specific port. The next step, make install, installs the binaries on your system. After the port is updated, built, and installed, it’s a good idea to clean the binaries and temporary build files so disk space isn’t exhausted. The make clean instruction handles the details of cleaning up the build files. The JDK_HOME Environment V ariable Many of the JDK tools, build envir onment, and run-time environment depend on the JDK_HOME envir onment variable to run correctly. After building and installing the JDK, you’ll want to set your JDK_HOME envir on- 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 envir onment using the setenv command shows my JDK_HOME envir onment variable set. JDK_HOME=/usr/local/jdk1.1.8 A good place to set the JDK_HOME envir onment 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 CLASSP ATH Environment Variable The CLASSP ATH environment variable tells the Java Virtual Machine and other Java applications (for example, the Java tools located in the jdk1.1.8/bin dir ectory) 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 dir ectory used to keep the DIO software. # setenv CLASSPATH=/usr/local/dio/class The CLASSP ATH variable is set in the login script. 145 Chapter Eight JNI Layer The LD_LIBRARY_PATH Environment Variable LD_LIBRAR Y_PATH is an environment variable where the system’s shared- 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. # setenv LD_LIBRARY_PATH=/usr/local/dio/lib As with the JDK_HOME and CLASSP ATH environment variables, the LD_LIBRARY_PATH variable is set in login startup scripts. Creating the JNI Layer In this section we ar e 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. [...]... using the standard ports installation procedure Let’s review those steps now 158 Embedded FreeBSD Cookbook Installing Tomcat The version of Tomcat installed on my system is Tomcat 3.2.3 # # # # cd /usr/ports/www/jakarta-tomcat make make install make clean These instructions may be used to update, build, and install any of the FreeBSD port packages The make command retrieves and builds the latest version... DIOLineState(0); public static final DIOLineState set = new DIOLineState(1); public int State() { return(state_); }; private DIOLineState(int state) { state_ = state; }; private int state_; } Listing 8-2 148 Embedded FreeBSD Cookbook 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... line7 line8 line9 line10 line11 line12 line13 line14 line15 line16 line 17 line18 line19 line20 line21 line22 line23 = = = = = = = = = = = = = = = = = = = = = = = = new new new new new new new new new new new new new new new new new new new new new new new new DIOLineNumber(0); DIOLineNumber(1); DIOLineNumber(2); DIOLineNumber(3); DIOLineNumber(4); DIOLineNumber(5); DIOLineNumber(6); DIOLineNumber (7) ;... linein = new DIOLineDirection(1); public int Direction() { return(direction_); }; private DIOLineDirection(int direction) { direction_ = direction; }; private int direction_; } Listing 8-4 150 Embedded FreeBSD Cookbook 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,... GetDirection For each of the Java functions there is a corresponding native function that will be used to the corresponding C function, GetLineNative, SetLineNative, and GetDirectionNative 152 Embedded FreeBSD Cookbook 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... 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 154 Embedded FreeBSD Cookbook types, pass the appropriate data between the layers, and provide access to the C library from Java The Java_DIOIfJNI_SetLineNative Function The Java_DIOIfJNI_SetLineNative function is... I$(JDK_HOME)/include /freebsd all: libdioifjni.so DIOIfJNI.h: DIOIfJNI.java DIOLineNumber.java DIOLineState.java DIOLineDirection.java javac DIOIfJNI.java javah -jni DIOIfJNI libdioifjni.so: DIOIfJNI.h DIOIfJNI.cpp 156 Embedded FreeBSD Cookbook g++ $(CFLAGS) -o libdioifjni.so DIOIfJNI.cpp -L/usr/local/lib -ldioif cp libdioifjni.so /usr/local/lib clean: rm -f libdioifjni.so rm -f DIOIfJNI.h Listing 8-10 In addition to the typical...146 Embedded FreeBSD Cookbook 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... the most used scripts are startup.sh and shutdown.sh These scripts are used to start and stop Tomcat Starting Tomcat is performed by the following command: # cd $TOMCAT_HOME/bin # startup.sh 160 Embedded FreeBSD Cookbook Stopping Tomcat is performed by the following command: # cd $TOMCAT_HOME/bin # shutdown.sh doc The doc directory contains Tomcat documentation in html format, so you can point your browser... include file directories The two directories necessary are include and include /freebsd In the JNI layer Makefile, these directories were added to the CFLAGS variable Listing 8-10 shows the complete Makefile for developing the JNI interface for the DIO appliance CFLAGS= -fpic -shared -I /inc -I$(JDK_HOME)/include I$(JDK_HOME)/include /freebsd all: libdioifjni.so DIOIfJNI.h: DIOIfJNI.java DIOLineNumber.java . 136 Embedded FreeBSD Cookbook } else { printf(“illegal state
”); return; } if (dio_set_int(s) != 0) { printf(“set int failed
”); } } Listing 7- 7 The int_handler. activelo; } 138 Embedded FreeBSD Cookbook else { printf(“invalid polarity
”); return; } if (dio_set_polarity(polarity) != 0) { printf(“error writing polarity
”); } } Listing 7- 9 The int_handler. printf(“ invalid command
”); } } 142 Embedded FreeBSD Cookbook /* since quit handles cleanup and exit we ’ll never get here */ exit(0); } Listing 7- 14 The command parsing loop consists