標籤:parameter oca alt use 支援 部落格 位元組 計算公式 existing
1、普通下載一個MinGW程式、安裝之後可以直接將MinGW目錄拷貝到總工程的tool裡面:
demo_mesh_common tree -L 2.├── app├── bin├── build├── doc├── sdk│?? ├── alg│?? ├── bsp│?? ├── driver│?? └── phy└── tool └── MinGW
2、參考學習在dos下使用gcc來編譯,發現分步驟編譯會報_alloca未定義的錯誤:
a.o:a.c:(.text+0x3f8): undefined reference to `_alloca'
猜測可能是有些庫沒有連結進來,於是搜尋MinGW/lib/下的庫:
F:\demo_mesh_common\tool\MinGW\lib>grep -rn "_alloc"Binary file libmingw32.a matchesBinary file libmingwex.a matchesBinary file libwldap32.a matchesBinary file libdxerr8.a matchesBinary file libdxerr9.a matchesBinary file gcc/mingw32/3.4.5/libgcc.a matchesBinary file librpcdce4.a matchesBinary file libbfd.a matchesBinary file libiberty.a matches
通過一個一個加進編譯選項,最終發現:需要將gcc/mingw32/3.4.5/libgcc.a加入:
./MinGW/bin/ld -L"./MinGW/lib" -o a.exe a.o "./MinGW/lib/crt2.o" -lmingw32 -lkernel32 -lmsvcrt -luser32 -lwow32 -lwldap32 -lwin32k -lvfw32 -lmingw32 -lmingwex -lwldap32 -ldxerr8 -ldxerr9 -lrpcdce4 -lbfd -liberty -L"./MinGW/lib/gcc/mingw32/3.4.5" -lgcc
3、我測試的win32串口程式,在Git Bush(linux屬性)的視窗中可以執行,但無資料,必須在win視窗中執行。
4、附錄
makefile:
a.o:a.c ./MinGW/bin/gcc -c a.cB:a.o ./MinGW/bin/ld -L"./MinGW/lib" -o a.exe a.o "./MinGW/lib/crt2.o" -lmingw32 -lkernel32 -lmsvcrt -luser32 -lwow32 -lwldap32 -lwin32k -lvfw32 -lmingw32 -lmingwex -lwldap32 -ldxerr8 -ldxerr9 -lrpcdce4 -lbfd -liberty -L"./MinGW/lib/gcc/mingw32/3.4.5" -lgccA: ./MinGW/bin/gcc -s -O2 a.c -mconsole
a.c:
#include <stdio.h>#include <stdlib.h>#include <windows.h>#include <string.h>#include <malloc.h>HANDLE hComm;OVERLAPPED m_ov;COMSTAT comstat;DWORD m_dwCommEvents;//如果在調用CreateFile建立控制代碼時指//定了FILE_FLAG_OVERLAPPED標誌,那麼調用ReadFile和WriteFile對該控制代碼進//行的操作就應該是重疊的;如果未指定//重疊標誌,則讀寫操作應該是同步的//在同步執行時,函數直到操作完成後才返回。這意味著同步執行時線程會被阻塞,從//而導致效率下降。在重疊執行時,即使操作還未完成,這兩個函數也會立即返回,費//時的I/O操作在後台進行BOOL openport(char *portname)//開啟一個串口{ hComm = CreateFile(portname, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); if (hComm == INVALID_HANDLE_VALUE) return FALSE; else return TRUE;}BOOL setupdcb(int rate_arg){ DCB dcb; int rate= rate_arg; memset(&dcb,0,sizeof(dcb)); //在一段記憶體塊中填充某個給定的值,是對較大的結構//體或數組進行清零操作的一種最快方法 if(!GetCommState(hComm,&dcb))//擷取當前DCB配置 { return FALSE; } /* -------------------------------------------------------------------- */ // set DCB to configure the serial port dcb.DCBlength = sizeof(dcb); /* ---------- Serial Port Config ------- */ dcb.BaudRate = rate; dcb.Parity = NOPARITY; dcb.fParity = 0; dcb.StopBits = ONESTOPBIT; dcb.ByteSize = 8; dcb.fOutxCtsFlow = 0; dcb.fOutxDsrFlow = 0; dcb.fDtrControl = DTR_CONTROL_DISABLE; dcb.fDsrSensitivity = 0; dcb.fRtsControl = RTS_CONTROL_DISABLE; dcb.fOutX = 0; dcb.fInX = 0; /* ----------------- misc parameters ----- */ dcb.fErrorChar = 0; dcb.fBinary = 1; dcb.fNull = 0; dcb.fAbortOnError = 0; dcb.wReserved = 0; dcb.XonLim = 2; dcb.XoffLim = 4; dcb.XonChar = 0x13; dcb.XoffChar = 0x19; dcb.EvtChar = 0; /* -------------------------------------------------------------------- */ // set DCB if(!SetCommState(hComm,&dcb)) { return FALSE; } else return TRUE;}//在用readfile和writefile讀寫串列口時,需要考慮逾時問題, 讀寫串口的逾時有兩//種:間隔逾時和總逾時, 寫操作只支援總逾時,而讀操作兩種逾時均支援, 如果所有//寫逾時參數均為0,那麼就不使用寫逾時。BOOL setuptimeout(DWORD ReadInterval,DWORD ReadTotalMultiplier,DWORD ReadTotalconstant,DWORD WriteTotalMultiplier,DWORD WriteTotalconstant) { COMMTIMEOUTS timeouts; timeouts.ReadIntervalTimeout=ReadInterval; //讀間隔逾時 timeouts.ReadTotalTimeoutConstant=ReadTotalconstant; //讀時間係數 timeouts.ReadTotalTimeoutMultiplier=ReadTotalMultiplier; //讀時間常量 timeouts.WriteTotalTimeoutConstant=WriteTotalconstant; // 寫時間係數 timeouts.WriteTotalTimeoutMultiplier=WriteTotalMultiplier; //寫時間常//量, 總逾時的計算公式是:總逾時=時間係數×要求讀/寫的字元數+時間常量 if(!SetCommTimeouts(hComm, &timeouts)) { return FALSE; } else return TRUE;}void ReceiveChar(){ BOOL bRead = TRUE; BOOL bResult = TRUE; DWORD dwError = 0; DWORD BytesRead = 0; char RXBuff; while(TRUE){ bResult = ClearCommError(hComm, &dwError, &comstat); // 在使用ReadFile 函數進行讀操作前,應先使用ClearCommError函數清除錯誤 if(comstat.cbInQue==0)// COMSTAT結構返回串口狀態資訊 //本文只用到了cbInQue成員變數,該成員變數的值代表輸入緩衝區的位元組數 continue; if(bRead){ bResult = ReadFile(hComm, // Handle to COMM port串口的控制代碼 &RXBuff,// RX Buffer Pointer// 讀入的資料存放區的地址,即讀入的資料將存//儲在以該指標的值為首地址的一片記憶體區 1,// Read one byte要讀入的資料的位元組數, &BytesRead, // Stores number of bytes read, 指向一個DWORD//數值,該數值返回讀操作實際讀入的位元組數 &m_ov); // pointer to the m_ov structure// 重疊操作時,該參數指向一個OVERLAPPED結構,同步操作時,該參數為NULL printf("%02X",RXBuff); if (!bResult){// 當ReadFile和WriteFile返回FALSE時,不一定就是操作失//敗,線程應該調用GetLastError函數分析返回的結果 switch (dwError = GetLastError()){ case ERROR_IO_PENDING: bRead = FALSE; break; default:break; } }else{ bRead = TRUE; } } // close if (bRead) if (!bRead){ bRead = TRUE; bResult = GetOverlappedResult(hComm, // Handle to COMM port &m_ov, // Overlapped structure &BytesRead, // Stores number of bytes read TRUE); // Wait flag } }}BOOL WriteChar(BYTE* m_szWriteBuffer,DWORD m_nToSend){ BOOL bWrite = TRUE; BOOL bResult = TRUE; DWORD BytesSent = 0; HANDLE m_hWriteEvent; ResetEvent(m_hWriteEvent); if (bWrite){ m_ov.Offset = 0; m_ov.OffsetHigh = 0; // Clear buffer bResult = WriteFile(hComm, // Handle to COMM Port, 串口的控制代碼 m_szWriteBuffer, // Pointer to message buffer in calling finction // 即以該指標的值為首地址的nNumberOfBytesToWrite // 個位元組的資料將要寫入串口的發送資料緩衝區 m_nToSend, // Length of message to send, 要寫入的資料的位元組數 &BytesSent, // Where to store the number of bytes sent // 指向指向一個DWORD數值,該數值返回實際寫入的位元組數 &m_ov ); // Overlapped structure // 重疊操作時,該參數指向一個OVERLAPPED結構, // 同步操作時,該參數為NULL if (!bResult){ // 當ReadFile和WriteFile返回FALSE時,不一定就是操作失 //敗,線程應該調用GetLastError函數分析返回的結果 DWORD dwError = GetLastError(); switch (dwError){ case ERROR_IO_PENDING: //GetLastError函數返回//ERROR_IO_PENDING。這說明重疊操作還未完成 // continue to GetOverlappedResults() BytesSent = 0; bWrite = FALSE; break; default:break; } } } // end if(bWrite) if (!bWrite){ bWrite = TRUE; bResult = GetOverlappedResult(hComm, // Handle to COMM port &m_ov, // Overlapped structure &BytesSent, // Stores number of bytes sent TRUE); // Wait flag // deal with the error code if (!bResult){ printf("GetOverlappedResults() in WriteFile()"); } } // end if (!bWrite) // Verify that the data size send equals what we tried to send if (BytesSent != m_nToSend){ printf("WARNING: WriteFile() error.. Bytes Sent: %d; Message Length: %d\n", BytesSent, strlen((char*)m_szWriteBuffer)); } return TRUE;}int main(void){ printf("open comport successsdsfds\n"); if(openport("com3")) printf("open comport success\n"); if(setupdcb(9600)) printf("setupDCB success\n"); if(setuptimeout(0,0,0,0,0)) //如果所有寫逾時參數均為0,那麼就不使用寫逾時 printf("setuptimeout success\n"); PurgeComm(hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT); // 在讀寫串口之前,還要用PurgeComm()函數清空緩衝區 //PURGE_TXABORT 中斷所有寫操作並立即返回,即使寫操作還沒有完成。 //PURGE_RXABORT 中斷所有讀操作並立即返回,即使讀操作還沒有完成。 //PURGE_TXCLEAR 清除輸出緩衝區 //PURGE_RXCLEAR 清除輸入緩衝區 //WriteChar("please send data now",20); printf("received data:\n"); ReceiveChar( ); system("pause"); return 0;}
連結
- 學習在dos下使用gcc來編譯:https://www.cnblogs.com/personnel/p/4584819.html
@beautifulzzzz智能硬體、物聯網,熱愛技術,關注產品部落格:http://blog.beautifulzzzz.com園友交流群:414948975
[編譯] 2、minGW gcc在windows搭建編譯win32程式環境