source: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/win32/sio.c@ 457

Last change on this file since 457 was 457, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 9.2 KB
Line 
1/*
2 * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
21 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
25 * OF SUCH DAMAGE.
26 *
27 * This file is part of the lwIP TCP/IP stack.
28 *
29 */
30
31#include <lwip/opt.h>
32#include <lwip/sys.h>
33#include <lwip/sio.h>
34
35#include <stdio.h>
36#include <stdarg.h>
37
38#ifdef _MSC_VER
39#pragma warning (push, 3)
40#endif
41#include <windows.h>
42#ifdef _MSC_VER
43#pragma warning (pop)
44#endif
45#include "lwipcfg.h"
46
47/** When 1, use COM ports, when 0, use named pipes (for simulation). */
48#ifndef SIO_USE_COMPORT
49#define SIO_USE_COMPORT 1
50#endif
51
52/** If SIO_USE_COMPORT==1, use COMx, if 0, use a pipe (default) */
53#if SIO_USE_COMPORT
54#define SIO_DEVICENAME "\\\\.\\COM"
55#else
56#define SIO_DEVICENAME "\\\\.\\pipe\\lwip"
57#endif
58
59#if SIO_USE_COMPORT
60#ifndef SIO_COMPORT_SPEED
61#define SIO_COMPORT_SPEED 115200
62#endif
63#ifndef SIO_COMPORT_BYTESIZE
64#define SIO_COMPORT_BYTESIZE 8
65#endif
66#ifndef SIO_COMPORT_STOPBITS
67#define SIO_COMPORT_STOPBITS 0 /* ONESTOPBIT */
68#endif
69#ifndef SIO_COMPORT_PARITY
70#define SIO_COMPORT_PARITY 0 /* NOPARITY */
71#endif
72#endif /* SIO_USE_COMPORT */
73
74static int sio_abort = 0;
75
76/* \\.\pipe\lwip0 */
77/* pppd /dev/ttyS0 logfile mylog debug nocrtscts local noauth noccp ms-dns 212.27.54.252 192.168.0.4:192.168.0.5
78 */
79
80/**
81 * SIO_DEBUG: Enable debugging for SIO.
82 */
83#ifndef SIO_DEBUG
84#define SIO_DEBUG LWIP_DBG_OFF
85#endif
86
87#if SIO_USE_COMPORT
88/** When using a real COM port, set up the
89 * serial line settings (baudrate etc.)
90 */
91static BOOL
92sio_setup(HANDLE fd)
93{
94 COMMTIMEOUTS cto;
95 DCB dcb;
96
97 /* set up baudrate and other communication settings */
98 memset(&dcb, 0, sizeof(dcb));
99 /* Obtain the DCB structure for the device */
100 if (!GetCommState(fd, &dcb)) {
101 return FALSE;
102 }
103 /* Set the new data */
104 dcb.BaudRate = SIO_COMPORT_SPEED;
105 dcb.ByteSize = SIO_COMPORT_BYTESIZE;
106 dcb.StopBits = 0; /* ONESTOPBIT */
107 dcb.Parity = 0; /* NOPARITY */
108 dcb.fParity = 0; /* parity is not used */
109 /* do not use flow control */
110 /*dcb.fOutxDsrFlow = dcb.fDtrControl = 0;
111 dcb.fOutxCtsFlow = dcb.fRtsControl = 0;
112 dcb.fErrorChar = dcb.fNull = 0;
113 dcb.fInX = dcb.fOutX = 0;
114 dcb.XonChar = dcb.XoffChar = 0;
115 dcb.XonLim = dcb.XoffLim = 100;*/
116
117 /* Set the new DCB structure */
118 if (!SetCommState(fd, &dcb)) {
119 return FALSE;
120 }
121
122 memset(&cto, 0, sizeof(cto));
123 if(!GetCommTimeouts(fd, &cto))
124 {
125 return FALSE;
126 }
127 /* change read timeout, leave write timeout as it is */
128 cto.ReadIntervalTimeout = 1;
129 cto.ReadTotalTimeoutMultiplier = 0;
130 cto.ReadTotalTimeoutConstant = 1; /* 1 ms */
131 if(!SetCommTimeouts(fd, &cto)) {
132 return FALSE;
133 }
134
135 return TRUE;
136}
137#endif /* SIO_USE_COMPORT */
138
139/**
140 * Opens a serial device for communication.
141 *
142 * @param devnum device number
143 * @return handle to serial device if successful, NULL otherwise
144 */
145sio_fd_t sio_open(u8_t devnum)
146{
147 HANDLE fileHandle = INVALID_HANDLE_VALUE;
148 CHAR fileName[256];
149 LWIP_DEBUGF(SIO_DEBUG, ("sio_open(%lu)\n", (DWORD)devnum));
150#if SIO_USE_COMPORT
151 snprintf(fileName, 255, SIO_DEVICENAME"%lu", (DWORD)(devnum));
152#else /* SIO_USE_COMPORT */
153 snprintf(fileName, 255, SIO_DEVICENAME"%lu", (DWORD)(devnum & ~1));
154 if ((devnum & 1) == 0) {
155 fileHandle = CreateNamedPipeA(fileName, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_NOWAIT,
156 PIPE_UNLIMITED_INSTANCES, 102400, 102400, 100, NULL);
157 } else
158#endif /* SIO_USE_COMPORT */
159 {
160 fileHandle = CreateFileA(fileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
161 }
162 if (fileHandle != INVALID_HANDLE_VALUE) {
163 sio_abort = 0;
164#if !SIO_USE_COMPORT
165 if (devnum & 1) {
166 DWORD mode = PIPE_NOWAIT;
167 if (!SetNamedPipeHandleState(fileHandle, &mode, NULL, NULL)) {
168 LWIP_DEBUGF(SIO_DEBUG, ("sio_open(%lu): SetNamedPipeHandleState failed. GetLastError() returns %d\n",
169 (DWORD)devnum, GetLastError()));
170 }
171 } else
172#endif /* !SIO_USE_COMPORT */
173 {
174 FlushFileBuffers(fileHandle);
175 }
176#if SIO_USE_COMPORT
177 if(!sio_setup(fileHandle)) {
178 CloseHandle(fileHandle);
179 LWIP_DEBUGF(SIO_DEBUG, ("sio_open(%lu): sio_setup failed. GetLastError() returns %lu\n",
180 (DWORD)devnum, GetLastError()));
181 return NULL;
182 }
183#endif /* SIO_USE_COMPORT */
184 LWIP_DEBUGF(SIO_DEBUG, ("sio_open: file \"%s\" successfully opened.\n", fileName));
185 printf("sio_open: file \"%s\" (%d) successfully opened: 0x%08x\n", fileName, devnum, LWIP_PTR_NUMERIC_CAST(unsigned int, fileHandle));
186 return (sio_fd_t)(fileHandle);
187 }
188 LWIP_DEBUGF(SIO_DEBUG, ("sio_open(%lu) failed. GetLastError() returns %lu\n",
189 (DWORD)devnum, GetLastError()));
190 printf("sio_open(%lu) failed. GetLastError() returns %lu\n",
191 (DWORD)devnum, GetLastError());
192 return NULL;
193}
194
195/**
196 * Sends a single character to the serial device.
197 *
198 * @param c character to send
199 * @param fd serial device handle
200 *
201 * @note This function will block until the character can be sent.
202 */
203void sio_send(u8_t c, sio_fd_t fd)
204{
205 DWORD dwNbBytesWritten = 0;
206 LWIP_DEBUGF(SIO_DEBUG, ("sio_send(%lu)\n", (DWORD)c));
207 while ((!WriteFile((HANDLE)(fd), &c, 1, &dwNbBytesWritten, NULL)) || (dwNbBytesWritten < 1)) {
208 }
209}
210
211/**
212 * Receives a single character from the serial device.
213 *
214 * @param fd serial device handle
215 *
216 * @note This function will block until a character is received.
217 */
218u8_t sio_recv(sio_fd_t fd)
219{
220 DWORD dwNbBytesReadden = 0;
221 u8_t byte = 0;
222 LWIP_DEBUGF(SIO_DEBUG, ("sio_recv()\n"));
223 while ((sio_abort == 0) && ((!ReadFile((HANDLE)(fd), &byte, 1, &dwNbBytesReadden, NULL)) || (dwNbBytesReadden < 1)));
224 LWIP_DEBUGF(SIO_DEBUG, ("sio_recv()=%lu\n", (DWORD)byte));
225 return byte;
226}
227
228/**
229 * Reads from the serial device.
230 *
231 * @param fd serial device handle
232 * @param data pointer to data buffer for receiving
233 * @param len maximum length (in bytes) of data to receive
234 * @return number of bytes actually received - may be 0 if aborted by sio_read_abort
235 *
236 * @note This function will block until data can be received. The blocking
237 * can be cancelled by calling sio_read_abort().
238 */
239u32_t sio_read(sio_fd_t fd, u8_t* data, u32_t len)
240{
241 BOOL ret;
242 DWORD dwNbBytesReadden = 0;
243 LWIP_DEBUGF(SIO_DEBUG, ("sio_read()...\n"));
244 ret = ReadFile((HANDLE)(fd), data, len, &dwNbBytesReadden, NULL);
245 LWIP_DEBUGF(SIO_DEBUG, ("sio_read()=%lu bytes -> %d\n", dwNbBytesReadden, ret));
246 LWIP_UNUSED_ARG(ret);
247 return dwNbBytesReadden;
248}
249
250/**
251 * Tries to read from the serial device. Same as sio_read but returns
252 * immediately if no data is available and never blocks.
253 *
254 * @param fd serial device handle
255 * @param data pointer to data buffer for receiving
256 * @param len maximum length (in bytes) of data to receive
257 * @return number of bytes actually received
258 */
259u32_t sio_tryread(sio_fd_t fd, u8_t* data, u32_t len)
260{
261 /* @todo: implement non-blocking read */
262 BOOL ret;
263 DWORD dwNbBytesReadden = 0;
264 LWIP_DEBUGF(SIO_DEBUG, ("sio_read()...\n"));
265 ret = ReadFile((HANDLE)(fd), data, len, &dwNbBytesReadden, NULL);
266 LWIP_DEBUGF(SIO_DEBUG, ("sio_read()=%lu bytes -> %d\n", dwNbBytesReadden, ret));
267 LWIP_UNUSED_ARG(ret);
268 return dwNbBytesReadden;
269}
270
271/**
272 * Writes to the serial device.
273 *
274 * @param fd serial device handle
275 * @param data pointer to data to send
276 * @param len length (in bytes) of data to send
277 * @return number of bytes actually sent
278 *
279 * @note This function will block until all data can be sent.
280 */
281u32_t sio_write(sio_fd_t fd, u8_t* data, u32_t len)
282{
283 BOOL ret;
284 DWORD dwNbBytesWritten = 0;
285 LWIP_DEBUGF(SIO_DEBUG, ("sio_write()...\n"));
286 ret = WriteFile((HANDLE)(fd), data, len, &dwNbBytesWritten, NULL);
287 LWIP_DEBUGF(SIO_DEBUG, ("sio_write()=%lu bytes -> %d\n", dwNbBytesWritten, ret));
288 LWIP_UNUSED_ARG(ret);
289 return dwNbBytesWritten;
290}
291
292/**
293 * Aborts a blocking sio_read() call.
294 * @todo: This currently ignores fd and aborts all reads
295 *
296 * @param fd serial device handle
297 */
298void sio_read_abort(sio_fd_t fd)
299{
300 LWIP_UNUSED_ARG(fd);
301 LWIP_DEBUGF(SIO_DEBUG, ("sio_read_abort() !!!!!...\n"));
302 sio_abort = 1;
303 return;
304}
Note: See TracBrowser for help on using the repository browser.