01.01.2015 Views

¦þ¹ ¼³¾Šł

¦þ¹ ¼³¾Šł

¦þ¹ ¼³¾Šł

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Êîäèíã<br />

C/C++: ÐÀÁÎÒÀÅÌ Ñ COM-ÏÎÐÒÎÌ<br />

Íèêîëàé «GîrluM» Àíäðååâ (gorlum@real.xakep.ru)<br />

Âõîäèò è<br />

Âûõîäèò....<br />

Ðàáîòàåì ñ COM-ïîðòîì<br />

Äàâíûì-äàâíî, âî âðåìåíà ñòàðîãî äîáðîãî DOS`à, ðàáîòàòü ñ õàðäâàðîì áûëî ãîðàçäî ïðîùå.<br />

Âçÿòü, íàïðèìåð, óïðàâëåíèå êîììóíèêàöèîííûìè ïîðòàìè. Ïðîãðàììû òîãäà èñïîëüçîâàëè<br />

ïðåðûâàíèÿ è îáùàëèñü ñ óñòðîéñòâàìè íàïðÿìóþ (ýòî áûëî íàñòîÿùåå ðàçäîëüå<br />

âèðìåéêåðàì). Ñ òåõ ïîð ìíîãîå ïåðåìåíèëîñü. Íà ñìåíó ÄÎÑó ïðèøëè âèíäû, à ñ íèìè è<br />

íîâûå ïðàâèëà. Òåïåðü ïðîãðàììû, ðàáîòàþùèå â Windows, îáùàþòñÿ ñ óñòðîéñòâîì íå íàïðÿìóþ,<br />

à ÷åðåç ñïåöèàëüíûå WinAPI ôóíêöèè. Âîò ýòè ñàìè WinAPI ôóíêöèè ìû ñåãîäíÿ è<br />

áóäåì èçó÷àòü. Ðàçáåðåì ðàáîòó ñ COM-ïîðòîì, à â êà÷åñòâå ïðèìåðà íàïèøåì ïðîñòåíüêóþ<br />

òåðìèíàëüíóþ ïðîãðàììó äëÿ ìîäåìà ñ ïðîñòûì è êðàñèâûì ãðàôè÷åñêèì èíòåðôåéñîì.<br />

Íèêîëàé "GorluM" Àíäðååâ (gorlum@real.xakep.ru)<br />

Ðàáîòàåì êàê ñ ôàéëîì<br />

Ñàìà ñèñòåìà äðàéâåðîâ, äà è âèíäîâ â öåëîì, ïîçâîëÿåò ðàáîòàòü ñ êîììóíèêàöèîííûìè<br />

ïîðòàìè (íå òîëüêî COM, íî è LPT) êàê ñ îáûêíîâåííûìè ôàéëàìè. Òî åñòü äëÿ<br />

ýòîãî áóäóò èñïîëüçîâàòüñÿ òå æå ôóíêöèè, ÷òî è ïðè ðàáîòå ñ ôàéëàìè. Âîò êàê ýòî<br />

ðåàëèçóåòñÿ. Äëÿ íà÷àëà âçàèìîäåéñòâèÿ ñ ïîðòîì íåîáõîäèìî ïîëó÷èòü åãî õýíäë ïðè<br />

ïîìîùè ôóíêöèè CreateFile. Ïðè÷åì ïàðàìåòðû òî÷íî òàêèå æå, êàê è ïðè ðàáîòå ñ<br />

ôàéëàìè, òîëüêî â ïîëå èìåíè ôàéëà ìû ñòàâèì èìÿ ïîðòà - "COM1", "COM2" è ò.ï.:<br />

HANDLE hCom =<br />

CreateFile("COM1",GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,0,0);<br />

Äëÿ äðóãèõ ïðèëîæåíèé äðàéâåð ïîðòà ïîëó÷èò ñòàòóñ "çàíÿòûé", è â ïåðåìåííîé<br />

hCom îêàæåòñÿ HANDLE ïîðòà. Òåïåðü ìû ìîæåì ðàáîòàòü ñ íèì ïðè ïîìîùè äâóõ<br />

api-ôóíêöèé: ReadFile è WriteFile. Íàïðèìåð, äëÿ òîãî ÷òîáû ïîñëàòü â ïîðò ñòðîêó<br />

buffer, íåîáõîäèìî ñäåëàòü ñëåäóþùåå:<br />

WriteFile(hCom, buffer, strlen(buffer), &n, 0);<br />

 ïåðâîì ïàðàìåòðå ýòîé ôóíêöèè ìû ïåðåäàåì õýíäë ïîðòà, äàëåå óêàçàòåëü íà<br />

ñòðîêó, îáúåì ïîñûëàåìûõ áàéò, çàòåì óêàçàòåëü íà ïåðåìåííóþ òèïà DWORD, â êîòîðóþ<br />

çàíåñåòñÿ êîëè÷åñòâî ïîñëàííûõ áàéò, è óêàçàòåëü íà overlapped-áóôåð (îí<br />

íàì íå íóæåí, ïîýòîìó ïðîñòî ïåðåäàåì íîëü).<br />

À âîò ÷òî íåîáõîäèìî ñäåëàòü, ÷òîáû ïðî÷èòàòü èç ïîðòà ñòðîêó äëèíîé â 6 ñèìâîëîâ:<br />

ReadFile(hCom, &buffer, 6, &n, 0);<br />

Ó ýòîé ôóíêöèè åñòü îäèí íþàíñ. Ïðè çàïóñêå îíà æäåò ïîÿâëåíèÿ çàäàííîãî êîëè÷åñòâà<br />

áàéò â ïîðòó. Åñëè ïðèõîäèò ìåíüøå îæèäàåìîãî, òî ôóíêöèÿ ïðîñòî íå âåðíåò óïðàâëåíèÿ<br />

ïðîãðàììå è áóäåò äîæèäàòüñÿ îñòàâøèõñÿ áàéò. ×òîáû óáðàòü òàêèå "çàâèñàíèÿ"<br />

èç ïðîãðàììû, ìû ìîæåì ñäåëàòü ñëåäóþùåå: â öèêëå ÷èòàòü ïî îäíîìó áàéòó èç<br />

ïîðòà è òîò÷àñ æå åãî âûâîäèòü. Íî â òî æå âðåìÿ ó íàñ íå ïîëó÷èòñÿ îäíîâðåìåííî ïèñàòü<br />

â ïîðò è ñ÷èòûâàòü. À âûõîä èç ñëîæèâøèéñÿ ñèòóàöèè ïðîñò! Íàì íàäî ñîçäàòü ïîòîê,<br />

òî åñòü ôóíêöèþ, ðàáîòàþùóþ ïàðàëëåëüíî ñ îñíîâíîé ïðîãðàììîé, â êîòîðûé ìû<br />

è ïîìåñòèì íàø öèêë ÷òåíèÿ. Äëÿ ýòîãî ìû îïðåäåëèì ôóíêöèþ è äîáàâèì â íåå öèêë:<br />

DWORD __stdcall ReadThread(LPVOID param){<br />

// ... òóò öèêë ÷òåíèÿ<br />

}<br />

À óæå èç ìåéíîâîé ôóíêöèè çàïóñòèì ïðè ïîìîùè WinAPI íàø ïîòîê:<br />

HANDLE hThread = CreateThread(0, 0, ReadThread, (LPVOID)0, 0, 0);<br />

È âðîäå áû âñå çàìå÷àòåëüíî: â îäíîì ïîòîêå ó íàñ èäåò ÷òåíèå è âûâîä, â äðóãîì<br />

(ãëàâíîì) - ìû ââîäèì äàííûå è ïîñûëàåì èõ â ïîðò. Íî òóò êðîåòñÿ åùå îäíà ïðîáëåìà.<br />

Íàì íåëüçÿ îäíîâðåìåííî ÷èòàòü è ïîñûëàòü äàííûå! Òî åñòü â òî âðåìÿ, ïîêà<br />

èç ïîðòà íè÷åãî íå ïðèøëî, è ReadFile ñïîêîéíî æäåò ñâîåãî áàéòèêà, ìû íå ìîæåì<br />

ïîñëàòü äàííûå. Êàê æå áûòü Ïðîñòî ïðåæäå ÷åì îòïðàâèòü óæå ââåäåííûå äàííûå,<br />

ìû êèëëàíåì ïîòîê. Óáüåì, ïîøëåì, à çàòåì ñíîâà ñîçäàäèì. È òàê êàæäûé ðàç,<br />

êîãäà çàõîòèì ïîñëàòü ÷òî-ëèáî â ïîðò. Óáèâàòü ïîòîê ìû áóäåì ïðè ïîìîùè ôóíêöèè<br />

TerminateThread, â ïåðâîì ïàðàìåòðå êîòîðîé ïåðåäàäèì óêàçàòåëü íà ïîòîê<br />

(hThread), à âî âòîðîì - êîä çàâåðøåíèÿ (0). Âûãëÿäèò âñå ýòî òàê:<br />

86<br />

// Óáèâàåì íèòü ÷òåíèÿ äàííûõ<br />

TerminateThread(hThread,0);<br />

// Îòïðàâëÿåì òåêñò<br />

WriteFile(hCom, writebuffer, strlen(writebuffer), &n1, 0);<br />

// Çàíîâî ñîçäàåì ïîòîê<br />

hThread = CreateThread(0, 0, ReadThread, (LPVOID)hwnd, 0, 0);<br />

Ïàðàìåòðû ïîðòà<br />

×èòàòü è ïèñàòü ìû íàó÷èëèñü :). Òåïåðü íàì íàäî íàó÷èòüñÿ ìåíÿòü ïàðàìåòðû ïîðòà.<br />

Ýòî ìîæíî ñäåëàòü â device manager, çàéäÿ â ñâîéñòâà óñòðîéñòâà, à ìîæíî è èç<br />

ñâîåé ïðîãðàììû. Âñå ïàðàìåòðû ïîðòà áóäóò õðàíèòüñÿ â îãðîìíîé ñòðóêòóðå ïîä<br />

íàçâàíèåì DCB. Âîò åå îñíîâíûå çíà÷åíèÿ:<br />

BaudRate - ñêîðîñòü ïîðòà. Ìîæåò ïðèíèìàòü çíà÷åíèÿ CBR_9600, CBR_19200,<br />

CBR_38400 è ò.ä.<br />

ByteSize - ðàçìåð áàéòà, âàðüèðóåòñÿ îò 4 äî 8. Íàì íåîáõîäèìî 8.<br />

Parity - ÷åòíîñòü. Íàì îíà íå íóæíà, ïîýòîìó ïðèñâàèâàåì defined-çíà÷åíèå NOPARITY.<br />

StopBits - ñòîïîâûå áèòû, ó íàñ - ONESTOPBIT.<br />

Ëåïèì êíîïêè<br />

Äëÿ òîãî ÷òîáû îòðåäàêòèðîâàòü ïàðàìåòðû, èõ íàäî ñíà÷àëà ïîëó÷èòü. Ïîýòîìó ìû<br />

âîñïîëüçóåìñÿ ôóíêöèåé GetCommState: â ïåðâîì àðãóìåíòå ïåðåäàåòñÿ õýíäë ïîðòà,<br />

à âî âòîðîì - ïåðåìåííàÿ òèïà ñòðóêòóðû DCB. Ïîñëå âûïîëíåíèÿ ôóíêöèè<br />

ñòðóêòóðà áóäåò çàïîëíåíà òåêóùèìè óñòàíîâêàìè ïîðòà. Òåïåðü ìû ìîæåì ñìåëî<br />

ðåäàêòèðîâàòü ëþáîé èç íèõ. Ïîñëå ðåäàêòèðîâàíèÿ ïàðàìåòðîâ èõ, åñòåñòâåííî,<br />

íàäî ñîõðàíèòü. Äëÿ ýòîãî ñîçäàíà ôóíêöèÿ SetCommState. Âîò òàê âûãëÿäèò êîä ðåêîíôèãóðàöèè<br />

â íàøåé ïðîãðàììå:<br />

DCB dcb;<br />

GetCommState(hCom, &dcb);<br />

dcb.BaudRate = CBR_57600;<br />

dcb.ByteSize = 8;<br />

dcb.Parity = NOPARITY;<br />

dcb.StopBits = ONESTOPBIT;

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!