📄 ext_serial_utils.c
字号:
/*
* Copyright 1994-2003 The MathWorks, Inc.
*
* File: ext_serial_utils.c $Revision: 1.1.6.4 $
*
* Absract:
* External mode shared data structures and functions used by the external
* communication, mex link, and generated code. This file is for definitions
* related to custom external mode implementations (e.g., tcpip, serial).
* See ext_share.h for definitions common to all implementations of external
* mode (ext_share.h should NOT be modified).
*/
/*
* Adapted for rtmc9s12-Target, fw-09-7
*/
/***************** TRANSPORT-DEPENDENT DEFS AND INCLUDES **********************/
#include <stdlib.h>
#include <string.h>
#include "tmwtypes.h"
#include "ext_share.h"
#include "simstruc_types.h"
#include "ext_svr.h"
#include "ext_serial_port.h"
#include "ext_serial_pkt.h"
/* this file is used by both host and target... */
#ifndef MATLAB_MEX_FILE
/* TARGET ONLY ------------------- */
#include "cpp_req_defines.h" /* System macros (EXT_MODE, etc.) -- generated by 'gen_cpp_req_defines_h.tlc' */
#include "mc_signal.h" /* blinky */
#if COMMSTATE_ON_PTT == 1
/* Microcontroller specific and system headers */
#if MC9S12_TYPE == DP256
#include <mc9s12dp256.h> /* port definitions etc. */
#elif MC9S12_TYPE == C128
#include <mc9s12c128.h> /* port definitions etc. */
#elif MC9S12_TYPE == C32
#include <mc9s12c32.h> /* port definitions etc. */
#endif
#endif
#ifdef HOSTALIVECHECK
/* flag is reset to TRUE with every properly received ACK_PACKET;
* flag is set to FALSE when the target buffer is full (-> most likely cause: host inactive)
* used to control the writing of new data into the circBuf
*
* fw-07-07
*/
/* stop buffering data when the target buffer is full and the host seems busy */
extern boolean_T HostIsAlive; /* defined in mc_main.c */
#endif
#else
/* HOST ONLY --------------------- */
#define abort_LED(err) /* nothing */
#ifndef CIRCBUFSIZE
#define CIRCBUFSIZE 2000 /* default (host) */
#endif
#ifndef FIFOBUFSIZE
#define FIFOBUFSIZE 400 /* default (host) */
#endif
/* FIFOHOSTFACTOR should be > 2 (the larger, the more stable the host after long blockages of Simulink (e.g. menu open)
* The memory needed on the host is: FIFOBUFNUM * FIFOBUFSIZE = CIRCBUFSIZE * FIFOHOSTFACTOR... at least: 2000 * FIFOHOSTFACTOR
* An insanely high factor of '50' thus leads to a memory requirement of 2k * 50 = 100 kByte, nothing on a PC. With a factor '50'
* a DP9S12 based target with a target buffer size of 2k target should survive a host blockage of approx. 10 minutes...
* ... in theory :)
*
* fw-07-07
*/
#define FIFOHOSTFACTOR 50
#define FIFOBUFNUM CIRCBUFSIZE/FIFOBUFSIZE * FIFOHOSTFACTOR
/* used here to activate/deactivate the deadlock emergency control (ExtSetPkt) -- fw-07-07 */
/* HostSimStatus is an enum defined in ext_share.h */
extern HostSimStatus HostStatus;
#endif
#include "debugMsgs.h" /* macros PRINT_DEBUG_MSG_LVL1 to PRINT_DEBUG_MSG_LVL5, fw-06-07 */
/* Display clear text messages of what packet has been sent/received (debug mode only) */
#if DEBUG_MSG_LVL > 0
static const char *debugTelTypeStrings[3]= {
"Packet type is UNDEFINED_PACKET",
"Packet type is EXTMODE_PACKET",
"Packet type is ACK_PACKET"
};
#ifdef MATLAB_MEX_FILE
#define numActionStrings 34
extern const char *debugActionStrings[]; /* defined in ext_comm.c, 34 strings */
#endif /* MATLAB_MEX_FILE */
// monitor the number of stored packets (queue: FIFOPkt)
static unsigned int numFIFOPkts=0;
#endif
/* defined in 'ext_work.c', here only referenced */
extern int_T volatile startModel;
/*
* Buffers used for storing incoming and outgoing packets.
*/
PRIVATE ExtSerialPacket buffer1st;
PRIVATE ExtSerialPacket buffer2nd;
PRIVATE ExtSerialPacket *InBuffer= &buffer1st;
PRIVATE ExtSerialPacket *OutBuffer= &buffer2nd;
/*
* If waitForAck is true, a packet can not be sent until the other side sends
* an ack indicating there is space to store the unsent packet.
*/
PRIVATE boolean_T waitForAck=false;
/* needed for host sided communication module... fw-06-07 */
#ifdef MATLAB_MEX_FILE
/*
* NOTE: When adding or removing a valid baud rate, both the baudRates and
* baudRatesStr variables must be modified!
*/
PRIVATE const uint32_T baudRates[]= {
1200,
2400,
4800,
9600,
14400,
19200,
38400,
56000,
57600,
115200
};
PRIVATE const char_T *baudRatesStr="baud rate must be one of the following:\n"
"\t1200, 2400, 4800, 9600, 14400,\n"
"\t19200, 38400, 56000, 57600, 115200\n";
#endif
/*
* The maximum number of bytes a serial packet may contain. Serial pkts
* larger than the maximum size will be broken up into multiple pkts
* (each equal to or less than the max size) for transmission.
*/
#define MAX_SERIAL_PKT_SIZE FIFOBUFSIZE
/*
* The maximum number of (maximum sized) packets that can be stored at
* any one time.
*/
#define NUM_FIFO_BUFFERS FIFOBUFNUM
typedef struct FIFOBuffer_tag {
char pktBuf[MAX_SERIAL_PKT_SIZE];
uint32_T size;
uint32_T offset;
struct FIFOBuffer_tag *next;
} FIFOBuffer;
PRIVATE FIFOBuffer *FreeFIFOHead=NULL;
PRIVATE FIFOBuffer *FreeFIFOTail=NULL;
PRIVATE FIFOBuffer *PktFIFOHead=NULL;
PRIVATE FIFOBuffer *PktFIFOTail=NULL;
PRIVATE bool isFIFOEmpty(FIFOBuffer *head, FIFOBuffer *tail) {
if((head==NULL)&&(tail==NULL)) {
return true;
}
return false;
}
PRIVATE void InsertFIFO(FIFOBuffer **head, FIFOBuffer **tail, FIFOBuffer *buf) {
if(isFIFOEmpty(*head, *tail)) {
*head= *tail=buf;
buf->next=NULL;
}
else {
assert(*head != NULL);
assert(*tail != NULL);
(*tail)->next=buf;
*tail=buf;
buf->next=NULL;
}
}
PRIVATE FIFOBuffer * RemoveFIFO(FIFOBuffer **head, FIFOBuffer **tail) {
FIFOBuffer *buf=NULL;
if(isFIFOEmpty(*head, *tail)) {
return NULL;
}
else {
assert(*head != NULL);
assert(*tail != NULL);
buf= *head;
*head=buf->next;
if(*head==NULL) {
*tail=NULL;
}
buf->next=NULL;
}
return buf;
}
PRIVATE bool isFIFOFreeEmpty(void) {
return isFIFOEmpty(FreeFIFOHead, FreeFIFOTail);
}
PRIVATE bool isFIFOPktEmpty(void) {
return isFIFOEmpty(PktFIFOHead, PktFIFOTail);
}
PRIVATE void InsertFIFOFree(FIFOBuffer *buf) {
InsertFIFO(&FreeFIFOHead, &FreeFIFOTail, buf);
}
PRIVATE FIFOBuffer * RemoveFIFOFree(void) {
return RemoveFIFO(&FreeFIFOHead, &FreeFIFOTail);
}
PRIVATE void InsertFIFOPkt(FIFOBuffer *buf) {
// local function name... debugging only
#if DEBUG_MSG_LVL > 0
const char *funct_name="InsertFIFOPkt";
#endif
#if DEBUG_MSG_LVL > 0
numFIFOPkts++;
PRINT_DEBUG_MSG_LVL3("Number of stored messages in FIFOPkt: ");
PRINT_DEBUG_MSG_LVL3_UDec((uint16_T)(numFIFOPkts));
PRINT_DEBUG_MSG_NL3;
#endif
InsertFIFO(&PktFIFOHead, &PktFIFOTail, buf);
}
PRIVATE FIFOBuffer * RemoveFIFOPkt(void) {
// local function name... debugging only
#if DEBUG_MSG_LVL > 0
const char *funct_name="RemoveFIFOPkt";
#endif
#if DEBUG_MSG_LVL > 0
PRINT_DEBUG_MSG_LVL3("Fetching last previously stored packet...");
PRINT_DEBUG_MSG_NL3;
numFIFOPkts--;
PRINT_DEBUG_MSG_LVL3("Number of stored messages left in FIFOPkt: ");
PRINT_DEBUG_MSG_LVL3_UDec((uint16_T)(numFIFOPkts));
PRINT_DEBUG_MSG_NL3;
#endif
return RemoveFIFO(&PktFIFOHead, &PktFIFOTail);
}
PRIVATE FIFOBuffer * GetFIFOPkt(void) {
return PktFIFOHead;
}
PRIVATE boolean_T AddToFIFOFree(void) {
int i;
boolean_T error=EXT_NO_ERROR;
// local function name... debugging only
#if DEBUG_MSG_LVL > 0
const char *funct_name="AddToFIFOFree";
#endif
PRINT_DEBUG_MSG_LVL3("Allocating memory for (another) ");
PRINT_DEBUG_MSG_LVL3_UDec((uint16_T)NUM_FIFO_BUFFERS);
PRINT_DEBUG_MSG_LVL3_Raw(" free FIFO buffers");
PRINT_DEBUG_MSG_NL3;
for(i=0 ; i<NUM_FIFO_BUFFERS ; i++) {
FIFOBuffer *buf=calloc(1, sizeof(FIFOBuffer));
if(buf==NULL) {
abort_LED(22);
error=EXT_ERROR;
goto EXIT_POINT;
}
InsertFIFOFree(buf);
}
EXIT_POINT:return(error);
}
PRIVATE void SavePkt(char *mem, int size) {
FIFOBuffer *buf = RemoveFIFOFree();
#ifdef MATLAB_MEX_FILE
/* The ack protocol NO LONGER ensures there is available space to save the pkt. -- fw-07-07 */
if(buf == NULL) {
//mexPrintf("Allocating more FIFO buffers... \n");
/* allocate another FIFOBUFNUM buffers... */
if(AddToFIFOFree() != EXT_NO_ERROR) {
/* out of memory... */
mexErrMsgTxt("Out of memory while trying to allocate more FIFO buffers...\n\r");
}
/* now get one of the newly allocated (free) FIFOs... */
buf = RemoveFIFOFree();
} /* buf == NULL */
#endif
assert(buf!=NULL);
/* The max transmission size ensures we never exceed memory when copying. */
assert(size<=MAX_SERIAL_PKT_SIZE);
memcpy(buf->pktBuf, mem, size);
buf->size=size;
buf->offset=0;
InsertFIFOPkt(buf);
}
#if DEBUG_MSG_LVL > 0
/* Debug function: display actually received contents... */
PRIVATE void DisplayActualReceivedPacket(ExtSerialPacket *pkt) {
int i;
unsigned char *myPtr = (unsigned char *)pkt;
uint32_T mySize = pkt->size;
PRINT_DEBUG_MSG_LVL1_Raw("[");
/* header (2), type (1), size (4) */
for(i=0; i<7; i++) {
PRINT_DEBUG_MSG_LVL1_Raw(" 0x");
PRINT_DEBUG_MSG_LVL1_UHex((uint16_T)(*myPtr++));
}
/* data */
for(i=0; i<mySize; i++) {
PRINT_DEBUG_MSG_LVL1_Raw(" 0x");
PRINT_DEBUG_MSG_LVL1_UHex((uint16_T)*((unsigned char *)&(pkt->Buffer[i])));
}
/* data */
myPtr = (unsigned char *)&pkt->tail;
for(i=0; i<2; i++) {
PRINT_DEBUG_MSG_LVL1_Raw(" 0x");
PRINT_DEBUG_MSG_LVL1_UHex((uint16_T)(*myPtr++));
}
PRINT_DEBUG_MSG_LVL1_Raw(" ]\n\r");
}
#endif
/***************** PRIVATE FUNCTIONS ******************************************/
/* Forward declaration */
PRIVATE boolean_T ExtSetPkt(ExtSerialPort *, char *, int, int *, PacketTypeEnum);
/* Function: ExtGetPktBlocking =================================================
* Abstract:
* Blocks until a packet is available on the comm line. If the incoming packet
* is an ACK, the packet is processed and thrown away. Otherwise, the packet
* is saved.
*
* EXT_NO_ERROR is returned on success, EXT_ERROR on failure.
*/
PRIVATE boolean_T ExtGetPktBlocking(ExtSerialPort *portDev) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -