色yeye在线视频观看_亚洲人亚洲精品成人网站_一级毛片免费播放_91精品一区二区中文字幕_一区二区三区日本视频_成人性生交大免费看


實驗:Linux下多路復用式串口操作

分享到:
           

    1.實驗目的

    通過編寫多路復用式串口讀寫,進一步理解多路復用函數的用法,同時更加熟練地掌握Linux設備文件的讀寫方法。

    2.實驗內容

    本實驗中,實現兩臺機器(宿主機和目標板)之間的串口通信,而且每臺機器均可以發送數據和接收數據。 除了串口設備名稱不同(宿主機上使用串口1:/dev/ttyS0,而在目標板上使用串口2:/dev/ttyS1),兩臺機器上的程序基本相同。

    首先,程序打開串口設備文件并進行相關配置,調用select()函數,使它等待從標準輸入(終端)文件中的輸入數據及從串口設備的輸入數據。如果有標準輸入文件上的數據,則寫入到串口,使對方讀取。如果有串口設備上的輸入數據,則將數據寫入到普通文件中。

    3.實驗步驟

    (1)畫出流程圖。圖2.6所示為程序流程圖,兩臺機器上的程序使用同樣的流程圖。


圖2.6 宿主機/目標板程序的流程圖

    (2)編寫代碼。編寫宿主機和目標板上的代碼,在這些程序中用到的open_port()和set_com_config()函數請參照后續章節所述,這里只列出宿主機上的代碼。

    /* com_host.c */
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <fcntl.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <errno.h>
    #include "uart_api.h"

    int main(void)
    {
        int fds[SEL_FILE_NUM], recv_fd, maxfd;
        char buff[BUFFER_SIZE];
        fd_set inset,tmp_inset;
        struct timeval tv;
        unsigned loop = 1;
        int res, real_read, i;
        /* 將從串口讀取的數據寫入到這個文件中 */
        if ((recv_fd = open(RECV_FILE_NAME, O_CREAT|O_WRONLY, 0644)) < 0)
        {
            perror("open");
            return 1;
        }

        fds[0] = STDIN_FILENO; /* 標準輸入 */
        if ((fds[1] = open_port(HOST_COM_PORT)) < 0) /* 打開串口 */
        {
            perror("open_port");
            return 1;
        }

        if (set_com_config(fds[1], 115200, 8, 'N', 1) < 0) /* 配置串口 */
        {
            perror("set_com_config");
            return 1;
        }

        FD_ZERO(&inset);
        FD_SET(fds[0], &inset);
        FD_SET(fds[1], &inset);
        maxfd = (fds[0] > fds[1])?fds[0]:fds[1];
        tv.tv_sec = TIME_DELAY;
        tv.tv_usec = 0;
        printf("Input some words(enter 'quit' to exit):\n");
        while (loop && (FD_ISSET(fds[0], &inset) || FD_ISSET(fds[1], &inset)))
        {
            tmp_inset = inset;
            res = select(maxfd + 1, &tmp_inset, NULL, NULL, &tv);
            switch(res)
            {
                case -1: /* 錯誤 */
                {
                    perror("select");
                    loop = 0;
                }
                break;

                case 0: /* 超時 */
                {
                    perror("select time out");
                    loop = 0;
                }
                break;

                default:
                {
                    for (i = 0; i < SEL_FILE_NUM; i++)
                    {
                        if (FD_ISSET(fds[i], &tmp_inset))
                        {
                            memset(buff, 0, BUFFER_SIZE);
                            /* 讀取標準輸入或者串口設備文件 */
                            real_read = read(fds[i], buff, BUFFER_SIZE);
                            if ((real_read < 0) && (errno != EAGAIN))
                            {
                                loop = 0;
                            }
                            else if (!real_read)
                            {
                                close(fds[i]);
                                FD_CLR(fds[i], &inset);
                            }
                            else
                            {
                                buff[real_read] = '\0';
                                if (i == 0)
                                { /* 將從終端讀取的數據寫入到串口 */
                                    write(fds[1], buff, strlen(buff));
                                    printf("Input some words
                                    (enter 'quit' to exit):\n");
                                }
                                else if (i == 1)
                                { /* 將從串口讀取的數據寫入到普通文件中 */
                                    write(recv_fd, buff, real_read);
                                }
                                if (strncmp(buff, "quit", 4) == 0)
                                { /* 如果讀取為quit則退出 */
                                    loop = 0;
                                }
                            }
                        } /* end of if FD_ISSET */
                    } /* for i */
                }
            } /* end of switch */
        } /* end of while */
        close(recv_fd);
        return 0;
    }

    (3)接下來,將目標板的串口程序交叉編譯,再將宿主機的串口程序在PC上編譯。

    (4)連接PC的串口1和開發板的串口2,然后將目標板串口程序下載到開發板上,分別在兩臺機器上運行串口程序。

    4.實驗結果

    宿主機上的運行結果如下所示:

    $ ./com_host
    Input some words(enter 'quit' to exit):
    Hello, Target!
    Input some words(enter 'quit' to exit):
    I'm host program!
    Input some words(enter 'quit' to exit):
    Byebye!
    Input some words(enter 'quit' to exit):
    quit /* 這個輸入使雙方的程序都結束 */

    從串口讀取的數據(即目標板中發送過來的數據)寫入到同目錄下的recv.dat文件中。

    $ cat recv.dat
    Hello, Host!
    I'm target program!
    Byebye!

    目標板上的運行結果如下所示:

    $ ./com_target
    Input some words(enter 'quit' to exit):
    Hello, Host!
    Input some words(enter 'quit' to exit):
    I'm target program!
    Input some words(enter 'quit' to exit):
    Byebye!

    與宿主機上的代碼相同,從串口讀取的數據(即目標板中發送過來的數據)寫入到同目錄下的recv.dat文件中。

    $ cat recv.dat
    Hello, Target!
    I'm host program!
    Byebye!
    Quit

    請讀者用poll()函數實現具有以上功能的代碼。

    本文選自華清遠見嵌入式培訓教材《從實踐中學嵌入式Linux應用程序開發》

   熱點鏈接:

   1、Linux下多路復用I/O接口
   2、嵌入式Linux串口應用編程之串口讀寫
   3、嵌入式Linux串口應用編程之串口配置
   4、嵌入式Linux串口應用編程基礎知識
   5、標準I/O操作的緩沖存儲類型

更多新聞>> 

主站蜘蛛池模板: 国产00粉嫩馒头一线天萌白酱 | AAAAA级少妇高潮大片免费看 | 男同CHAINSEXGAY同志 | 波多野结衣系列18部无码观看a | 国产一区二区99 | 国产精品久久高潮 | 久久久久影院美女国产主播 | 蜜桃AV无码免费看永久 | 中国6一12呦女精品 男人a天堂2814 | 亚洲AV无码一区二区三区在线播放 | 日本免费a级片 | 久久水蜜桃亚洲av无码精品麻豆 | 精品国产成人网站一区二区 | 欧美私人家庭影院 | 国产成人无码AV片在线观看不卡 | A8在线看片WWW | 亚洲国产精品无码久久一区二区 | 久碰香蕉线视频在线观看视频 | 国产在线乱子伦一区二区 | 给丰满丁字裤少妇按摩到高潮 | 亚洲精品成人AA片在线播 | 性动态图AV无码专区 | 人妻被按摩师玩弄到潮喷 | www国产黄色 | 天天爽天天爽夜夜爽毛片 | 成人毛片AV免费 | 人妻少妇乱子伦喷水 | 免费观看又黄又爽的视频 | 无码中文字幕在线播放2 | 日本高清色www在线安全 | 又大又爽又黄无码A片 | 美国少妇性xxxx另类 | 国产偷窥熟女高潮精品视频 | 麻批好紧日起要舒服死了 | 日本一级淫片免费放 | 少妇人妻真实偷人精品视频 | 亚洲人成在线观看网站不卡 | 99久久久国产精品免费牛牛 | 亚洲国产精品一区二区久久亚洲午夜 | 亚洲黄网在线 | 涩av在线 |