Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
tcp
USB主机_host
nuc980
NK-980IOT测评之网络USB打印机测试
5.00
发布于 2022-03-16 23:55:12 浏览:1610
订阅该版
一、功能模块的硬件介绍 新唐NK-980IOT开发板核心搭载了NUC980DR61YC 的ARM9处理器,主频最高300M,并且芯片集成了64 MB的DRAM,外设接口包由物联网常用的数据通讯接口,比如以太网接口、USB 2.0高速接口、RS-485总线、CAN 总线、SPI接口、通用GPIO、硬件加速等等,开发板官方也支持许多操作系统,比如rt-thread、linux、freertos、openwrt等等,资料文档也非常齐全。 ![image.png](https://oss-club.rt-thread.org/uploads/20220315/b089c4c8448f38b6c9e3c81fd4b563d4.png.webp) ![image.png](https://oss-club.rt-thread.org/uploads/20220315/dbb3817e58613368c626adc317572e5f.png.webp) ![image.png](https://oss-club.rt-thread.org/uploads/20220315/6d6b1e2e94dfbff2cd9cb1717f21e0a0.png.webp) 二、功能模块的使用说明 开发板包装非常简约,里面打开了就可以看到主板本体 ![image.png](https://oss-club.rt-thread.org/uploads/20220315/20414e8ae7ac4d9f59cb600159c86c68.png.webp) 随便找了根usb micro的数据线,接到开发板的烧写端口(板子上一共有2 个 micro usb 接口,一个用于是连接到 nuc980 usb,可以用于给 nuc980 下载固件,还有一个USB是连接到板子上的 USB 转 TTL,可以用于调试,把NUC980 设置为 USB 启动进入下载模式) ![image.png](https://oss-club.rt-thread.org/uploads/20220315/0a52ff4c3619cafa0b2d2470f01eb7a5.png.webp) 此时电脑出现usb设备发现,但是缺少驱动的提示 ![image.png](https://oss-club.rt-thread.org/uploads/20220315/b97aa76fc3e90123095af6d36363e0fb.png.webp) 下载https://github.com/OpenNuvoton/NUC980_NuWriter 安装WinUSB4NuVCOM.exe ![image.png](https://oss-club.rt-thread.org/uploads/20220315/1c92f6178dc76f00309393355039adfd.png.webp) 打开NuWriter\NuWriter\Release\NuWriter.exe 这样就可以对开发板进行各种类型的烧写了 ![image.png](https://oss-club.rt-thread.org/uploads/20220315/f121394f741bf2922eb54f63e0cde432.png.webp) 打开RT-Thread Stduio,安装980开发板相对应的开发包,新建工程进行编译 ![image.png](https://oss-club.rt-thread.org/uploads/20220315/15ab7e07369619772ffad6ed31d7fd85.png) 开发板的主板sw1跳线到usb启动,使用nuwiter进行下载 ![image.png](https://oss-club.rt-thread.org/uploads/20220315/371465d40fd40233bfd22cd768e3e985.png) 成功运行rt-thread ![image.png](https://oss-club.rt-thread.org/uploads/20220315/3c94b956485c700900e6c496e5330d1f.png) 三、rt-thread开发 1、参考linux的usb打印机驱动,移植进rt-thread,增加配置项 ![image.png](https://oss-club.rt-thread.org/uploads/20220316/2c8904c83bf6d2da63d7daae4c337b8a.png) 可以成功发现识别usb打印机 ![image.png](https://oss-club.rt-thread.org/uploads/20220316/29ac42d77545139a0e28c39d1d331313.png) 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); ``` 四、功能演示 ![image.png](https://oss-club.rt-thread.org/uploads/20220316/3a8532c84a13e861f784c4f66ac00efc.jpg.webp) ![image.png](https://oss-club.rt-thread.org/uploads/20220316/8746be9f403c387f99dd5150391cefb6.jpg.webp) 视频: https://www.bilibili.com/video/BV15R4y1F7w2/ 代码: https://github.com/CEC0D5F1B6AB/nk-980iot_usb_printer.git 五、心得体会 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也大体一致,学习成本非常低。
5
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
cec0d5f1b6ab
这家伙很懒,什么也没写!
文章
1
回答
0
被采纳
0
关注TA
发私信
相关文章
1
freemodbus tcp
2
stm32f103 LWIP 2.0.2 TCP收发问题
3
AT_DEVICE TCP 接收大文件失败!
4
RT thread freemobus tcp通讯问题
5
hard fault on thread: tcpip
6
RT系统TCP收数据速度慢
7
TCP Client 断线重连
8
TCP数据包多包重合的问题
9
rtthread simulator中能够使用WIN10中得TCP/IP服务吗
10
lwip 跨网段ping不通的问题
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
I2C_IIC
ESP8266
UART
WIZnet_W5500
ota在线升级
cubemx
PWM
flash
freemodbus
BSP
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
编译报错
中断
Debug
rt_mq_消息队列_msg_queue
SFUD
msh
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
xusiwei1236
8
个答案
2
次被采纳
踩姑娘的小蘑菇
1
个答案
2
次被采纳
用户名由3_15位
9
个答案
1
次被采纳
bernard
4
个答案
1
次被采纳
RTT_逍遥
3
个答案
1
次被采纳
本月文章贡献
聚散无由
2
篇文章
15
次点赞
catcatbing
2
篇文章
5
次点赞
Wade
2
篇文章
4
次点赞
Ghost_Girls
1
篇文章
7
次点赞
xiaorui
1
篇文章
2
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部