Serial to USB를 장착하게 되면 윈도우는 자동으로 사용하지 않는 빈 포트를 할당하게 된다. 그리고 해당 Serial to USB가 장착되어 있으면 장치관리자에서 원하는 포트로 재할당이 가능하고 삭제도 가능하다. 하지만 여기서 문제점은 해당 Serial to USB가 없으면 삭제 및 다른 포트로 할당이 불가능하다는 점이다. 그리고 다른 Serial to USB를 장착하게 되면 이미 선점되어 있는 포트를 제외한 포트에 할당이 된다.

이 글에서 해결을 하려는 점은 포트는 할당되어 있지만, 사용하지 않는 포트를 지우고자 하는 것이다. 보통은 문제가 생기지 않을 수도 있지만, 시리얼을 사용하는 프로그램에서 시리얼을 1번까지부터 9번까지만 인식하는 경우가 있다. 이러한 경우 1번부터 9번까지 포트가 선점되어 있다면 새로운 Serial to USB를 장착할 경우 10번 포트가 할당되게 된다. 그러므로 프로그램에서는 인식을 할 수가 없다.

이러한 경우 등등등을 위해 사용하지 않는 시리얼 포트를 지우는 방법에 대해서 찾아보았다. 구글링을 검색한 결과 삭제법이 나오나 영어로 되어 있어 필요한 사항만을 간단히 적어보도록 하겠다.

1. 윈도우 키 + R or 시작 > 실행

2. 명령 프롬프트> set devmgr_show_nonpresent_devices=1
  a. 에코는 없음

3. 명령 프롬프트> start devmgmt.msc
  a. 에코는 없음

  b. 장치 관리자가 뜸

4. 장치 관리자 > 보기 > 숨김 장치 표시
  a. 선택 체크

5. 포트에서 삭제하고자하는 포트에 오른쪽 마우스 버튼을 눌러 제거를 선택
AND

AHAV9302를 reset하면 u-boot로 부팅을 시작하지만 리눅스가 부팅되지는 않는다. 왜냐하면, uImage, rImage를 지워버렸기 때문이다. 엄마 몰래 리눅스 포팅 강좌에 보면 tftp로 다운받는 방법이 나온다. 물론 그 방법이 편리하고 속도도 빠르기 때문에 권장을 하고 있다. 하지만 본인은 마이너한 걸 좋아하므로 시리얼 다운로드를 해보도록 한다.

u-boot의 문서를 확인해 본 결과 C-Kermit를 사용하기에 본인도 동일한 프로그램을 설치하여 사용하였다. http://www.denx.de/wiki/view/DULG/SystemSetup#Section_4.3. 에 보면 설정법이 나와 있다. 자신의 환경에 맞게 동일하게 설정한다. 본인의 설정을 보자면 ~/.kermrc 부분에서 set line /dev/ttyUSB0을 수정하였다.

1. $kermit
2. C-Kermit>connect
보드랑 PC를 연결한다(minicom과 같은 역할)
프로그램을 실행하여 기본적인 환경을 셋팅한다.
AHAV9302> setenv baudrate 115200
AHAV9302> setenv hostname apple
AHAV9302> setenv bootdelay 3
AHAV9302> setenv ethaddr 00:60:6E:F0:00:02
AHAV9302> setenv ipaddr 192.168.100.182
AHAV9302> setenv netmask 255.255.255.0
AHAV9302> setenv gatewayip 192.168.100.254
AHAV9302> setenv dnsip 203.255.112.34
AHAV9302> setenv dnsip2 192.135.250.69
AHAV9302> setenv serverip 192.168.100.250
AHAV9302> setenv bootfile "uImage"
AHAV9302> setenv kfaddr 0x60100000
AHAV9302> setenv rfaddr 0x60300000
AHAV9302> setenv kraddr 0xc3000000
AHAV9302> setenv rraddr 0xc2000000
AHAV9302> setenv iraddr 0xc0800000
AHAV9302> setenv bootargs console=ttyAM0,$(baudrate) root=/dev/ram rw initrd=$(iraddr) ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off init=/sbin/init
AHAV9302> setenv bootcmd 'cp.b $(kfaddr) $(kraddr) $(kisize); cp.b $(rfaddr) $(rraddr) $(risize); bootm $(kraddr) $(rraddr)'

AHAV9302> saveenv

기본적인 환경설정을 마친 뒤, uImage와 rImage를 다운로드 한다.
AHAV9302> protect off 0x60100000 0x602fffff
AHAV9302> erase 0x60100000 0x602fffff
AHAV9302> loadb 0xc0000000
kermit으로 램의 0xc0000000에 저장한다.
CTRL를 누른채 \, c 키 두 개를 순서대로 누르면 kermit 명령모드로 빠진다.
3. C-Kermit>send /bin uImage
램으로 uImage파일을 다운로드한다.
4. C-Kermit>connect
Total Size와 시작 주소를 표시해 준다.
이제 램으로 복사를 한다.
5. AHAV9302> cp.b 0xc0000000 0x60100000 $(filesize)
램의 0xc0000000에서 NOR의 0x60100000으로 파일의 크기만큼 복사한다.
AHAV9302> setenv kisize $(filesize)
AHAV9302> protect on 0x60100000 0x602fffff

AHAV9302> protect off 0x60300000 0x606fffff
AHAV9302> erase 0x60300000 0x606fffff
AHAV9302> loadb 0xc3000000
kermit으로 램의 0xc3000000에 저장한다.
CTRL를 누른채 \, c 키 두 개를 순서대로 누르면 kermit 명령모드로 빠진다.
3. C-Kermit>send /bin rImage
램으로 rImage파일을 다운로드한다.
4. C-Kermit>connect
Total Size와 시작 주소를 표시해 준다.
이제 램으로 복사를 한다.
5. AHAV9302> cp.b 0xc3000000 0x60300000 $(filesize)
램의 0xc3000000에서 NOR의 0x60300000으로 파일의 크기만큼 복사한다.
AHAV9302> setenv risize $(filesize)
AHAV9302> protect on 0x60300000 0x606fffff

AHAV9302> saveenv

AHAV9302> iminfo 0x60100000
AHAV9302> iminfo 0x60300000

AHAV9302> reset

정상적으로 리눅스 부팅까지 된다. 성공적이다.

AND

AHAV9302보드의 MCU는 시리얼 다운로드를 지원한다. 그래서 JTAG 장비를 사지않더라도 저렴한 시리얼 케이블로 바이너리파일을 다운로드 할 수 있다.

엄마 몰래 리눅스 포팅강좌에는 u-boot에 대한 다운로드 방법이 간단해서인지 다운로드에 대한 자세한 사항이 없다. 그래서 직접 u-boot를 다운로드 해보기로 하였다.

(아마도 기본적으로 순대국밥님께서 미리 u-boot, uImage, rImage를 미리 다운로드 해놓아서 그런지도 모르겠다)

우선 본인은 VMWARE에서 우분투 9.04에 커널 2.6.28-14-generic를 사용하고 있다. 그리고 USB to SERIAL 컨버터를 사용하여 보드와 연결해서 사용중이다. 초기 다운로드는 랜으로 다운로드 할 수 없고, 무조건 시리얼 다운로드만 사용된다.(물론 JTAG는 제외된다)

기본적으로 설치되어 있는 NOR 메모리의 내용을 지워보기로 한다.

1. $minicom
본인은 USB to SERIAL를 사용하고 있으므로 minicom의 설정을 바꿨다. 우선 USB to SERIAL를 연결하면 자동으로 시리얼 장치로 인식이 되었다. 그리고 $ls /dev|grep USB를 해본 결과 ttyUSB0으로 나타났다. ttyUSB0을 사용하여야 하므로 minicom에서 CTRL-A O를 눌러 설정화면으로 들어간다. 그리고 Serial port setup를 선택하여 설정을 하였다. A - Serial Device에 있는 값을 /dev/ttyUSB0을 변경한다. 그리고 E - Bps/Par/Bits를 선택하면 다시 Speed를 설정할 수 있는데 115200으로 선택한다. 그리고 저장을 하고 설정화면을 빠져나간다. 이로써 기본적인 minicom에 대한 설정은 마쳤다.

보드를 리셋하게 되면 기본적으로 u-boot가 동작을 하게 되고 임베디드 리눅스를 부팅한다. 하지만!! NOR 메모리의 내용을 지우고 처음부터 다운로드하는 과정을 하기로 하였으므로 리셋을 하고 난 뒤 Hit any key to stop autoboot 부분에서 아무키나 눌러서 부팅을 멈추고 u-boot로 들어간다.
2. AHAV9302> protect off 60000000 60ffffff
3. AHAV9302> erase 60000000 60ffffff
u-boot, uImage, rImage부분을 protect on 되어 있으므로 NOR을 지우기 위해 protect를 해제한다. 그리고 NOR 모두를 지운다. 16진수 값으로 저 범위의 값은 0x1000000이다. 이는 16MB의 값을 가지므로 NOR을 모두 보호해제하고 지운다는 뜻이 된다. 이제는 리셋을 해보아도 부팅이 되지 않는다. 왜!! 모두 날라가 버렸기 때문이다.

지금부터 u-boot의 시리얼 다운로드를 해보기로 한다.
http://arm.cirrus.com/files/index.php?path=download/ 에서 Download_1-0-5.tar.gz를 다운로드 받고 압축을 풀자. 하위 디렉토리에 리눅스용 download가 바로 시리얼 다운로드 툴이다.
4. $./download -p USB0 u-boot.bin
본인은 USB to Serial을 사용하므로 -p 옵셥을 붙여서 포트를 따로 설정해주었다. 그리고 u-boot.bin은 당근이 강좌에 있는 u-boot, kernel, ramdisk 이미지입니다라는 글에 있는 base.zip을 받아서 압축을 풀어보면 그 안에 있다.
위의 명령을 실행시키면 USB to Serial 포트를 확인 한 뒤 시리얼 다운로드 모드가 될 때까지 기다리게 된다. 보드에 있는 BOOT버튼을 누르고 /POR버튼을 누른 뒤 떼면 다운로드를 시작한다. 혹시 동작하지 않으면 보드의 전원을 끄고 다시 연결해서 재시도해 본다.

AND

'당근이의 AVR 갖구 놀기'(이하 당근이)는 AVR을 한 번 만져본 사람이라면 누구나 한번씩은 방문해봤을 만큼 유명한 네이버 카페 중 하나이다.

처음에는 AVR에 관한 질의가 있어서 찾게 되었고, 많은 부분에 대한 문제해결을 본 게 계기가 되어 내게는 네이버에서 가장 즐겨찾는 카페중 하나가 되었다.
그리고, 현재는 엄마 몰래 리눅스 포팅이라는 강좌를 알게 되어서 자주 들락날락 거리고 있는 중이다.

학부 4학년때 처음으로 임베디드 리눅스에 대한 수업을 듣고 임베디드에 대해 관심을 가지게 되었다. 하지만 그 이후에는 고가의 관련장비도 문제거니와, 다른 프로젝트에 심혈을 기울이고 있는터라, 한동안 잊게 되었다.

그렇게 시간은 흘렀고, 현재 백수로 있는 동안 프로그래밍에 대한 감도 떨어지는 것 같아서 엄마 몰래 리눅스 포팅이라는 강좌를 계기로 다시금 관심분야에 대한 눈을 돌리고자 한다.

AND

vmware에서 usb-to-serial을 사용할 경우.
(본인은 vmware v5에 ubuntu 8.10을 설치한 상태)
WindowsXP의 경우는 usb-to-serial을 사용할 경우 가상 포트로 COMn이 잡히게 되어
Linux도 동일하게 가상포트로 잡히는 걸로 생각하였다.
(Windows COM1 == Linux ttyS0 과 동일하다
Windows의 경우 1부터 시작하나 Linux는 0부터 시작하게 된다. 0앞의 S는 serial을 뜻함)
하지만 Linux는 ttyUSB0으로 인식되었다.
(minicom에서 포트를 ttyS0 부터 계속 인식시켜서 안되길래
인터넷을 검색해본 결과 usb-to-serial은 ttyUSBn으로 인식된다는 것을 알았다)

minicom 에서 usb-to-serial은 ttyUSBn으로 할 것!!
AND

serial.h

embedded/AT89S52 2006. 12. 15. 15:08

// Serial.h - Definition of the CSerial class
//
// Copyright (C) 1999-2003 Ramon de Klein (Ramon.de.Klein@ict.nl)
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


#ifndef __SERIAL_H
#define __SERIAL_H


//////////////////////////////////////////////////////////////////////
// The SERIAL_DEFAULT_OVERLAPPED defines if the default open mode uses
// overlapped I/O. When overlapped I/O is available (normal Win32
// platforms) it uses overlapped I/O. Windows CE doesn't allow the use
// of overlapped I/O, so it is disabled there by default.

#ifndef SERIAL_DEFAULT_OVERLAPPED
#ifndef SERIAL_NO_OVERLAPPED
#define SERIAL_DEFAULT_OVERLAPPED true
#else
#define SERIAL_DEFAULT_OVERLAPPED false
#endif
#endif


//////////////////////////////////////////////////////////////////////
//
// CSerial - Win32 wrapper for serial communications
//
// Serial communication often causes a lot of problems. This class
// tries to supply an easy to use interface to deal with serial
// devices.
//
// The class is actually pretty ease to use. You only need to open
// the COM-port, where you need to specify the basic serial
// communication parameters. You can also choose to setup handshaking
// and read timeout behaviour.
//
// The following serial classes are available:
//
// CSerial      - Serial communication support.
// CSerialEx    - Serial communication with listener thread for events
// CSerialSync  - Serial communication with synchronized event handler
// CSerialWnd   - Asynchronous serial support, which uses the Win32
//                message queue for event notification.
// CSerialMFC   - Preferred class to use in MFC-based GUI windows.
//
//
// Pros:
// -----
// - Easy to use (hides a lot of nasty Win32 stuff)
// - Fully ANSI and Unicode aware
//
// Cons:
// -----
//  - Little less flexibility then native Win32 API, however you can
//    use this API at the same time for features which are missing
//    from this class.
//  - Incompatible with Windows 95 or Windows NT v3.51 (or earlier),
//    because CancelIo isn't support on these platforms. Define the
//   SERIAL_NO_CANCELIO macro for support of these platforms as
//   well. When this macro is defined, then only time-out values of
//   0 or INFINITE are valid.
//
//
// Copyright (C) 1999-2003 Ramon de Klein
//                         (Ramon.de.Klein@ict.nl)

class CSerial
{
// Class enumerations
public:
// Communication event
typedef enum
{
 EEventUnknown      = -1,   // Unknown event
 EEventNone      = 0,    // Event trigged without cause
 EEventBreak     = EV_BREAK,  // A break was detected on input
 EEventCTS       = EV_CTS,  // The CTS signal changed state
 EEventDSR       = EV_DSR,  // The DSR signal changed state
 EEventError     = EV_ERR,  // A line-status error occurred
 EEventRing      = EV_RING,  // A ring indicator was detected
 EEventRLSD      = EV_RLSD,  // The RLSD signal changed state
 EEventRecv      = EV_RXCHAR,  // Data is received on input
 EEventRcvEv     = EV_RXFLAG,  // Event character was received on input
 EEventSend     = EV_TXEMPTY, // Last character on output was sent
 EEventPrinterError = EV_PERR,  // Printer error occured
 EEventRx80Full    = EV_RX80FULL, // Receive buffer is 80 percent full
 EEventProviderEvt1 = EV_EVENT1,  // Provider specific event 1
 EEventProviderEvt2 = EV_EVENT2,  // Provider specific event 2
}
EEvent;

// Baudrate
typedef enum
{
 EBaudUnknown = -1,   // Unknown
 EBaud110     = CBR_110,  // 110 bits/sec
 EBaud300     = CBR_300,  // 300 bits/sec
 EBaud600     = CBR_600,  // 600 bits/sec
 EBaud1200    = CBR_1200, // 1200 bits/sec
 EBaud2400    = CBR_2400, // 2400 bits/sec
 EBaud4800    = CBR_4800, // 4800 bits/sec
 EBaud9600    = CBR_9600, // 9600 bits/sec
 EBaud14400   = CBR_14400, // 14400 bits/sec
 EBaud19200   = CBR_19200, // 19200 bits/sec (default)
 EBaud38400   = CBR_38400, // 38400 bits/sec
 EBaud56000   = CBR_56000, // 56000 bits/sec
 EBaud57600   = CBR_57600, // 57600 bits/sec
 EBaud115200  = CBR_115200, // 115200 bits/sec
 EBaud128000  = CBR_128000, // 128000 bits/sec
 EBaud256000  = CBR_256000, // 256000 bits/sec
}
EBaudrate;

// Data bits (5-8)
typedef enum
{
 EDataUnknown = -1,   // Unknown
 EData5       =  5,   // 5 bits per byte
 EData6       =  6,   // 6 bits per byte
 EData7       =  7,   // 7 bits per byte
 EData8       =  8   // 8 bits per byte (default)
}
EDataBits;

// Parity scheme
typedef enum
{
 EParUnknown = -1,   // Unknown
 EParNone    = NOPARITY,  // No parity (default)
 EParOdd     = ODDPARITY, // Odd parity
 EParEven    = EVENPARITY, // Even parity
 EParMark    = MARKPARITY, // Mark parity
 EParSpace   = SPACEPARITY // Space parity
}
EParity;

// Stop bits
typedef enum
{
 EStopUnknown = -1,   // Unknown
 EStop1       = ONESTOPBIT, // 1 stopbit (default)
 EStop1_5     = ONE5STOPBITS,// 1.5 stopbit
 EStop2       = TWOSTOPBITS // 2 stopbits
}
EStopBits;

// Handshaking
typedef enum
{
 EHandshakeUnknown  = -1, // Unknown
 EHandshakeOff   =  0, // No handshaking
 EHandshakeHardware  =  1, // Hardware handshaking (RTS/CTS)
 EHandshakeSoftware  =  2 // Software handshaking (XON/XOFF)
}
EHandshake;

// Timeout settings
typedef enum
{
 EReadTimeoutUnknown  = -1, // Unknown
 EReadTimeoutNonblocking =  0, // Always return immediately
 EReadTimeoutBlocking =  1 // Block until everything is retrieved
}
EReadTimeout;

// Communication errors
typedef enum
{
 EErrorUnknown = 0,   // Unknown
 EErrorBreak   = CE_BREAK, // Break condition detected
 EErrorFrame   = CE_FRAME, // Framing error
 EErrorIOE     = CE_IOE,  // I/O device error
 EErrorMode    = CE_MODE, // Unsupported mode
 EErrorOverrun = CE_OVERRUN, // Character buffer overrun, next byte is lost
 EErrorRxOver  = CE_RXOVER, // Input buffer overflow, byte lost
 EErrorParity  = CE_RXPARITY,// Input parity error
 EErrorTxFull  = CE_TXFULL // Output buffer full
}
EError;

// Port availability
typedef enum
{
 EPortUnknownError = -1,  // Unknown error occurred
 EPortAvailable    =  0,  // Port is available
 EPortNotAvailable =  1,  // Port is not present
 EPortInUse        =  2  // Port is in use

}
EPort;

// Construction
public:
CSerial();
virtual ~CSerial();

// Operations
public:
// Check if particular COM-port is available (static method).
static EPort CheckPort (LPCTSTR lpszDevice);

// Open the serial communications for a particular COM port. You
// need to use the full devicename (i.e. "COM1") to open the port.
// It's possible to specify the size of the input/output queues.
virtual LONG Open (LPCTSTR lpszDevice, DWORD dwInQueue = 0, DWORD dwOutQueue = 0, bool fOverlapped = SERIAL_DEFAULT_OVERLAPPED);

// Close the serial port.
virtual LONG Close (void);

// Setup the communication settings such as baudrate, databits,
// parity and stopbits. The default settings are applied when the
// device has been opened. Call this function if these settings do
// not apply for your application. If you prefer to use integers
// instead of the enumerated types then just cast the integer to
// the required type. So the following two initializations are
// equivalent:
//
//   Setup(EBaud9600,EData8,EParNone,EStop1)
//
// or
//
//   Setup(EBaudrate(9600),EDataBits(8),EParity(NOPARITY),EStopBits(ONESTOPBIT))
//
// In the latter case, the types are not validated. So make sure
// that you specify the appropriate values.
virtual LONG Setup (EBaudrate eBaudrate = EBaud9600,
     EDataBits eDataBits = EData8,
     EParity   eParity   = EParNone,
     EStopBits eStopBits = EStop1);

// Set/clear the event character. When this byte is being received
// on the serial port then the EEventRcvEv event is signalled,
// when the mask has been set appropriately. If the fAdjustMask flag
// has been set, then the event mask is automatically adjusted.
virtual LONG SetEventChar (BYTE bEventChar, bool fAdjustMask = true);

// Set the event mask, which indicates what events should be
// monitored. The WaitEvent method can only monitor events that
// have been enabled. The default setting only monitors the
// error events and data events. An application may choose to
// monitor CTS. DSR, RLSD, etc as well.
virtual LONG SetMask (DWORD dwMask = EEventBreak|EEventError|EEventRecv);

// The WaitEvent method waits for one of the events that are
// enabled (see SetMask).
virtual LONG WaitEvent (LPOVERLAPPED lpOverlapped = 0, DWORD dwTimeout = INFINITE);

// Setup the handshaking protocol. There are three forms of
// handshaking:
//
// 1) No handshaking, so data is always send even if the receiver
//    cannot handle the data anymore. This can lead to data loss,
//    when the sender is able to transmit data faster then the
//    receiver can handle.
// 2) Hardware handshaking, where the RTS/CTS lines are used to
//    indicate if data can be sent. This mode requires that both
//    ports and the cable support hardware handshaking. Hardware
//    handshaking is the most reliable and efficient form of
//    handshaking available, but is hardware dependant.
// 3) Software handshaking, where the XON/XOFF characters are used
//    to throttle the data. A major drawback of this method is that
//    these characters cannot be used for data anymore.
virtual LONG SetupHandshaking (EHandshake eHandshake);

// Read operations can be blocking or non-blocking. You can use
// this method to setup wether to use blocking or non-blocking
// reads. Non-blocking reads is the default, which is required
// for most applications.
//
// 1) Blocking reads, which will cause the 'Read' method to block
//    until the requested number of bytes have been read. This is
//    useful if you know how many data you will receive.
// 2) Non-blocking reads, which will read as many bytes into your
//    buffer and returns almost immediately. This is often the
//    preferred setting.
virtual LONG SetupReadTimeouts (EReadTimeout eReadTimeout);

// Obtain communication settings
virtual EBaudrate  GetBaudrate    (void);
virtual EDataBits  GetDataBits    (void);
virtual EParity    GetParity      (void);
virtual EStopBits  GetStopBits    (void);
virtual EHandshake GetHandshaking (void);
virtual DWORD      GetEventMask   (void);
virtual BYTE       GetEventChar   (void);

// Write data to the serial port. Note that we are only able to
// send ANSI strings, because it probably doesn't make sense to
// transmit Unicode strings to an application.
virtual LONG Write (const void* pData, size_t iLen, DWORD* pdwWritten = 0, LPOVERLAPPED lpOverlapped = 0, DWORD dwTimeout = INFINITE);
virtual LONG Write (LPCSTR pString, DWORD* pdwWritten = 0, LPOVERLAPPED lpOverlapped = 0, DWORD dwTimeout = INFINITE);

// Read data from the serial port. Refer to the description of
// the 'SetupReadTimeouts' for an explanation about (non) blocking
// reads and how to use this.
virtual LONG Read (void* pData, size_t iLen, DWORD* pdwRead = 0, LPOVERLAPPED lpOverlapped = 0, DWORD dwTimeout = INFINITE);

// Send a break
LONG Break (void);

// Determine what caused the event to trigger
EEvent GetEventType (void);

// Obtain the error
EError GetError (void);

// Obtain the COMM and event handle
HANDLE GetCommHandle (void)  { return m_hFile; }

// Check if com-port is opened
bool IsOpen (void) const  { return (m_hFile != 0); }

// Obtain last error status
LONG GetLastError (void) const { return m_lLastError; }

// Obtain CTS/DSR/RING/RLSD settings
bool GetCTS (void);
bool GetDSR (void);
bool GetRing (void);
bool GetRLSD (void);

// Purge all buffers
LONG Purge (void);

protected:
// Internal helper class which wraps DCB structure
class CDCB : public DCB
{
public:
 CDCB() { DCBlength = sizeof(DCB); }
};

// Attributes
protected:
LONG m_lLastError;  // Last serial error
HANDLE m_hFile;   // File handle
EEvent m_eEvent;   // Event type
DWORD m_dwEventMask;  // Event mask

#ifndef SERIAL_NO_OVERLAPPED
HANDLE m_hevtOverlapped; // Event handle for internal overlapped operations
#endif

protected:
// Check the requirements
void CheckRequirements (LPOVERLAPPED lpOverlapped, DWORD dwTimeout) const;

// CancelIo wrapper (for Win95 compatibility)
BOOL CancelCommIo (void);
};

#endif // __SERIAL_H

AND