📄 unix_devs.c
字号:
/* * Copyright (C) 2000-2004 by ETH Zurich * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY ETH ZURICH AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ETH ZURICH * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * For additional information see http://www.ethernut.de/ * *//* unix_devs.c - a nut/os device driver for native unix devices * * 2004.04.01 Matthias Ringwald <matthias.ringwald@inf.ethz.ch> * * \todo check block read implementation * \todo allow native filee accesss using names like "FAT_C:/.." \see fs/fat.c * \todo implement cooked mode and use it as default mode * *//* avoid stdio nut wrapper */#define NO_STDIO_NUT_WRAPPER#include <fcntl_orig.h>#include <arch/unix.h>#include <sys/atom.h>#include <sys/device.h>#include <sys/file.h>#include <sys/timer.h>#include <sys/thread.h>#include <sys/event.h>#include <dev/usart.h>#include <dev/irqreg.h>#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <termios.h>#include <dev/unix_devs.h>// for sockets #include <sys/types.h>#include <sys/socket.h> // #include <netinet/in.h> // #include <arpa/inet.h> // #include <netdb.h>#include <sys/uio.h> #include <unistd.h>#include <string.h>#ifdef __CYGWIN__#include <sys/select.h>#endif/* on mac os x, not all baud rates are defined in termios.h but they are mapped to the numeric value anyway, so we define them here */#ifdef __APPLE__#ifndef B460800#define B460800 460800#endif#ifndef B500000#define B500000 500000#endif#ifndef B576000#define B576000 576000#endif#ifndef B921600#define B921600 921600#endif#endif/* thread attributes */pthread_attr_t unix_devs_attr;/* protect thread signaling */pthread_mutex_t unix_devs_mutex;/* to get a new thread start acked'd */pthread_cond_t unix_devs_cv;/* * functions available on avr somehow -- not implemented properly here :( */char *dtostre(double f, char *str, u_char prec, u_char flags);char *dtostre(double f, char *str, u_char prec, u_char flags){ sprintf(str, "%e", f); return str;}char *dtostrf(double f, char width, char prec, char *str);char *dtostrf(double f, char width, char prec, char *str){ sprintf(str, "%f", f); return str;}/* * Quite unnecessary functions, because linux doesn't define B19200 as 19200 * we have to map those value to their symbolic counterparts: * 0 * 50 * 75 * 110 * 134 * 150 * 200 * 300 * 600 * 1200 * 1800 * 2400 * 4800 * 9600 * 19200 * 38400 * 57600 * 115200 * 230400 * 460800 * 500000 * 576000 * 921600 */static int convertToRealSpeed(int baudSpeed){ switch (baudSpeed) { case B0: return 0; case B50: return 50; case B75: return 75; case B110: return 110; case B134: return 134; case B150: return 150; case B200: return 200; case B300: return 300; case B600: return 600; case B1200: return 1200; case B1800: return 1800; case B2400: return 2400; case B4800: return 4800; case B9600: return 9600; case B19200: return 19200; case B38400: return 38400; case B57600: return 57600; case B115200: return 115200; case B230400: return 230400;#ifndef __CYGWIN__ case B460800: return 460800; case B500000: return 500000; case B576000: return 576000; case B921600: return 921600;#endif } return -1;}static int convertToBaudSpeed(int realSpeed){ switch (realSpeed) { case 0: return B0; case 50: return B50; case 75: return B75; case 110: return B110; case 134: return B134; case 150: return B150; case 200: return B200; case 300: return B300; case 600: return B600; case 1200: return B1200; case 1800: return B1800; case 2400: return B2400; case 4800: return B4800; case 9600: return B9600; case 19200: return B19200; case 38400: return B38400; case 57600: return B57600; case 115200: return B115200; case 230400: return B230400;#ifndef __CYGWIN__ case 460800: return B460800; case 500000: return B500000; case 576000: return B576000; case 921600: return B921600;#endif } return -1;}/* ======================= sockets ======================== */unsigned int resolve(char *);unsigned int resolve(char *ip_addr){ struct hostent *hp; unsigned int ip; hp = gethostbyname(ip_addr); if (!hp) { ip = inet_addr(ip_addr); if ((int)ip == -1) { return -1; } else { return ip; } } // hp->h_length should equal to 4 memcpy(&ip, hp->h_addr, 4); return ip;}/* * IRQ Handler for correct signaling * not currently used (see UnixDevReadThread for more info on variantsstatic void UnixDevRxIntr(void *arg){ NUTDEVICE* dev = (NUTDEVICE*) arg; UNIXDCB * dcb = (UNIXDCB*) dev->dev_dcb; // printf("UnixDevRxIntr(%s)\n",dev->dev_name); NutEventPostFromIrq( &dcb->dcb_rx_rdy);} *//* * Read Thread * */static void *UnixDevReadThread( void * arg ){ int ret; int fd; fd_set rfd_set; NUTDEVICE* dev = (NUTDEVICE*) arg; UNIXDCB * dcb = (UNIXDCB*) dev->dev_dcb; // fd fd = dcb->dcb_fd; if (fd == STDOUT_FILENO) fd = STDIN_FILENO; // non-nut thread => block IRQ signals pthread_sigmask(SIG_BLOCK, &irq_signal, 0); // printf("UnixDevReadThread() started\n"); // be ready to receive requests pthread_mutex_lock(&dcb->dcb_rx_mutex); // confirm start pthread_mutex_lock(&unix_devs_mutex); pthread_cond_signal(&unix_devs_cv); pthread_mutex_unlock(&unix_devs_mutex); // printf("UnixDevReadThread(%s) start confirmed\n", dev->dev_name); // for (;;) { pthread_cond_wait(&dcb->dcb_rx_trigger, &dcb->dcb_rx_mutex); // printf("UnixDevReadThread(%s) triggered\n", dev->dev_name); // wait for data to become ready // do { FD_ZERO(&rfd_set); FD_SET(fd, &rfd_set); ret = select(fd + 1, &rfd_set, NULL, NULL, NULL); } while (FD_ISSET(fd, &rfd_set) == 0); // printf("UnixDevReadThread(%s) task processed\n", dev->dev_name); // signale waiting thread /* version 1 (working but could cause a race condition) NutEventPostAsync( &dcb->dcb_rx_rdy); */ /* version 2 (correct, but currently very slow) if (dev->dev_name[4] == '0') { NutIRQTrigger(IRQ_UART0_RX); } else { NutIRQTrigger(IRQ_UART1_RX); }*/ /* version 3 (another hack, but fast and correct */ switch (dev->dev_name[4]) { case '0': NutUnixIrqEventPostAsync( IRQ_UART0_RX, &dcb->dcb_rx_rdy); break; case '1': NutUnixIrqEventPostAsync( IRQ_UART1_RX, &dcb->dcb_rx_rdy); break; case '2': NutUnixIrqEventPostAsync( IRQ_UART2_RX, &dcb->dcb_rx_rdy); break; } } return 0;}/*! * \brief Open UnixDev * * \return Pointer to a static NUTFILE structure. */static NUTFILE *UnixDevOpen(NUTDEVICE * dev, const char *name, int mode, int acc){ NUTFILE *nf; int nativeFile; char *nativeName; struct termios t; long baud; pthread_t *thread; // sockets struct sockaddr_in sinaddr; struct sockaddr_in remote; unsigned int remote_ip; unsigned int remote_port; char *ip; char *port;// char *idx; // map from dev->name to unix name if (strncmp("uart", dev->dev_name, 4) == 0) { // uart switch (dev->dev_name[4]) { case '0': nativeName = emulation_options.uart_options[0].device; break; case '1': nativeName = emulation_options.uart_options[1].device; break; case '2': nativeName = emulation_options.uart_options[2].device;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -