index previous next

pre test

To realize CGI system , I have had some tests.

The following is my test procedure in this case.
  • Access device files
  • Access HTML file through network
  • Get 'Environment Variables'
  • Get information from HTML FORM
  • Set permission to access HTML file
  • Set permission to run CGI
  • Check sequence flow

Access device files

'Armadillo' base ARM7 has a parallel interface port : GPIO. *GPIO : General Purpose Inputs and Outputs If you want to use this GPIO , you must set a control word to DDR. *DDR : Data Direction Register As DDR is a byte register, you shall set bit pattern. 1 : output , 0 : input In this case this DDR is assigned to device file /dev/pbddr. Apply system call 'open' to get file discripter. Watch the following procedure code. int fd_ddr ; fd_ddr = open( "/dev/pbddr" , O_WRONLY ) ; If you can not get file discripter with this system call, add error handling. if ( fd_ddr < 0 ) { fprintf( stderr , "DDR open error !\n" ) ; exit(1); } I have set each bit as followings.
  • GPIO_0:(output)open
  • GPIO_1:(output)close
  • GPIO_2:(output)light
  • GPIO_3:(output)pump
  • GPIO_4:(input )door
  • GPIO_5:(input )detector
  • GPIO_6:(input )
  • GPIO_7:(input )
Write the souce code: upper nibble -> inputs , lower nibble => outputs. typedef unsigned char UBYTE ; UBYTE tmp ; tmp = 0x0f ; /* in in in in out out out out -> 00001111 */ write( fd_ddr , &tmp , sizeof( UBYTE ) ) ; The above code can only set port directions. To get and put logical value to GPIO, you shall set a word to DR. *DR : Data Register In this case this DR is assigned to device file /dev/pbdr. Apply system call 'open' to get file discripter. To activate an actuator , put '1'. In initial state you must not activate them. Watch the following procedure code. int fd_dr ; fd_dr = open("/dev/pbdr", O_RDWR ); if ( fd_dr < 0 ) { fprintf( stderr , "DR open error !\n" ) ; exit(1); } tmp = 0x00 ; /* 00000000 */ write( fd_dr , &tmp , sizeof( UBYTE ) ) ; After define some functions, write test code to control actuators. With test tools you can check your hardware. I have an example code to activate hardware. (This code is called 'Knight rider' among Japanese engineers.) Please watch the next sequence.
  1. ***o
  2. **o*
  3. *o**
  4. o***
  5. *o**
  6. **o*
  7. return first state
@* turn off / o turn on In this case I recommend to use state machine. State machine sequence is written by 'switch' statement in C. UBYTE pat[6] = {1,2,4,8,4,2} ; UBYTE result ; int state ; state = 0 ; result = pat[state] ; while ( 1 ) { write( fd_dr , &result , sizeof( UBYTE ) ); switch ( state ) { case 0 : state = 1 ; break ; case 1 : state = 2 ; break ; case 2 : state = 3 ; break ; case 3 : state = 4 ; break ; case 4 : state = 5 ; break ; case 5 : state = 0 ; break ; default : state = 0 ; break ; } sleep(1); result = pat[state] ; } To indicate given value I have maken next code. void binary_display(UBYTE x) { int i ; for ( i = 7 ; i > 3 ; i-- ) { putchar('0'+((x >> i) & 1)); } putchar('\n'); } After define this function, make endless test loop. while ( 1 ) { write( fd_dr , &result , sizeof( UBYTE ) ); switch ( state ) { case 0 : state = 1 ; break ; case 1 : state = 2 ; break ; case 2 : state = 3 ; break ; case 3 : state = 4 ; break ; case 4 : state = 5 ; break ; case 5 : state = 0 ; break ; default : state = 0 ; break ; } result = pat[state] ; read( fd_dr , &result , sizeof( UBYTE ) ); binary_display(result); sleep(1); } Concatnate some statements and functions. #include <stdio.h> #include <unistd.h> typedef unsigned char UBYTE ; int fd_ddr,fd_dr ; void initialize(void) { UBYTE tmp ; fd_ddr = open("/dev/pbddr", O_WRONLY ); if ( fd_ddr < 0 ) { fprintf( stderr , "DDR open error !\n" ) ; exit(1); } tmp = 0x0f ; /* in in in in out out out out -> 00001111 */ write( fd_ddr , &tmp , sizeof( UBYTE ) ) ; fd_dr = open("/dev/pbdr", O_RDWR ); if ( fd_dr < 0 ) { fprintf( stderr , "DR open error !\n" ) ; exit(1); } tmp = 0x00 ; /* 00000000 */ write( fd_dr , &tmp , sizeof( UBYTE ) ) ; } void binary_display(UBYTE x) { int i ; for ( i = 7 ; i > 3 ; i-- ) { putchar('0'+((x >> i) & 1)); } putchar('\n'); } int main(void) { UBYTE pat[6] = {1,2,4,8,4,2} ; UBYTE result ; int state ; initialize() ; state = 0 ; result = pat[state] ; while ( 1 ) { write( fd_dr , &result , sizeof( UBYTE ) ); switch ( state ) { case 0 : state = 1 ; break ; case 1 : state = 2 ; break ; case 2 : state = 3 ; break ; case 3 : state = 4 ; break ; case 4 : state = 5 ; break ; case 5 : state = 0 ; break ; default : state = 0 ; break ; } result = pat[state] ; read( fd_dr , &result , sizeof( UBYTE ) ); binary_display(result); sleep(1); } return 0 ; } Name this source code 'htest.c'. I recommend to make shell script to reduce typing. #!/bin/bash # This shell script is 'armgcc'. # Usage => ./armgcc file_name arm-linux-gcc -I/usr/arm-linux/include -L/usr/arm-linux/lib -o $1 $1.c To use this script, type the following. $ ./armgcc htest{enter} After compiling and linking (if happened no errors), transfer load module to 'Armadillo'. In UNIX operating system you can transfer it with FTP protocol. Change permission of this load module in 'Armadillo' console and run it. # chmod +x htest{enter} # ./htest{enter} You can check the following items with this load module.
  • device file '/dev/pbddr' operating
  • device file '/dev/pbdr' operating
  • soldering mistakes

HTML script

HTTP server daemon 'thttpd' be always running on 'Armadillo'. In default case target HTML file must be in the following directory. /home/www-data To begin with apply Web Browser to get the next HTML script 'hello.htm'. <html> <title>Hello</title> <body> <h3> <blockquote> <pre> <font color="#0000ff"> <H1>Hello , JICA partitipants !</H1></font> My name is <font color="#ff0000">Armadillo</font>. I am a small Linux box. Now I send you this message from JICA training room. Please enjoy this time. You can get some drinks and cakes. </pre> </blockquote> </h3> </body> After make the above HTML file and transfer it with FTP. Maybe 'Armadillo' copy it the directory /home/ftp/pub. After confirmation transfer it to given directory and change permission. # cp /home/ftp/pub/hello.htm /home/www-data/hello.htm{enter} # cd /home/www-data{enter} # chmod 766 hello.htm{enter} Type IP address of 'Armadillo' and follow HTML file name. http://192.168.0.101/www-data/hello.htm When Web browser show you the context of HTML file, you can find to have success. *Assumed : IP address of 'Armadillo' = 192.168.0.101

Get environment variables

You can use Environment Variables to get some informations on UNIX. In order to get informations through the network, write CGI code. As environment variables are formatted 'variable name=value' , get the value with system call 'getenv' line by line. After informations are gotten ,return them to Web brower to confirm them. I have decided to show the context of HTML file with next format.
  1. send string 'Content-type: text/html' with carriage return to stdout
  2. send empty string with carriage return to stdout
  3. send the context of HTML file to stdout
Run CGI code (printenv.cgi) , then you can get the following list. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ PATH=/usr/local/bin:/usr/ucb:/bin:/usr/bin SERVER_SOFTWARE=thttpd/2.20c 21nov01 SERVER_NAME=armadillo GATEWAY_INTERFACE=CGI/1.1 SERVER_PROTOCOL=HTTP/1.1 SERVER_PORT=80 REQUEST_METHOD=POST SCRIPT_NAME=/cgi-bin/printenv.cgi REMOTE_ADDR=192.168.0.57 HTTP_REFERER=http://192.168.0.62/btst.htm HTTP_USER_AGENT=Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1) HTTP_ACCEPT=image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */* HTTP_ACCEPT_ENCODING=gzip, deflate CONTENT_TYPE=application/x-www-form-urlencoded HTTP_HOST=192.168.0.62 CONTENT_LENGTH=13 AUTH_TYPE=Basic CGI_PATTERN=cgi-bin/*|*.cgi b0=1&b3=1 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ As 'Armadillo' must set CGI program directory /home/www-data/cgi-bin, save CGI load module 'printenv.cgi' to this directory. In order to transfer informations to CGI program, you must select 'POST' or 'GET' method. After selection you must write it in HTML file. Lately I shall explain about this concept. Realize this CGI program applied the next C source code. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> void crlf(void) { fprintf( stdout , "\r\n"); } void out_header(void) { fprintf( stdout , "Content-type: text/html");crlf(); crlf(); } void start_html(char *x) { fprintf( stdout , "<html>");crlf(); fprintf( stdout , "<title>%s</title>",x);crlf(); fprintf( stdout , "<body>");crlf(); fprintf( stdout , "<blockquote>");crlf(); fprintf( stdout , "<pre>");crlf(); } void end_html(void) { fprintf( stdout , "</pre>");crlf(); fprintf( stdout , "</blockquote>");crlf(); fprintf( stdout , "</body>");crlf(); fprintf( stdout , "</html>");crlf(); } int main(void) { extern char **environ ; char **pp ; char *pcCL = getenv("CONTENT_LENGTH"); char *pcQS = NULL ; out_header(); start_html("test"); for ( pp = environ ; *pp ; pp++ ) { fprintf( stdout , "%s<br>\r\n",*pp); } if ( pcCL != NULL ) { int nCL = 0 ; sscanf( pcCL , "%d" , &nCL ); if ( nCL > 0 ) { pcQS = malloc( nCL + 1 ); if ( pcQS == NULL ) { fprintf( stderr , "No memory <%d> \n",nCL ); exit(1); } fread( pcQS , 1 , nCL , stdin ); pcQS[nCL] = 0 ; } } if ( pcQS == NULL ) pcQS = "" ; fprintf( stdout , "%s\r\n",pcQS); end_html(); return 0; } +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Web brower will send informations through the following HTML codes. <html> <head>Test</head> <title>Automatic Door</title> <body bgcolor="#f0fff0"> <form action="/cgi-bin/printenv.cgi" method="post"> <input type="checkbox" namd="led3" value="1" checked>LED3 <input type="checkbox" namd="led4" value="1" >LED4 <input type="checkbox" namd="led5" value="1" checked>LED5 <input type="checkbox" namd="led6" value="1" >LED6 <p> <input type="submit" value="SUBMIT!"> </form> </body> </html>

Get informations from FORM

I have written CGI program with C. As C compiler is prepared on any UNIX , you can test your code easily. In automatic door system you can control one actuator with electric signal 'H' or 'L'. I have designed to send 4 bit pattern to actuators in order to control them. Each bit '1' is activate , '0' is not activate an actuator. I have designed that user will set or reset control bit connected to actuator. And send them to CGI program from HTML FORM. To send informations from HTML FORM , select 'POST' or 'GET' method. As 'POST' method can transfer many informations than 'GET' one, I recommend to send informations with 'POST' method. Write method="post" with HTML form tag to send informations formatted 'POST' method. Apply 'check box' to show state is active or inactive. Current state will be indicated with 'checked' command. I have maken the following HTML script. <html> <title>Automatic Door</title> <h3> <body> <blockquote> <FONT COLOR="#0000FF"><h2>CONTROL</h2></FONT> <form action="cgi-bin/padoor.cgi" method="post"> <ul> <li>open <input type="radio" name="b0" value="0" checked>OFF <input type="radio" name="b0" value="1">ON <li>close <input type="radio" name="b1" value="0" checked>OFF <input type="radio" name="b1" value="1">ON <li>light <input type="radio" name="b2" value="0" checked>OFF <input type="radio" name="b2" value="1">ON <li>pump <input type="radio" name="b3" value="0" checked>OFF <input type="radio" name="b3" value="1">ON </ul> <input type=submit value="update"> </form> </blockquote> </body> </h3> </html> CGI program will get the next string through HTML script. b0=0&b1=0&b2=0&b3=0 And CGI program gets them from 'stdin'. After getting this string, separate each bit states.

Permission

You can create and edit HTML script easily. After complete HTML script typing, copy it to target directory. And change its permisson. As UNIX files have own their permissons, you must change the permisson. If you have fogotton permisson changing, Web Browser can not access HTML script. Type the following. (Assumed HTML file is 'hello.htm') # cp /home/ftp/pub/hello.htm /home/www-data/hello.htm{enter} # cd /home/www-data{enter} # chmod 766 hello.htm{enter}

Permission to enable CGI

You can compile and link C source code and get CGI load module. To activate this CGI program you must change its permisson. Type the following.(Assumed CGI program is 'printenv.cgi') # cp /home/ftp/pub/printenv.cgi /home/www-data/cgi-bin/printenv.cgi{enter} # cd /home/www-data/cgi-bin{enter} # chmod +x printenv.cgi{enter}

Check whole flow

Check and test the sequence on your desk without a computer.
  1. Get strings length from 'Environment Variable'
  2. Get command strings from 'stdin'
  3. Analyze command strings
  4. Put control signals to actuators according to information
  5. Get sensor states
  6. Generate HTML script
  7. Send HTML script to network
Since CGI program is a server side application, complete its process and exit as soon as possible. Long processing is harmful to another processes. You must make the sequence to run process without looping.

index previous next

inserted by FC2 system