The EtherSmart Wildcard User GuideTable of ContentsSummary of EtherSmart Capabilities Connecting To the Wildcard Bus Selecting the Wildcard Address The EtherSmart Software Driver Routines EtherSmart Driver Data Structures EtherSmart Initialization, Configuration and Diagnostics Initializing Multiple EtherSmart Wildcards Code Downloads and Interactive Communications via Ethernet Serial Tunneling Buffer Management Functions Serial Tunneling Data Transmission and Reception Functions Serial Tunneling Connection Functions Serial Tunneling Inter-Task Service Management Functions Introduction to the Dynamic Webserver An Example of a Dynamic Web Page with a Remote Image Reference Serving Out a Stand-Alone Image Implementing a "Remote Front Panel" Using the Webserver Appendix A: Installing the Software Generating the EtherSmart Kernel Extension Library Creating Web Page and Image Resources with the Image Converter Loading the Software onto the Controller Using the EtherSmart Driver with C Using the Driver Code with Forth Appendix C: C Remote Front Panel Demo Program Appendix D: Forth Demo Program Appendix E: Forth Remote Front Panel Demo Program Appendix F: Browser Configuration Using Opera Is Highly Recommended Reconfiguring the Internet Explorer Browser Appendix G: Hardware Schematic (pdf) |
Appendix C: C Remote Front Panel Demo Program
Listing 1‑19 Ether_GUI_Demo.c program listing. // this demonstration code is provided in source form. // Top level function: // GUI_Web_Demo ( -- ) // no input parameters; runs gui and web page
// *************** IMPORTANT: SET MODULENUM TO MATCH HARDWARE JUMPERS ******************
// recall: modulenum 0 is reserved on the QScreen!
#define E_MODULENUM 4 // ******** SET THIS TO MATCH HARDWARE JUMPERS J1 AND J2! *****
// This specifies the modulenum for the high level functions in this file // except for Ether_Monitor_Demo (see its comments).
// If EtherSmart is installed on module bus 0, E_MODULENUM = 0, 1, 2, or 3 // If EtherSmart is installed on module bus 1, E_MODULENUM = 4, 5, 6, or 7 // That is, the bus specifies the top bit of a 3-bit modulenum, // and [J2, J1] specifies the remaining 2 bits of the modulenum. // Example: On module bus 0, if neither jumper cap is installed: E_MODULENUM = 0 // Example: On module bus 0, if both jumper caps are installed: E_MODULENUM = 3 // Example: On module bus 1, if J2 is installed but J1 is not: E_MODULENUM = 6
// ************** #includes **************
#include <\mosaic\allqed.h> // include all of the qed and C utilities
// choose the correct controller product, comment in/out the appropriate #includes:
#include “Library\esmart_gui_qvga\library.h” // for QVGA controller #include “Library\esmart_gui_qvga\library.c”
// #include “Library\esmart_gui_qscreen\library.h” // for QScreen controller // #include “Library\esmart_gui_qscreen\library.c”
// include the header file that defines the base xaddress and 32-bit size for each resource: #include “Resources\qvga\image_headers.h” // for QVGA controller // #include “Resources\qscreen\image_headers.h” // for QScreen controller
#include “guidemo_qvga.c” // gui demo program for qvga controller // #include “guidemo_qscreen.c” // gui demo program for qscreen controller
#include “strdefs.h” // defines STRING_XADDR(str_addr) macro; see comments below
// ************** USEFUL MACRO FOR STRINGS IN V4.xx C COMPILER **************
// the TO_XADDR defined in /mosaic/include/types.h // transforms a separate 16-bit addr, page into a 32-bit xaddress: // #define TO_XADDR(address,page) ((xaddr) (((page)<<16)+ (0xFFFF & (address))))
// We want to substitute THIS_PAGE (also defined in types.h) for the page, // as the V4.xx C compiler replicates the strings on each page; // therefore, in most cases, the calling function’s page is the same as the string page:
// #define STRING_XADDR(str_addr) ((xaddr) TO_XADDR(((xaddr) str_addr), ((xaddr) THIS_PAGE)))
// ************** USEFUL CONSTANTS **************
#ifdef __FABIUS__ #define BITMAP_BUFFER 0x020000 // if V4.xx, put on pg 2 #else #define BITMAP_BUFFER 0x148000 // if V6.xx, put on pg 0x14 #endif // __FABIUS__
#define BITMAP_MAXBYTES 0x8000 // 32K max, plenty for monochrome displays #define BITMAP_SCREEN_FORMAT 1 // used by Screen_To_Image, Simulated_Touch_To_Image
// ************** SETUP ETHERNET TASK TO RUN WEB AND TUNNELING SERVICES **************
TASK ether_control_task; // 1 Kbyte per task area
_Q void Ether_Task_Setup_Default( void ) // performs full initialization of the ether_info struct and mailboxes for the // specified modulenum, and // builds and activates an ethernet control task to service the xport { // NEXT_TASK = TASKBASE; // empties task loop; comment out if other tasks are allowed Ether_Task_Setup( ðer_control_task, E_MODULENUM); }
// ********************* URL STRINGS **************************
char* slash_url_str = “/”; // synonym for home page url
char* index_url_str = “/index.html”; // home page url
char* screen_image_str = “/screen_image.bmp”; // screen image url
char* gui_response_str = “/gui_response.cgi”; // gui response url
// *********************** WEBSERVER ***************************
// the following is created using the Image Converter program which creates 2 constants: // GUI_RESPONSE_TEXT_HTML_XADDR // GUI_RESPONSE_TEXT_HTML_SIZE
// <html><head><title>EtherSmart/GUI Remote Front Panel</title></head> // <body> // <H3>EtherSmart/GUI Remote Front Panel</H3><p> // <H4>Click on the screen image to operate the touchscreen remotely</H3><p><p> // <a href=“/gui_response.cgi”><img src=“/screen_image.bmp” ismap></a> // </body></html>
// make sure to declare gui_response.cgi as Cache-Control: no-cache (dynamic content). // Notes: this works very nicely with Opera, the recommended browser.
void Screen_Image_Response( int modulenum ) // handler for /screen_image.bmp url. serves the screen image. // assumes that Simulated_Touch_To_Image has run. // xbuffer contains 32-bit count (NOTE!) followed by image data. // marks as no-cache (always reloads). // NOTE: this function is NOT a gui handler; it should be posted by http_add_handler. { xaddr http_outbuf_base = HTTP_Outbuf(modulenum); uint http_outbuf_size = HTTP_Outbufsize(modulenum); uint image_size = FetchInt((xaddr) (BITMAP_BUFFER+2)); // get size of image we created uint http_header_size; HTTP_Put_Header(http_outbuf_base, http_outbuf_size); // http header->outbuf HTTP_Put_Content_Type(http_outbuf_base, http_outbuf_size, 1, HTTP_IMAGE_BITMAP_CONTENT); // params: xlbuf,maxbufsize,dynamic?,content_type // dynamic bitmap image content ->outbuf;header is done http_header_size = FetchInt(http_outbuf_base); // get size of http header we created HTTP_Send_2Buffers(http_outbuf_base+2, http_header_size, (xaddr) (BITMAP_BUFFER+4), image_size, modulenum); } // send http header and bitmap image
// from types.h, used in GUI_Response to hold HTTP_Imagemap x,y results. // typedef union // { ulong int32; // struct // { int msInt; // int lsInt; // } twoNums; // } TWO_INTS;
void GUI_Response( int modulenum ) // a clickable ismap version of the screen image that runs the gui toolkit simulated touch. // url = /gui_response.cgi // this routine is called via ether_check_gui which runs in the application task // that runs Service_GUI_Events. it is posted using http_gui_add_handler. { xaddr http_outbuf_base = HTTP_Outbuf(modulenum); uint http_outbuf_size = HTTP_Outbufsize(modulenum); uint http_header_size, x, y; TWO_INTS x_and_y; x_and_y = HTTP_Imagemap( modulenum); // get mouseclick x,y coordinates x = x_and_y.twoNums.msInt; // get x from most significant 16bits y = x_and_y.twoNums.lsInt; // get y from least significant 16bits Simulated_Touch_To_Image(BITMAP_BUFFER, BITMAP_MAXBYTES, BITMAP_SCREEN_FORMAT, x, y); HTTP_Put_Header(http_outbuf_base, http_outbuf_size); // http header->outbuf HTTP_Put_Content_Type(http_outbuf_base, http_outbuf_size, 0, HTTP_TEXT_HTML_CONTENT); // params: xlbuf,maxbufsize,dynamic?,content_type // dynamic bitmap image content ->outbuf;header is done http_header_size = FetchInt(http_outbuf_base); // get size of http header we created HTTP_GUI_Send_2Buffers(http_outbuf_base+2, http_header_size, GUI_RESPONSE_TEXT_HTML_XADDR, GUI_RESPONSE_TEXT_HTML_SIZE, modulenum); } // send http header and content
_Q int Init_Screen_Image( void ) // if return value=0, image has been created { return Screen_To_Image((xaddr) BITMAP_BUFFER, BITMAP_MAXBYTES, BITMAP_SCREEN_FORMAT); }
void Remote_Panel_Start( int modulenum ) // serves an initial clickable ismap version of the screen image. // url = /index.html // puts initial version of screen into bitmap_buffer. // this routine is called via ether_check_gui which runs in the application task // that runs Service_GUI_Events. it is posted using http_gui_add_handler { xaddr http_outbuf_base = HTTP_Outbuf(modulenum); uint http_outbuf_size = HTTP_Outbufsize(modulenum); int http_header_size; HTTP_Put_Header(http_outbuf_base, http_outbuf_size); // http header->outbuf HTTP_Put_Content_Type(http_outbuf_base, http_outbuf_size,0, HTTP_TEXT_HTML_CONTENT); // params: xlbuf,maxbufsize,dynamic?,content_type // static html type->outbuf, cnt in first 2bytes; header’s done Init_Screen_Image(); // ignore return value; image has been created http_header_size = FetchInt(http_outbuf_base); // get size of http header we created HTTP_GUI_Send_2Buffers(http_outbuf_base+2, http_header_size, GUI_RESPONSE_TEXT_HTML_XADDR, GUI_RESPONSE_TEXT_HTML_SIZE, modulenum); // params: xbuf1,cnt1,xbuf2,count2,modulenum } // send header&content, ignore numbytes_sent
#ifdef __FABIUS__ #pragma option init=.doubleword // declare 32-bit function pointers in code area #include </mosaic/gui_tk/to_large.h> #endif // __FABIUS__
xaddr (*screen_image_response_ptr)(void) = Screen_Image_Response; xaddr (*gui_response_ptr)(void) = GUI_Response; xaddr (*remote_panel_start_ptr)(void) = Remote_Panel_Start; // home page
#ifdef __FABIUS__ #include </mosaic/gui_tk/fr_large.h> #pragma option init=.init // return the initialized variable area to RAM; #endif // __FABIUS__
int Install_GUI_Web_Handlers( int modulenum ) // call this after ETHER_Task_Setup_DEFAULT point browser to raw ip or to // ip/index.html to see the home GUI web page = remote front panel. // urls are case sensitive. // any other url’s serve out: page not found. // returns nonzero error if too many handlers were added // (limited by AUTOSERVE_DEFAULT_ROWS passed to ether_init) // Some of the gui web handlers in this example are handled by the application task. { int error = 0; // we’ll OR error results together and return final result error |= HTTP_Add_GUI_Handler(STRING_XADDR(slash_url_str), strlen(slash_url_str), remote_panel_start_ptr, modulenum); error |= HTTP_Add_GUI_Handler(STRING_XADDR(index_url_str), strlen(index_url_str), remote_panel_start_ptr, modulenum); error |= HTTP_Add_Handler(STRING_XADDR(screen_image_str), strlen(screen_image_str), screen_image_response_ptr, modulenum); error |= HTTP_Add_GUI_Handler(STRING_XADDR(gui_response_str), strlen(gui_response_str), gui_response_ptr, modulenum); InitElapsedTime(); // start at zero so home page reports correct elapsed time return(error); }
_Q void GUI_Web_Demo( void ) { Ether_Task_Setup_Default(); // start ethernet task Install_GUI_Web_Handlers(E_MODULENUM); // setup web; ignore error flag GUI_Demo(); // start the gui demo on local touchscreen } // NOTE: for QScreen, GUI_Demo MUST call Globalize_TVars(TVARS);
void main(void) { GUI_Web_Demo(); }
// NOTES: place a call to Ether_Check_GUI(E_MODULENUM); in the application task // that invokes the GUI Routine // (for example, after the call to Service_GUI_Events on a QVGA Controller system). // Add a call to Screen_Has_Changed(); in each GUI handler that changes screen appearance. // QScreen Controllers require a call to Globalize_TVars(TVARS); in the init function. // When building tasks, do NOT include the statement NEXT_TASK = TASKBASE; // because we want to allow multiple tasks to be built. // Type WARM or COLD before re-running the program.
|
Home|Site Map|Products|Manuals|Resources|Order|About Us
Copyright (c) 2006 Mosaic Industries, Inc.
Your source for single board computers, embedded controllers, and operator interfaces for instruments and automation