⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unix_devs.c

📁 含有完整TCP/IP PPP协议的嵌入式操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * 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 + -