📄 ext_serial_pkt.c
字号:
/*
* Copyright 1994-2003 The MathWorks, Inc.
*
* File: ext_serial_pkt.c $Revision: 1.1.6.4 $
*
* Abstract:
* The External Mode Serial Packet is a container object for the serial data
* to be transitted or received and the serial communication overhead (such as
* headers, tailers, etc.). The external mode code writes data to be
* transmitted into an External Mode Serial Packet and lets the packet object
* handle all of the details involved in sending the data. Conversely, data to
* be received by the external mode code is stored in an External Mode Serial
* Packet that handles all of the details in receiving that data. In this
* way, the External Mode Serial Packet provides a clean interface for sending
* and receiving data to a serial port without worrying about the details
* involved with transmitting and receiving the data.
*
* ----------------------------------
* | Host/Target external mode code |
* ----------------------------------
* / \ / \
* /| |\ /| |\
* | | | |
* | | Connect | | Write
* | | Disconnect \| |/ Read
* | | Pending \ /
* | | -----------------
* | | | External Mode |
* | | | Serial Packet |
* | | -----------------
* | | / \
* | | /| |\ Send
* | | | | Receive
* | | | |
* \| |/ \| |/
* \ / \ /
* ----------------------------------
* | External Mode Serial Port |
* ----------------------------------
* / \
* /| |\
* | |
* | |
* \| |/
* \ /
* ----------------------------------
* | HW/OS/Physical serial port |
* ----------------------------------
*
* See also ext_serial_<TRANSPORT>_port.c.
*/
/*
* Adapted for rtmc9s12-Target, fw-09-7
*/
#include <stdlib.h>
#include <string.h>
#include "tmwtypes.h"
#include "ext_types.h"
#include "ext_share.h"
#include "ext_serial_port.h"
#include "ext_serial_pkt.h"
#ifndef MATLAB_MEX_FILE
#include "cpp_req_defines.h" /* System macros (EXT_MODE, etc.) -- generated by 'gen_cpp_req_defines_h.tlc' */
#include "mc_signal.h" /* blinky */
#else
#define abort_LED(err) /* do nothing */
#endif
#include "debugMsgs.h" /* macros PRINT_DEBUG_MSG_LVL1 to PRINT_DEBUG_MSG_LVL1, fw-06-07 */
/* Function: IsEscapeChar ======================================================
* Abstract:
* Returns true if the char belongs to the escape sequence, false otherwise.
*/
PRIVATE boolean_T IsEscapeChar(char c) {
if((c==packet_head)||(c==packet_tail)||(c==escape_character)) {
return true;
}
return false;
} /* end IsEscapeChar */
/* Function: Filter ============================================================
* Abstract:
* Filter the outgoing message to trasnslate any bytes that conflict with
* escape chars. If a byte does conflict, the byte is replaced with two
* bytes: The first is the escape character and the second is the conflicted
* byte exclusive or'd with the mask character. If a byte does not conflict,
* it is unchanged. Returns the new size of the buffer after filtering.
*
* Note: In the worst case where every char is an escape char, the
* destination buffer will be 2 times the size of the source buffer.
*/
PRIVATE uint32_T Filter(char *dest, char *src, uint32_T bytes) {
uint32_T i;
uint32_T newSize=bytes;
char *pDest=dest;
char *pSrc=src;
for(i=0 ; i<bytes ; i++, pSrc++) {
if(IsEscapeChar(*pSrc)) {
*pDest=escape_character;
pDest++;
*pDest=(char)((*pSrc)^mask_character);
pDest++;
newSize++;
}
else {
*pDest= *pSrc;
pDest++;
}
}
return newSize;
} /* end Filter */
/* Function: Num2String ========================================================
* Abstract:
* Translates unsigned long values into strings and returns the size of the
* string.
*/
PRIVATE uint32_T Num2String(char *dest, uint32_T value, boolean_T doFilter, boolean_T endianess) {
char c[sizeof(uint32_T)];
int i;
int j;
numString temp;
temp.num=value;
if(!endianess) {
/* big endian */
i=sizeof(uint32_T);
j=0;
while(j<sizeof(uint32_T)) {
c[j]=temp.string[i-1];
j++;
i--;
};
memcpy(temp.string, c, sizeof(uint32_T));
}
if(doFilter) {
return Filter(dest, temp.string, sizeof(uint32_T));
}
else {
memcpy(dest, temp.string, sizeof(uint32_T));
return sizeof(uint32_T);
}
} /* end Num2String */
/* Function: String2Num ========================================================
* Abstract:
* Translates strings into unsigned long values and returns the size of the
* value of the number.
*/
PRIVATE uint32_T String2Num(char *source, boolean_T endianess) {
numString temp;
numString temp2;
int i;
int j;
temp.num=0; /* For compilation warning using lcc. */
temp2.num=0; /* For compilation warning using lcc. */
memcpy(temp.string, source, 4);
if(!endianess) {
/* big endian */
i=sizeof(uint32_T);
j=0;
temp2.num=0ul;
while(j<4) {
temp2.string[i-1]=temp.string[j];
j++;
i--;
};
return temp2.num;
}
else {
/* little endian */
return temp.num;
}
} /* end String2Num */
/* Function: SetExtSerialPacket ================================================
* Abstract:
* Sets (sends) the contents of an ExtSerialPacket on the comm line. This
* includes the packet's buffer as well as all serial communication overhead
* associated with the packet.
*
* EXT_NO_ERROR is returned on success, EXT_ERROR on failure.
*/
PUBLIC boolean_T SetExtSerialPacket(ExtSerialPacket *pkt, ExtSerialPort *portDev) {
uint32_T i;
uint32_T numAct=0; /* Num bytes actually sent. */
uint32_T numExp=0; /* Num bytes ordered to send. */
uint32_T newByteCnt=0; /* Num bytes after filtering. */
uint32_T bytesWritten=0; /* Num bytes written by send. */
boolean_T error=EXT_NO_ERROR;
char Buffer[sizeof(uint32_T)*2]; /* Local buffer for converting escape chars. */
// local function name... debugging only
#if DEBUG_MSG_LVL > 0
const char *funct_name="SetExtSerialPacket";
#endif
PRINT_DEBUG_MSG_LVL4("IN");
PRINT_DEBUG_MSG_NL4;
/* If not connected, return immediately. */
if(!portDev->fConnected) {
// temporarily disable to throw an error in the calling method instead -- fw-07-07
//abort_LED(11);
return EXT_ERROR;
}
/* Initialize some fileds of the packet. */
pkt->head[0]=packet_head;
pkt->head[1]=packet_head;
pkt->tail[0]=packet_tail;
pkt->tail[1]=packet_tail;
pkt->state=ESP_NoPacket;
pkt->cursor=0;
pkt->DataCount=0;
pkt->inQuote=false;
/* Send the packet header. */
PRINT_DEBUG_MSG_LVL4("State -> ESP_InHead");
PRINT_DEBUG_MSG_NL4;
error=ExtSerialPortSetData(portDev, pkt->head, HEAD_SIZE, &bytesWritten);
if(error!=EXT_NO_ERROR) {
/* never happens, errors caught above -- fw-07-07 */
abort_LED(12); // just in case
goto EXIT_POINT;
}
numAct=bytesWritten;
numExp=HEAD_SIZE;
/* Send the packet type. */
PRINT_DEBUG_MSG_LVL4("State -> ESP_InType");
#if DEBUG_MSG_LVL >= 4
if(pkt->PacketType==UNDEFINED_PACKET) {
PRINT_DEBUG_MSG_LVL4_Raw(" (UNDEFINED_PACKET)");
}
if(pkt->PacketType==EXTMODE_PACKET) {
PRINT_DEBUG_MSG_LVL4_Raw(" (EXTMODE_PACKET)");
}
if(pkt->PacketType==ACK_PACKET) {
PRINT_DEBUG_MSG_LVL4_Raw(" (ACK_PACKET)");
}
#endif
PRINT_DEBUG_MSG_NL4;
newByteCnt=Filter(Buffer, &(pkt->PacketType), PACKET_TYPE_SIZE);
error=ExtSerialPortSetData(portDev, Buffer, newByteCnt, &bytesWritten);
if(error!=EXT_NO_ERROR) {
/* never happens, errors caught above -- fw-07-07 */
abort_LED(13); // just in case
goto EXIT_POINT;
}
numAct+=bytesWritten;
numExp+=newByteCnt;
/* Send the size of the packet buffer. */
PRINT_DEBUG_MSG_LVL4("State -> ESP_InSize (");
PRINT_DEBUG_MSG_LVL4_UDec(pkt->size);
PRINT_DEBUG_MSG_LVL4_Raw(" bytes)");
PRINT_DEBUG_MSG_NL4;
newByteCnt=Num2String(Buffer, pkt->size, true, portDev->isLittleEndian);
error=ExtSerialPortSetData(portDev, Buffer, newByteCnt, &bytesWritten);
if(error!=EXT_NO_ERROR) {
/* never happens, errors caught above -- fw-07-07 */
abort_LED(14); // just in case
goto EXIT_POINT;
}
numAct+=bytesWritten;
numExp+=newByteCnt;
/* Send the variable-sized packet buffer data. */
PRINT_DEBUG_MSG_LVL4("State -> ESP_InPayload");
PRINT_DEBUG_MSG_NL4;
for(i=0; i<pkt->size; i++) {
#ifdef MATLAB_MEX_FILE
PRINT_DEBUG_MSG_LVL5("Data element ");
PRINT_DEBUG_MSG_LVL5_UDec(i+1);
PRINT_DEBUG_MSG_LVL5_Raw("/");
PRINT_DEBUG_MSG_LVL5_UDec(pkt->size);
PRINT_DEBUG_MSG_LVL5_Raw(": ");
PRINT_DEBUG_MSG_LVL5_UHex(pkt->Buffer[i]);
PRINT_DEBUG_MSG_NL5;
#endif /* MATLAB_MEX_FILE */
newByteCnt=Filter(Buffer, &(pkt->Buffer[i]), 1);
#ifdef MATLAB_MEX_FILE
PRINT_DEBUG_MSG_LVL5("Converted data element ");
PRINT_DEBUG_MSG_LVL5_UDec(i+1);
PRINT_DEBUG_MSG_LVL5_Raw("/");
PRINT_DEBUG_MSG_LVL5_UDec(pkt->size);
PRINT_DEBUG_MSG_LVL5_Raw(": ");
#if DEBUG_MSG_LVL >= 5
{
int kk;
for(kk=0; kk<newByteCnt; kk++) {
PRINT_DEBUG_MSG_LVL5_UHex((uint16_T)Buffer[kk]);
PRINT_DEBUG_MSG_LVL5_Raw(" ");
}
}
#endif
PRINT_DEBUG_MSG_NL5;
#endif /* MATLAB_MEX_FILE */
error=ExtSerialPortSetData(portDev, Buffer, newByteCnt, &bytesWritten);
if(error!=EXT_NO_ERROR) {
/* never happens, errors caught above -- fw-07-07 */
abort_LED(15); // just in case
goto EXIT_POINT;
}
numAct+=bytesWritten;
numExp+=newByteCnt;
}
/* Send the packet tail. */
PRINT_DEBUG_MSG_LVL4("State -> ESP_InTail");
PRINT_DEBUG_MSG_NL4;
error=ExtSerialPortSetData(portDev, pkt->tail, TAIL_SIZE, &bytesWritten);
if(error!=EXT_NO_ERROR) {
/* never happens, errors caught above -- fw-07-07 */
abort_LED(16); // just in case
goto EXIT_POINT;
}
numAct+=bytesWritten;
numExp+=TAIL_SIZE;
/*
* Return false if actual number of bytes sent does not equal the expected
* number of bytes. Otherwise, return true.
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -