Presentation is loading. Please wait.

Presentation is loading. Please wait.

 Wind River Systems, Inc. 1997 Appendix - D RPC.

Similar presentations


Presentation on theme: " Wind River Systems, Inc. 1997 Appendix - D RPC."— Presentation transcript:

1  Wind River Systems, Inc. 1997 Appendix - D RPC

2 D-2 NETWORK COMPONENTS

3 D-3 RPC / XDR Overview A distributed application may be molded as a set of local and remote procedure calls. RPC (Remote Procedure Call) provides a standard way to invoke procedures on a remote machine. XDR (eXternal Data Representation) provides system independent data representation used for: Parameters passed to remote procedures. Data returned from remote procedures. Documentation and source code can be found in wind/target/unsupported/rpc4.0.

4 D-4 RPC Client - Server Model

5 D-5 An RPC Code Generator User creates specification file (e.g.spec.x) describing the remote procedures. RPC code generator, rpcgen, creates: spec_clnt.cclient stub. spec_svc.cserver stub. spec_xdr.cxdr routines for packing/unpacking data structures. Not created if all parameters / return values are standard data types. spec.hfor inclusion by client and server.

6 D-6 Using rpcgen

7 D-7 Example Specification File /* spec.x */ program MY_PROG { version MY_VERS { long MY_GET_NUM (void) = 1; /* function 1 */ string MY_GET_STR (long) = 2; /* function 2 */ } = 1; /* version 1 */ } = 0x31234567; /* program number */

8 D-8 VxWorks Specifics Each VxWorks task accessing RPC calls must first initialize access. STATUS rpcTaskInit( ) Code generated by rpcgn uses static variables: Not reentrant. Can have at most one task calling a given remote procedure without conflict. RPC objects (such as CLIENTs or SVCXPRTs) may not be shared between tasks. Delete these when task exits. rpcgen generates non-ANSI code. Compile with the - traditional flag when using an ANSI compiler.

9 D-9 Server Stub If the server is to run on VxWorks, the stub generated by rpcgen must be modified. The entry point should be changed from main( ) to something more meaningful (e.g., fooServer( )). Add a call to rpcTaskInit( ) near the beginning of the main entry point:

10 D-10 Server Program Must write server program implementing the remote procedures. Include the header file generated by rpcgen. Write the server routines. rpcgen requires that the server routines take slightly different syntax than listed in specification file: Specified names converted to lower case and _versionNumber is appended. Extra level of indirection. In our example, we must write: long *my_get_num_1 (void) char **my_get_str_1 (long *)

11 D-11 Client Program The client program must: Include the header file generated by rpcgen. Call rpcTaskInit( ) (if running on VxWorks). To invoke remote procedures, must first establish a handle to the server: CLIENT * clnt_create (host, progNum, versNum, protocol) hostMachine on which server runs. progNumFrom specification file. versNumFrom specification file. protocol“udp” or “tcp”. Returns client handle on success, otherwise NULL.

12 D-12 Client Example 1CLIENT * cl; 2long *pNum; 3/* Initialize a VxWorks task’s access to RPC. 4 * Not called for UNIX tasks */ 5if (rpcTaskInit() == ERROR) 6 return (ERROR); 7 8/* Get a client handle to the server */ 9cl = clnt_create (“colunbia”, MY_PROG, MY_VERS, 10 “tcp”); 11if (cl == NULL) 12 return(ERROR); 13... 14/* RPC interface similar to local calls */ 15if ((pNum = my_get_num_1 (NULL, cl)) == NULL) 16 { 17 clnt_destroy (cl); 18 return (ERROR); 19 }

13 D-13 Compilation Example Server runs on UNIX, client runs on VxWorks. User writes client.c, server.c, and spec.x. Compiling/linking (typically done in Makefile.): rpcgen spec.x cc [spec_xdr.c] spec_svc.c server.c -o servProg ccx -traditional spec_clnt.c [ccx -traditional spec_xdr.c] ccx client.c ld68k -r [spec_xdr.o] spec_clnt.o client.o -o clntProg.o

14 D-14 Summary rpcgenGenerates client and server stubs. reentrancyCode generated by rpcgen is not reentrant. rpcTaskInit( )Called by VxWorks tasks using RPC. Creates RPC context for the calling task. RPC objects not sharable between tasks.

15 D-15 RPC Appendix RPC Lab

16 D-16 Remote Procedure Call (RPC) Objective: To be able to call functions on remote nodes using the RPC protocol. In a X window, change your directory to HomeDir/unsupported/rpc. In this directory there is a program which runs on UNIX and prints the date. % unixDate Fri Dec 27 06:35:31 1991 This exercise is to modify this program so that, using RPC, we can execute the code from VxWorks. The steps below provide an overview of what is required. These steps will be discussed in more detail later. 1. Remote VxWorks with RPC included. 2. Create time.x, a RPC specifications file. To keep everyone’s work separate, use the following RPC program number: Team Program Number 10x20000001 20x20000002 30x20000003... 80x20000008 3. Write unixTimeServer.c (a modification of unixDate.c) to act as a RPC server. 4. Write vxTimeClient.c to act as an RPC client. 5. Use rpcgen to time.x to generate the time.h, time_svc.c and time_clnt.c files. 6. Modify time.h so that it will compile for VxWorks. You may use the script provided: % rpcModify time.h (Note: this step is optional if you compile with -nostdinc.)

17 D-17 7. Compile and link unixTimeServer.c and time_svc.c into timeServer. Since timeServer will run on the host side, use the native compiler for your host (cc in the laboratory). You may want to compile unixServer.c with a native ANSI compiler, and time_svc.c with a traditional compiler, then link the resulting object modules. Run timeServer in background. 8. Compile vxTimeClient.c and time_clnt.c Since the client runs under VxWorks, use the appropriate cross-compiler for your target. 9. Incrementally link vxTimeClient.o and time_clnt.o to create file called timeClient.o. Use the cross-linker for your architecture. 10. Load timeClient.o on your VxWorks target and test it. You can either stop here and start the lab or you can continue reading for a more detailed description of each of the steps above. Do what you think will make best use of your lab time. 1. Modify config.h so that the symbol INCLUDE_RPC is defined, or use WindConfig. Remake the system image. Then reboot your target. 2. Creating time.x, the RPC specification file The RPC specification file has the following format: program PROG_NAME { version VERSION_NAME { type routineName (type) = 1; type routineName (type) = 2;... } = versionNumber; } = programNumber; The PROG_NAME and VERSION_NAME are arbitrary names that will be converted by rpcgen into symbolic constants. We’ll call them TIME_PROG and TIME_VERS respectively. Since this is our first version, we’ll assign versionNumber to be 1. The program number must be in the range 0x200000000 to 0x3ffffff. Other numbers are reserved by Sun. Use a program number of 0x2000000n where n is your team number (0-8). Now we have: Contd...

18 D-18 Contd... program TIME_PROG { version TIME_VERS { type routineName (type) = 1; type routineName (type) = 2;... } = 1; } = 0X20000001; The innermost part of the structure is just a list of the routines in your program. We only have one routine, let’s call it print_time. By convention, the program name is written in upper case. So we have: program TIME_PROG { version TIME_VERS { type PRINT_TIME (type) = 1; } = 1; } = 0X20000001; What are we going to pass as an argument to print_time? Nothing, so it is type void. What does print_time return? A pointer to a character (string). RPC has predefined term, string, for a NULL terminated character string. So, now we have: program TIME_PROG { version TIME_VERS { string PRINT_TIME (void) = 1; } = 1; } = 0X20000001; 3. Modify unixDate.c Copy unicDate.c to unixTimeServer.c. We will make our changes in unixTimeServer.c. Remove the main( ) routine. The time_svc.c generated by rpcgen has the program’s main().

19 D-19 As a local routine print_time returns a pointer to a character (a string). Remote calls always use one more level of indirection than you would locally, i.e. if the local routine passes (or returns) a long, the remote call uses a pointer to a long. So, print_time must return a pointer to a string, i.e. “char**”. The name of the routine, PRINT_TIME, described in the specification file is converted to lower case and appended with the version number. That is, if you have a routine name of BLAH_BLAH in the specifications file and your version number is 2, then you need to define a routine called blah_blah_2. For our purposes, we need to change the name of the routine from print_time to print_time_1. So, the declaration should now read: char ** print_time_1 () Lastly, we need to modify the return value from: return (pStr); ---return a character pointer -- to: return (&pStr); returning a pointer to a string. 4. Write a routine called printTime is a file called vxTimeClient.c: This routine must call:  rpcTaskInit ()Initializes the VxWorks RPC package for this task.  clnt_create ()Creates a client handle to the RPC task on the remote host. The CLIENT handle returned from this routine should be stored in a global variable. By only calling clnt_create if the global variable is NULL, you avoid establishing this handle every time printTime is called. Note, however, that the CLIENT handle may not be shared between tasks. If you intend to call printTime( ) directly from the Wind Shell, you must recreate (and later delete, with clnt_destroy) the client handle on each call, as in this case a new task is created for each call. You might define a macro and use conditional compilation to treat these two cases differently. Another possible solution is given in the lab answers. Contd...

20 D-20 Contd... print_time_1( ) Gets the time from the server task  printf( )Prints the string received from print_time_1  free()Free memory allocated for the string. 5. Call rpcgen. % rpcgen time.x This should create a time.h, time_clnt.c, and time_svc.c 6. Call rpcModify. % rpcModify time.h This changes the include line in time.h from #include to #ifdef VXWORKS #include “vxWorks.h” #include “rpc/rpc.h” #else #include #endif If VXWORKS is defined, vxWorks.h and rpc/rpc.h will be included, otherwise rpc/rpc.h (under/usr/include). 7. Compile and link the server program with: % cc unixTimeServer.c time_svc.c -o timeServer Start the server program. %./timeServer

21 D-21 Contd... 8. Compile the main client program and client stub: % ccx -DVXWORKS vxTimeClient.c % ccx traditional -DVXWORKS timeclnt.c The “-traditional” flag is required because rpcgen generates non-ANSI code. The “-DVXWORKS” is to define VXWORKS so that the correct header files will be included in time.h. 9. Link the lient modules to form a client program: %ldArch -r vxTimeClient.o time_clnt.o -o timeClient.o 10. From VxWorks, change directory to HomeDir/unsupported/rpc and load the client module: -> ld < timeClient.o value = 0 = 0x0 Call the printTime routine (It was defined in client.o). -> printTime Fri Dec 27 14:36:09 1991 value = 0 = 0x0


Download ppt " Wind River Systems, Inc. 1997 Appendix - D RPC."

Similar presentations


Ads by Google