This chapter will explain the upper computer design of CAN bus based on windows platform.
The development of CAN bus host computer is basically secondary development if we are not the manufacturer of can card. We need to make use of the current can card equipment and the dynamic library or static library provided by the can card to do the corresponding application development.
Preliminary preparation:
1.UI options: VS built-in MFC C c# or current popular QT, etc. (this mainly depends on people's habits, which platform they are familiar with and which one they choose)
2. Understanding of multithreading development (multithreading is recommended)
3.CAN card and secondary development library
4. Lower computer (with CAN peripherals, and the software realizes the basic functions of CAN)
5. Have the agreement basis of 15765 14229
Next, let's see how to realize basic secondary development
1, Secondary development library and its data interpretation (here the author takes foreign PCA and domestic ITEKON as examples)
In fact, no matter which CAN card, it provides the demo of the conventional platform, such as vc qt labview, etc. by consulting the function manual provided, we CAN realize the basic equipment query, reading and writing operation. The project and its execution documents provided by PCAN are as follows:
That's it. Is it very simple? Others have provided source code engineering and manuals. We only need to provide the secondary development library and customize our own host computer.
2, The basic elements of the platform are introduced as follows. The two sdk basic packages are similar, such as device initialization, read-write shutdown, etc
TPCANStatus __stdcall CAN_Initialize( TPCANHandle Channel, TPCANBaudrate Btr0Btr1, TPCANType HwType _DEF_ARG, DWORD IOPort _DEF_ARG, WORD Interrupt _DEF_ARG); TPCANStatus __stdcall CAN_InitializeFD( TPCANHandle Channel, TPCANBitrateFD BitrateFD); TPCANStatus __stdcall CAN_Uninitialize( TPCANHandle Channel); TPCANStatus __stdcall CAN_Reset( TPCANHandle Channel); TPCANStatus __stdcall CAN_GetStatus( TPCANHandle Channel); TPCANStatus __stdcall CAN_Read( TPCANHandle Channel, TPCANMsg* MessageBuffer, TPCANTimestamp* TimestampBuffer); TPCANStatus __stdcall CAN_ReadFD( TPCANHandle Channel, TPCANMsgFD* MessageBuffer, TPCANTimestampFD *TimestampBuffer); TPCANStatus __stdcall CAN_Write( TPCANHandle Channel, TPCANMsg* MessageBuffer); TPCANStatus __stdcall CAN_WriteFD( TPCANHandle Channel, TPCANMsgFD* MessageBuffer); TPCANStatus __stdcall CAN_FilterMessages( TPCANHandle Channel, DWORD FromID, DWORD ToID, TPCANMode Mode); TPCANStatus __stdcall CAN_GetValue( TPCANHandle Channel, TPCANParameter Parameter, void* Buffer, DWORD BufferLength); TPCANStatus __stdcall CAN_SetValue( TPCANHandle Channel, TPCANParameter Parameter, void* Buffer, DWORD BufferLength); TPCANStatus __stdcall CAN_GetErrorText( TPCANStatus Error, WORD Language, LPSTR Buffer);
DWORD __stdcall VCI_OpenDevice(DWORD DeviceType,DWORD DeviceInd,DWORD Reserved); DWORD __stdcall VCI_CloseDevice(DWORD DeviceType,DWORD DeviceInd); DWORD __stdcall VCI_InitCAN(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd, PVCI_INIT_CONFIG pInitConfig); DWORD __stdcall VCI_ReadBoardInfo(DWORD DeviceType,DWORD DeviceInd,PVCI_BOARD_INFO pInfo); DWORD __stdcall VCI_ReadErrInfo(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,PVCI_ERR_INFO pErrInfo); DWORD __stdcall VCI_ReadCANStatus(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,PVCI_CAN_STATUS pCANStatus); DWORD __stdcall VCI_GetReference(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,DWORD RefType,PVOID pData); DWORD __stdcall VCI_SetReference(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,DWORD RefType,PVOID pData); ULONG __stdcall VCI_GetReceiveNum(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd); DWORD __stdcall VCI_ClearBuffer(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd); DWORD __stdcall VCI_StartCAN(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd); DWORD __stdcall VCI_ResetCAN(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd); ULONG __stdcall VCI_Transmit(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,PVCI_CAN_OBJ pSend,ULONG Len); ULONG __stdcall VCI_Receive(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,PVCI_CAN_OBJ pReceive,ULONG Len,INT WaitTime=-1);
Add a dynamic library to the project, such as VS (for details on how to add a library, you can find a tutorial, a large number of online):
III. basic framework construction (MFC is adopted for demo)
void CCAN_UDS_Win32Dlg::OnBnClickedButtonOpen() { /*Clear the MessageBox parameter first*/ m_LstBoxMessage.ResetContent(); if (IsConnect == TRUE) { MessageBox(_T("The device is connect!")); return; } /*Start the initialization related to the device*/ VCI_INIT_CONFIG init_config; int baud; UpdateData(true); init_config.AccCode = 0; init_config.AccMask = 0xffffff; init_config.Filter = 0; init_config.Mode = 0; /*Select User Baud rate*/ baud = m_ComboBaud.GetCurSel(); switch (baud) { case 0: //1000 init_config.Timing0 = 0; init_config.Timing1 = 0x14; break; case 1: //800 init_config.Timing0 = 0; init_config.Timing1 = 0x16; break; case 2: //666 init_config.Timing0 = 0x80; init_config.Timing1 = 0xb6; break; case 3: //500 init_config.Timing0 = 0; init_config.Timing1 = 0x1c; break; case 4://400 init_config.Timing0 = 0x80; init_config.Timing1 = 0xfa; break; case 5://250 init_config.Timing0 = 0x01; init_config.Timing1 = 0x1c; break; case 6://200 init_config.Timing0 = 0x81; init_config.Timing1 = 0xfa; break; case 7://125 init_config.Timing0 = 0x03; init_config.Timing1 = 0x1c; break; case 8://100 init_config.Timing0 = 0x04; init_config.Timing1 = 0x1c; break; case 9://80 init_config.Timing0 = 0x83; init_config.Timing1 = 0xff; break; case 10://50 init_config.Timing0 = 0x09; init_config.Timing1 = 0x1c; break; } if (VCI_OpenDevice(m_devtype, 0, 0) != STATUS_OK) { //MessageBox(_T("Open device fault!"), _T("Alarm"), MB_OK | MB_ICONQUESTION); InsertMessageToListBox(TEXT("Open device fault!")); return; } if (VCI_InitCAN(m_devtype, 0, 0, &init_config) != STATUS_OK) { //MessageBox(_T("Init can fault!"), _T("Alarm"), MB_OK | MB_ICONQUESTION); InsertMessageToListBox(TEXT("Init can fault!")); VCI_CloseDevice(m_devtype, 0); return; } if (VCI_StartCAN(m_devtype, 0, 0) != 1) { //MessageBox(_T("The device start false!")); InsertMessageToListBox(TEXT("The device start false!")); } else { InsertMessageToListBox(TEXT("Open device success!")); /*Create send receive thread*/ hThread[0] = (HANDLE)_beginthreadex(NULL, 0, xCAN_TxThread, pThis, 0, NULL); hThread[1] = (HANDLE)_beginthreadex(NULL, 0, xCAN_RxThread, pThis, 0, NULL); IsConnect = TRUE; } } void CCAN_UDS_Win32Dlg::OnBnClickedButtonReset() { if (IsConnect == FALSE) { return; } /*Disconnect equipment related*/ if (VCI_ResetCAN(m_devtype, 0, 0) == TRUE) { IsConnect = FALSE; MessageBox(_T("The device reset ok!")); } else { MessageBox(_T("The device reset false!")); } } unsigned int WINAPI xCAN_TxThread(PVOID lpParameter) { CCAN_UDS_Win32Dlg* dlg = (CCAN_UDS_Win32Dlg*)lpParameter; UINT8 frameReqStatus = REQ_FALSE; UINT8 reqStatus = xCAN_FAILURE; while(1) { WaitForSingleObject(hCAN_TxEvent, INFINITE); if (xCAN_SUCCESS == dlg->my_UDSCAN.xCAN_FrameReq(&frameReqStatus)) { /*Status after obtaining frame request: 1 Ready to continue sending,*/ switch (frameReqStatus) { case REQ_SFSUCCESS: case REQ_FFSUCCESS: case REQ_CFSUCCESS: ResetEvent(hCAN_TxEvent); break; case REQ_CFWAITE: break; default: break; } } Sleep(dlg->cycleTimer); } return 0; } unsigned int WINAPI xCAN_RxThread(PVOID lpParameter) { CCAN_UDS_Win32Dlg* dlg = (CCAN_UDS_Win32Dlg*)lpParameter; while(1) { WaitForSingleObject(hCAN_RxEvent, INFINITE); xCAN_ReceiveFrameData(dlg); ResetEvent(hCAN_RxEvent); } }
In addition, we need to know about the file analysis (the main engine factory has requirements for the file format: srec, hex, etc.). The file content is roughly two parts, one is the bin binary file (to be burned to ROM), and the other is to describe the exact location of its address. There is no introduction here. You can search for information on the Internet. In addition, it is added here that embedded ides such as Keil IAR have tools for file format conversion. For details, you can learn about relevant documents.
4, Realize UDS function (UDS is a complete set of standard protocols. In fact, it only needs to be familiar with ISO 15765-2 and ISO 14229-1 and express them in code form. Because there is a confidentiality agreement, the author will not show the core code)