IT培训机构|91免费精品视频|专注编程培训|91免费精品|软件开发培训_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操作的緩沖存儲類型

更多新聞>> 

主站蜘蛛池模板: 四川升降货梯厂家-提供高品质货梯产品-见田科技液压升降平台厂家 | 三亚酒吧KTV会所 专业舞台音响灯光 智能影音 会议音响工程 首选海南东演音响公司 | 智能电地暖_电地暖安装_电地暖价格-西安秦星暖通工程有限公司 | 宁波雷豹机电科技有限公司|雷豹冷风机|雷豹工业大风扇|MFC18000|MFC16000|MFC6000|EF3622|EF4222|EF4822|移动工业蒸发式冷风机空气冷却器|大型工业空调扇|雷豹移动式工业大风扇|雷豹大风扇|生产厂家|公司官网 | 暖气片,暖气片厂家,散热器,暖气片品牌-青岛瑞雪兆散热器有限公司 | 南宁清洁公司|外墙清洗|开荒清洁|洒水车|管道疏通|园林绿化_广西优而美环境工程有限公司 | 拉力机|拉力试验机|拉力测试机厂家-苏州天氏库力精密仪器有限公司 | 金华美凡文化传媒有限公司 | 呼吸家官网|肺功能检测仪生产厂家|国产肺功能仪知名品牌|肺功能检测仪|肺功能测试仪|婴幼儿肺功能仪|弥散残气肺功能仪|肺功能测试系统|广州红象医疗科技有限公司|便携式肺功能仪|大肺功能仪|呼吸康复一体机|儿童肺功能仪|肺活量计|医用简易肺功能仪|呼吸康复系统|肺功能仪|弥散肺功能仪(大肺)|便携式肺功能检测仪|肺康复|呼吸肌力测定肺功能仪|肺功能测定仪|呼吸神经肌肉刺激仪|便携式肺功能 | 厦门,泉州自助餐上门|生日自助餐|婚礼自助餐|公司聚会自助餐|户外烧烤|冷餐|茶歇外卖配送-福建非选餐饮公司 | 校园文化设计|文化墙建设|校园景观雕塑|校史馆设计-深圳市天合文化 | 亚洲一区日韩一区欧美一区a,中文字幕乱妇无码AV在线,欧美日韩免费在线观看,国产精品一区二区三区免费,日韩精品免费一线在线观看,日韩一本在线,国产呦精品一区二区三区下载,国产日韩精品一区二区在线观看,欧美日韩高清一区二区三区,日韩在线免费观看视频,欧美日韩一区在线观看 | 铸铁平台-焊接平台-划线平台-三维焊接平台厂家-泊头市溪海冶金机械设备有限公司 | 上海离婚律师|上海婚姻律师|上海家畅家事律师-上海家畅离婚律师网 | 碳化硅微粉_超细碳化硅微粉_潍坊凯华碳化硅微粉有限公司 | 意优教育|意大利留学中介_意大利留学费用_意大利申请条件_北京意大利语培训学校 | 拖链电缆-卷筒电缆-行车电缆-机器人电缆-上海甲朗制造 | 全自动圆木多片锯_立式圆木多片锯价格_大型圆木多片锯厂家-邢台友创机械制造有限公司 | 手游下载_app下载_好玩的手游下载_安卓市场下载_163下载 | 天之水网_新时代主流门户网站 十大文明网,主流新媒 、 值得信赖、关注我、温暖你! | 泰安led显示屏-泰安户外裸眼3D显示屏-扩声系统-舞台灯光机械-电子屏-肥城宁阳新泰东平-泰安市奇美特电子有限公司 | 无尘车间_净化工程_GMP食品药品化妆品电子厂无尘净化车间_无尘室 | 中深世纪广告公司 深圳标志设计,深圳logo设计公司,包装设计公司,深圳商标设计,深圳画册设计公司 中商信息网-商务数据网-中文商务数据网 | 金酱酒_金酱酒代理加盟招商_OEM贴牌企业定制! – 金酱酒代理加盟!茅台镇较早的酿酒烧坊,年产优质酱香白酒5000余吨,仁怀市十强白酒企业,主营主品:金酱酒、金酱陈香酒、酱香老酒等系列品牌产品 | 家具板|橱柜衣柜家具板|木饰面定制|榉木胶合板|防水胶合板|胶合板厂家-佛山吉盛唐朝木业-大坂木业 | 河南反渗透设备,河南纯净水设备,河南软化水设备,郑州EDI超纯水设备,郑州水处理设备厂家_河南江宇环保科技有限公司 | 西安西雷脉冲功率技术有限公司-高压调制器/加速器与脉冲功率系统的研发/生产/应用推广/高压脉冲电源的应用研究/设计/生产和销售/高功率脉冲器件/材料与仪器设备的研发/生产和销售/高电压/大电流/强磁场环境的模拟及测试服务/会议会展服务/货物及进出口的业务/脉冲功率技术领域类的技术转让 | 明康食品有限公司 -方集馓子 亨特小麻花 | 全自动烫金机-全自动移印机-全自动丝印机-全自动平面机-东莞联昌实业供应各种丝印机和移印机 | 昆明纸箱厂-礼盒定制-包装盒定做-纸箱厂-云南包掌柜包装有限公司 | 苏州交通设施_道路划线_停车场划线_厂区划线_环氧地坪厂家-推荐【飞扬市政交通设施公司】专注交通设施8年! | 深圳LED显示屏厂家_室内户外LED显示屏_彩屏电子有限公司 | 普利塞HS穿刺活检针-巴德穿刺活检针-美创爱琅Argon活检针同轴针-山东瑞玺源 | 宿迁市华泰交通设施有限公司,上海第四代路名牌,天津仿罗马柱路名牌,标准路名牌,路名牌灯箱,公交站台,户外广告灯箱, 交通标志牌,社区阅报栏 | 耐压测试仪(检测电气设备绝缘性能)百科 | 十树品牌策划—品牌战略、品牌策划、品牌定位、品牌设计、包装设计、品牌营销-上海十树品牌管理咨询有限公司官网 | 西门子伺服电机维修_西门子变频器维修_西门子伺服驱动器维修_数控系统维修_PL维修-上海仰光电子 西克制冷官网│制冷机组冷风机冷库设备厂家-西克制冷(无锡)有限公司_西克制冷(无锡)有限公司 | 免喷涂材料,免喷涂塑料,免喷涂注塑,免喷涂挤塑,免喷涂工艺-中山鸿盛免喷涂 | 影像测量仪|检测设备定制|平面度测量仪|三坐标测量机|广州市海科思自动化设备有限公司-400-0528-668 | 乌鲁木齐万通汽车学校 | 泊头市特种油泵阀制造有限公司&nbsp;-&nbsp;渣油泵,重油泵,沥青泵,高压齿轮泵,煤焦油泵,导热油泵,三螺杆泵,圆弧齿轮泵,不锈钢齿轮泵, |