打印
[新唐博主]

【优质评测精选】NuMaker-IIoT-NUC980 测评之网络 USB 打印机测试

[复制链接]
6124|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
21ic小管家|  楼主 | 2022-5-30 12:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
NuMaker-IIoT-NUC980

测评之网络 USB 打印机测试



功能模块的硬件介绍

新唐NuMaker-IIoT-NUC980开发板核心搭载了NUC980DR61YC 的ARM9处理器,主频最高300M,并且芯片集成了64 MB的DRAM,外设接口包由物联网常用的数据通讯接口,比如以太网接口、USB 2.0高速接口、RS-485总线、CAN 总线、SPI接口、通用GPIO、硬件加速等等,开发板官方也支持许多操作系统,比如rt-thread、linux、freertos、openwrt等等,资料文档也非常齐全。





功能模块的使用说明

开发板包装非常简约,里面打开了就可以看到主板本体




随便找了根usb micro的数据线,接到开发板的烧写端口(板子上一共有2 个 micro usb 接口,一个用于是连接到 nuc980 usb,可以用于给 nuc980 下载固件,还有一个USB是连接到板子上的 USB 转 TTL,可以用于调试,把NUC980 设置为 USB 启动进入下载模式)



此时电脑出现usb设备发现,但是缺少驱动的提示





安装WinUSB4NuVCOM.exe




打开NuWriterNuWriterReleaseNuWriter.exe
这样就可以对开发板进行各种类型的烧写了

打开RT-Thread Stduio,安装980开发板相对应的开发包,新建工程进行编译

开发板的主板sw1跳线到usb启动,使用nuwiter进行下载


成功运行rt-thread


RT-Thread开发
1、参考linux的usb打印机驱动,移植进rt-thread,增加配置项


可以成功发现识别usb打印机


2、编写tcp server透传数据给打印机
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date           Author       Notes
* 2022-03-15     Tuber      first version
*/

#include
#include
#include
#include
#include
#include
#include

#define PRINTER_BUF_SIZE    1024
#define PRINTER_TCP_PORT    9100

rt_err_t printer_tcp_server_one_job()
{
    char *buf;
    socklen_t sin_size;
    int server, client, bytes_received;
    struct sockaddr_in server_addr, client_addr;
    int ret;
    int optval;
    int nrecv = 0;
    rt_device_t printer_dev;
    struct timeval timeout = { 0, 1 };

    server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (server == -1)
    {
        rt_kprintf("Socket error\n");
        return -RT_ERROR;
    }

    optval = 1;
    ret = setsockopt(server, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
    if (ret == -1)
    {
        rt_kprintf("Setsockopt error\n");
        closesocket(server);
        return -RT_ERROR;
    }

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(PRINTER_TCP_PORT);
    server_addr.sin_addr.s_addr = INADDR_ANY;
    rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));

    ret = bind(server, (struct sockaddr *) &server_addr, sizeof(struct sockaddr));
    if (ret == -1)
    {
        rt_kprintf("Unable to bind %d %d\n", ret, rt_get_errno());
        closesocket(server);
        return -RT_ERROR;
    }

    if (listen(server, 5) == -1)
    {
        rt_kprintf("Listen error\n");
        closesocket(server);
        return -RT_ERROR;
    }

    rt_kprintf("Prnd Server Waiting for client on port 9100\n");

    sin_size = sizeof(struct sockaddr_in);
    client = accept(server, (struct sockaddr *) &client_addr, &sin_size);
    if (client < 0)
    {
        rt_kprintf("accept connection failed! errno = %d\n", errno);
        closesocket(server);
        return -RT_ERROR;
    }

    ret = closesocket(server);

    // set timeout
    ret = setsockopt(client, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
    if (ret == -1)
    {
        closesocket(client);
        return -RT_ERROR;
    }

    rt_kprintf("I got a connection from (%s , %d)\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));

    //open printer and write data
    printer_dev = rt_device_find("prn1");
    if (!printer_dev)
    {
        rt_kprintf("find %s failed!\n", "prn1");
        closesocket(client);
        return -RT_ERROR;
    }

    ret = rt_device_open(printer_dev, RT_DEVICE_OFLAG_RDWR);
    if (ret != RT_EOK)
    {
        rt_kprintf("could not open printer\n");
        closesocket(client);
        return -RT_ERROR;
    }

    buf = rt_malloc(PRINTER_BUF_SIZE);
    if (buf == NULL)
    {
        rt_kprintf("malloc buf failed\n");
        closesocket(client);
        return -RT_ENOMEM;
    }

    while (1)
    {
        //read from printer
//        bytes_received = rt_device_read(printer_dev, 0, buf, PRINTER_BUF_SIZE);
//        if (bytes_received <= 0 && rt_get_errno() != RT_EOK)
//        {
//            break;
//        }
//        else if (bytes_received > 0)
//        {
//            rt_kprintf("usb recv[%d]\n", bytes_received);
//            send(client, buf, bytes_received, 0); //write to tcp client
//        }

        //read data from tcp server
        bytes_received = recv(client, buf, PRINTER_BUF_SIZE, 0);
        if (bytes_received <= 0 && rt_get_errno() != 18)
        {
            break;
        }
        else if (bytes_received > 0)
        {
            rt_kprintf("client recv[%d]\n", bytes_received);
            rt_device_write(printer_dev, 0, buf, bytes_received); //write to printer
            nrecv += bytes_received;
        }
    }

    rt_kprintf("\n nrecv %d = %d \r\n", nrecv);

    rt_free(buf);

    rt_device_close(printer_dev);

    closesocket(client);

    return RT_EOK;
}

void printer_tcp_server_task(void *arg)
{
    while (1)
    {
        if (printer_tcp_server_one_job() == RT_EOK)
        {
            continue;
        };
        rt_thread_mdelay(100);
    }
}

int printer_tcp_server_init(void)
{
    rt_thread_t thread = rt_thread_create("prnd", printer_tcp_server_task, RT_NULL, 2048, 15, 20);
    if (thread == RT_NULL)
    {
        rt_kprintf("start printer tcp server failed\n");
    }

    rt_thread_startup(thread);
    return 0;
}
INIT_APP_EXPORT(printer_tcp_server_init);

功能演示



心得体会
1、芯片的BSP涉及到usb host部分目前遇到bug:某些高速设备进行枚举的时候,会get full configuration descriptor failed,经研究发现当配置描述大于64字节的时候,rtt的usbh协议栈打开的pipo会使用最大每次64字节读一次的方式进行读取,但是bsp则会依据第一次setup传输记录的请求长度进行获取,结果直接返回大于64字节的数据包,导致错误。(https://github.com/RT-Thread/rt-thread/issues/5675
2、设备驱动框架很好的解耦和用户态和内核态之间的调用,基本和linux的架构差不多,初学者也很方便上手。
3、tcp方面是支持sal层的,可以很方便的移植linux下面的socket程序,api也大体一致,学习成本非常低。







使用特权

评论回复
沙发
onlycook| | 2022-6-8 15:02 | 只看该作者
赞一个,挺不错的测评贴

使用特权

评论回复
板凳
天灵灵地灵灵| | 2022-6-8 21:47 | 只看该作者
没看明白,你打印机到底用网线个开发板连接的还是用USB线连接的?

使用特权

评论回复
地板
antusheng| | 2022-6-11 19:49 | 只看该作者
这个是用MCU通过USB控制打印机?

使用特权

评论回复
5
laocuo1142| | 2022-7-18 10:44 | 只看该作者
这个不错,控制串口打印机

使用特权

评论回复
6
稳稳の幸福| | 2022-7-28 18:16 | 只看该作者
赞一个

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:祝大家天天开❤ ///w/// 有问题咨询联系QQ:3326242524

2786

主题

6477

帖子

245

粉丝