# tcp模块 | 状态 |最后更新 | API版本 | | ------ | ------ | ------ | | Active | 2020-06-20 | V1.00.00 | 在`V1.00.45`固件版本后,提供一个用户TCP端口,用于用户程序与用户自己的上位机进行交互。 用途:自动测试系统,自定义数据采集等。 ## 实现概略 表头连接到上位机,用Shizuku Toolbox打开后,Shizuku Toolbox会启动一个TCP端口,您自己的上位机通过这个TCP端口与表头交互,Shizuku Toolbox将转发双向通讯。 ![vcp_implementation](vcp_implementation.png) ## 用户TCP可以做什么 其他lua模块提供了对表头上资源的方便访问,但与外界交互的途径只有按钮,屏幕以及内部存储。部分客户想自己写上位机,并对表头发送命令及读取数据完成定制功能。这就需要一种上位机和用户lua程序的通信渠道,为此,**我们提供一个用户TCP端口实现用户lua程序与用户上位机的双向通信**。 ## 回环测试 在开始您的应用之前,我们应该先确保TCP转发工作正常。请跟随以下步骤进行测试: 如果您还没有安装上位机(即Shizuku Toolbox),请到[上位机下载](https://yk-lab.org:666/index.php/zh/shizuku-pc%e7%ab%af%e8%bd%af%e4%bb%b6/)。 连接表头与计算机(micro口为联机口),运行Shizuku Toolbox,双击设备名称打开表头: ![loopback1](loopback1.png) 点击`Lua脚本`面板页,找到`Lua TCP`: ![loopback2](loopback2.png) 设置好本地TCP端口号(默认1000),点击开始按钮。 ![loopback3](loopback3.png) 在右侧代码区复制以下代码,并按左边的绿色运行按钮运行: ```lua function tcp_callback() tcp.write(tcp.readAll()) end tcp.open() tcp.onReceived(tcp_callback) ``` ![loopback4](loopback10.png) 打开PuTTY,按以下设置(Port号与前面的端口号一致),并点击Open: ![loopback4](loopback4.png) 此时,在PuTTY会话中输入字符,应当收到重复字符(即,输入"abcd"并回车,对方将回复abcd),说明回环测试成功: ![loopback5](loopback5.png) ## tcp.open() ### 描述 打开用户TCP端口,可指定收发缓冲区大小,若未指定,收发缓冲区大小均为64字节。注意,rx与tx是站在表头的角度说的。 ### 参数 | 名称 | 类型 | 范围 | 用途 | | ---------------- | ------ | -------- | ------------------ | | [rx_buffer_size] | number | 1~2^32-1 | 指定接收缓冲区大小 | | [tx_buffer_size] | number| 1~2^32-1 |指定发送缓冲区大小| ### 返回值 nil ### 调用例 ```lua tcp.open() --Open user TCP ``` ## tcp.close() ### 描述 关闭用户TCP端口。 ### 参数 nil ### 返回值 nil ### 调用例 ```lua tcp.close() --Close user TCP ``` ## tcp.read() ### 描述 从TCP端口中读取指定字节数。 ### 参数 | 名称 | 类型 | 范围 | 用途 | | ---------------- | ------ | -------- | ------------------ | | bytesToRead | number | 1~2^32-1 | 希望读取的字节数 | ### 行为 若调用时,接收缓冲区中的字节数大于或等于所指定的`bytesToRead`,则从接收缓冲区中取`bytesToRead`字节并立刻返回。若接收缓冲区中的字节数小于`bytesToRead`,则函数开始等待直到收到`bytesToRead` 为止,若等待时间超过读取超时时间(参见`vcp.setTimeout()`), 则函数返回。 ### 返回值 | 名称 | 类型 | 范围 | 用途 | | ---------------- | ------ | -------- | ------------------ | | content | string | | 读取到的内容 | | actual_size | number | 1~2^32-1 | 实际取到的字节数 | ### 调用例 ```lua packet = tcp.read(20) --Read a packet with length 20. ``` ## tcp.readAll() ### 描述 读取接收缓冲区中的全部内容。 ### 参数 nil ### 行为 读取接收缓冲区中的全部内容。此函数调用后立刻返回,即使接收缓冲区为空(此时返回一个空`string`及`number`0)。 ### 返回值 | 名称 | 类型 | 范围 | 用途 | | ---------- | ------ | -------- | ------------ | | content | string | | 读取到的内容 | | bytesCount | number | 1~2^32-1 | 取到的字节数 | ### 调用例 ```lua packet,actual_size = tcp.readAll() --Read all if(actual_size == 0) begin print("We got nothing.") end ``` ## tcp.write() ### 描述 向串口写入内容。 ### 参数 | 名称 | 类型 | 范围 | 用途 | | ---------------- | ------ | -------- | ------------------ | | content | string | 1~2^32-1 | 要发送的内容 | ### 行为 若调用时,发送缓冲区的空闲空间足够,则将发送内容写入发送缓冲区并立刻返回。若发送缓冲区的空闲空间不够,则等待发送缓冲区空闲,并装入数据,直到内容发送完为止。若等待时间超过发送超时时间(参见`tcp.setTimeout()`), 则函数返回。 ### 返回值 | 名称 | 类型 | 范围 | 用途 | | ---------------- | ------ | -------- | ------------------ | | actual_size | number | 1~2^32-1 | 实际发送出的字节数 | ### 调用例 ```lua tcp.write("Hello World!!") ``` ## tcp.bytesToRead() ### 描述 获取接收缓冲区中的数据的字节数。 ### 参数 nil ### 返回值 | 名称 | 类型 | 范围 | 用途 | | ----------- | ------ | -------- | ------------------------ | | bytesToRead | number | 1~2^32-1 | 接收缓冲区中数据的字节数 | ### 调用例 ```lua byteCount = tcp.bytesToRead() --Get size of data in rx FIFO data = tcp.read(byteCount) --Read out data ``` ## tcp.bytesToWrite() ### 描述 获取发送缓冲区中尚未发送完毕的数据的字节数。 ### 参数 nil ### 返回值 | 名称 | 类型 | 范围 | 用途 | | ------------ | ------ | -------- | -------------------------------------- | | bytesToWrite | number | 1~2^32-1 | 发送缓冲区中尚未发送完毕的数据的字节数 | ### 调用例 ```lua if(tcp.bytesToWrite() > 0) then tcp.flushTx() end ``` ## tcp.rxOverflow() ### 描述 检查接收缓冲区是否溢出。 ### 参数 nil ### 返回值 | 名称 | 类型 | 范围 | 用途 | | ---------- | ------- | ---- | ------------------ | | overflowed | boolean | | 接收缓冲区是否溢出 | ### 调用例 ```lua if(tcp.rxOverflow()) then print("Oh shit, we are in trouble.") end ``` ## tcp.setTimeout() ### 描述 设置发送超时时间及接收超时时间。同时请参见`tcp.read()`与`tcp.write()`的行为。未调用此函数时,默认的发送超时时间及接收超时时间均为500ms。 ### 参数 | 名称 | 类型 | 范围 | 用途 | | ------------- | ------ | -------- | ---------------------- | | read_timeout | number | 1~2^32-1 | 指定接收超时时间(毫秒) | | write_timeout | number | 1~2^32-1 | 指定发送超时时间(毫秒) | ### 返回值 nil ### 调用例 ```lua tcp.setTimeout(1000,1000) --Set read & write timeout to 1000ms. ``` ## tcp.flushTx() ### 描述 清除发送缓冲区中的内容。 ### 参数 nil ### 返回值 nil ### 调用例 ```lua tcp.flushTx() ``` ## tcp.flushRx() ### 描述 清除接收缓冲区中的内容。 ### 参数 nil ### 返回值 nil ### 调用例 ```lua tcp.flushRx() ``` ## tcp.isOpen() ### 描述 检查TCP端口是否已打开。 ### 参数 nil ### 返回值 | 名称 | 类型 | 范围 | 用途 | | ---- | ------- | ---- | ---------- | | open | boolean | | 是否已打开 | ### 调用例 ```lua if(~tcp.isOpen()) then tcp.open() end ``` ## tcp.onReceived() ### 描述 设置接收到数据时的回调函数。 ### 参数 | 名称 | 类型 | 范围 | 用途 | | -------- | -------- | ---- | ------------ | | callback | function | | 指定回调函数 | | [threshold] | number | | 指定触发回调函数时接收缓冲区中的字节数 | ### 行为 设置接收到数据时的回调函数。指定后,一旦接收缓冲区中的数据的字节数大于或等于`threshold`,回调函数`callback`将被调用。若未指定`threshold`,默认触发字节数为1。 ### 提示 用户需要在回调函数中用`tcp.read()`或`tcp.readAll()`读取收到的内容,否则触发条件一直成立,将反复进入回调函数。 ### 返回值 nil ### 调用例 ```lua function tcp_callback() tcp.write(tcp.readAll()) end tcp.open() tcp.onReceived(tcp_callback) ```