Nut/OS  4.10.3
API Reference
rs232d.c
Go to the documentation of this file.
00001 
00052 #include <dev/board.h>
00053 
00054 #include <sys/heap.h>
00055 #include <sys/thread.h>
00056 #include <sys/timer.h>
00057 #include <sys/socket.h>
00058 
00059 #include <stdlib.h>
00060 #include <stdio.h>
00061 #include <string.h>
00062 #include <io.h>
00063 #include <fcntl.h>
00064 
00065 #include <arpa/inet.h>
00066 #include <net/if_var.h>
00067 #include <pro/dhcp.h>
00068 
00069 #define BUFFERSIZE  128
00070 #define TCPPORT     23
00071 
00072 typedef struct {
00073     FILE *cd_rs232;
00074     FILE *cd_tcpip;
00075     char cd_connected;
00076 } CHANNEL;
00077 
00078 /*
00079  * Transfer data from input stream to output stream.
00080  */
00081 void StreamCopy(FILE * istream, FILE * ostream, char *cop)
00082 {
00083     int cnt;
00084     char *buff;
00085 
00086     buff = malloc(BUFFERSIZE);
00087     while (*cop) {
00088         if ((cnt = fread(buff, 1, BUFFERSIZE, istream)) <= 0)
00089             break;
00090         if (*cop && (cnt = fwrite(buff, 1, cnt, ostream)) <= 0)
00091             break;
00092         if (*cop && fflush(ostream))
00093             break;
00094     }
00095     *cop = 0;
00096     free(buff);
00097 }
00098 
00099 /*
00100  * From RS232 to socket.
00101  */
00102 THREAD(Receiver, arg)
00103 {
00104     CHANNEL *cdp = arg;
00105 
00106     for (;;) {
00107         if (cdp->cd_connected) {
00108             NutThreadSetPriority(64);
00109             /*
00110              * We are reading from the UART without any timeout. So we
00111              * won't return immediately when disconnected.
00112              */
00113             StreamCopy(cdp->cd_rs232, cdp->cd_tcpip, &cdp->cd_connected);
00114             NutThreadSetPriority(128);
00115         }
00116         NutThreadYield();
00117     }
00118 }
00119 
00120 /*
00121  * Main application routine. 
00122  *
00123  * Nut/OS automatically calls this entry after initialization.
00124  */
00125 int main(void)
00126 {
00127     TCPSOCKET *sock;
00128     CHANNEL cd;
00129     uint32_t baud = 9600;
00130 
00131     /*
00132      * Register our devices.
00133      */
00134     NutRegisterDevice(&DEV_UART, 0, 0);
00135 #ifndef DEV_ETHER
00136     for (;;);
00137 #else
00138     NutRegisterDevice(&DEV_ETHER, 0x8300, 5);
00139 
00140     /*
00141      * Setup the uart device.
00142      */
00143     cd.cd_rs232 = fopen(DEV_UART_NAME, "r+b");
00144     _ioctl(_fileno(cd.cd_rs232), UART_SETSPEED, &baud);
00145 
00146     /*
00147      * Setup the ethernet device. Try DHCP first. If this is
00148      * the first time boot with empty EEPROM and no DHCP server
00149      * was found, use hardcoded values.
00150      */
00151     if (NutDhcpIfConfig(DEV_ETHER_NAME, 0, 60000)) {
00152         /* No valid EEPROM contents, use hard coded MAC. */
00153         uint8_t my_mac[] = { 0x00, 0x06, 0x98, 0x20, 0x00, 0x00 };
00154 
00155         if (NutDhcpIfConfig("eth0", my_mac, 60000)) {
00156             /* No DHCP server found, use hard coded IP address. */
00157             uint32_t ip_addr = inet_addr("192.168.192.100");
00158             uint32_t ip_mask = inet_addr("255.255.255.0");
00159 
00160             NutNetIfConfig("eth0", my_mac, ip_addr, ip_mask);
00161             /* If not in a local network, we must also call 
00162                NutIpRouteAdd() to configure the routing. */
00163         }
00164     }
00165 
00166     /*
00167      * Start a RS232 receiver thread.
00168      */
00169     NutThreadCreate("xmit", Receiver, &cd, 512);
00170 
00171     /*
00172      * Now loop endless for connections.
00173      */
00174     cd.cd_connected = 0;
00175     for (;;) {
00176         /*
00177          * Create a socket and listen for a client.
00178          */
00179         sock = NutTcpCreateSocket();
00180         NutTcpAccept(sock, TCPPORT);
00181 
00182         /*
00183          * Open a stdio stream assigned to the connected socket.
00184          */
00185         cd.cd_tcpip = _fdopen((int) sock, "r+b");
00186         cd.cd_connected = 1;
00187 
00188         /*
00189          * Call RS232 transmit routine. On return we will be
00190          * disconnected again.
00191          */
00192         StreamCopy(cd.cd_tcpip, cd.cd_rs232, &cd.cd_connected);
00193 
00194         /*
00195          * Close the stream.
00196          */
00197         fclose(cd.cd_tcpip);
00198 
00199         /*
00200          * Close our socket.
00201          */
00202         NutTcpCloseSocket(sock);
00203     }
00204 #endif
00205     return 0;
00206 }