📄 ext_svr.c
字号:
commInitialized = TRUE;
EXIT_POINT:
free(tmpBuf);
return(error);
} /* end ProcessConnectMsg */
/* Function: SendMsgHdrToHost ==================================================
* Abstract:
* Send a message header to the host.
*/
PRIVATE boolean_T SendMsgHdrToHost(
const ExtModeAction action,
const int_T size) /* # of bytes to follow msg header */
{
int_T nSet;
MsgHeader msgHdr;
boolean_T error = EXT_NO_ERROR;
msgHdr.type = (uint32_T)action;
msgHdr.size = size;
error = ExtSetHostMsg(extUD,sizeof(msgHdr),(char_T *)&msgHdr,&nSet);
if (error || (nSet != sizeof(msgHdr))) {
error = EXT_ERROR;
abort_LED(32);
goto EXIT_POINT;
}
EXIT_POINT:
return(error);
} /* end SendMsgHdrToHost */
/* Function: SendMsgDataToHost =================================================
* Abstract:
* Send message data to host. You are responsible for sending a header
* prior to sending the header.
*/
PRIVATE boolean_T SendMsgDataToHost(const char *data, const int_T size)
{
int_T nSet;
boolean_T error = EXT_NO_ERROR;
error = ExtSetHostMsg(extUD,size,data,&nSet);
if (error || (nSet != size)) {
error = EXT_ERROR;
abort_LED(33);
goto EXIT_POINT;
}
EXIT_POINT:
return(error);
} /* end SendMsgDataToHost */
/* Function: SendMsgToHost =====================================================
* Abstract:
* Send a message to the host on the message socket. Messages can be of
* two forms:
* o message header only
* the type is used as a flag to notify Simulink of an event
* that has taken place on the target (event == action == type)
* o msg header, followed by data
*/
PRIVATE boolean_T SendMsgToHost(
const ExtModeAction action,
const uint_T size, /* # of bytes to follow msg header */
const char *data)
{
boolean_T error = EXT_NO_ERROR;
error = SendMsgHdrToHost(action,size);
if (error != EXT_NO_ERROR) goto EXIT_POINT;
if (data != NULL) {
error = SendMsgDataToHost(data, size);
if (error != EXT_NO_ERROR) goto EXIT_POINT;
} else {
assert(size == 0);
}
EXIT_POINT:
return error;
} /* end SendMsgToHost */
/* Function: ProcessSetParamMsg ================================================
* Receive and process the EXT_SETPARAM message.
*/
PRIVATE boolean_T ProcessSetParamMsg(RTWExtModeInfo *ei,
const int_T msgSize)
{
const char *msg;
boolean_T error = EXT_NO_ERROR;
/*
* Receive message and set parameters.
*/
msg = GetMsg(msgSize);
if (msg == NULL) {
error = EXT_ERROR; goto EXIT_POINT;
}
SetParam(ei, msg);
/*
* Send response to host.
*/
error = SendMsgToHost(EXT_SETPARAM_RESPONSE, 0, NULL);
if (error != EXT_NO_ERROR) goto EXIT_POINT;
EXIT_POINT:
return(error);
} /* end ProcessSetParamMsg */
/* Function: ProcessGetParamsMsg ===============================================
* Respond to the hosts request for the parameters by gathering up all the
* params and sending them to the host.
*/
PRIVATE boolean_T ProcessGetParamsMsg(RTWExtModeInfo *ei)
{
int_T i;
int_T nBytesTotal;
boolean_T error = EXT_NO_ERROR;
const DataTypeTransInfo *dtInfo = rteiGetModelMappingInfo(ei);
const DataTypeTransitionTable *dtTable = dtGetParamDataTypeTrans(dtInfo);
if (dtTable != NULL) {
/*
* We've got some params in the model. Send their values to the
* host.
*/
int_T nTrans = dtGetNumTransitions(dtTable);
const uint_T *dtSizes = dtGetDataTypeSizes(dtInfo);
/*
* Take pass 1 through the transitions to figure out how many
* bytes we're going to send.
*/
nBytesTotal = 0;
for (i=0; i<nTrans; i++) {
boolean_T tranIsComplex = (boolean_T)dtTransGetComplexFlag(dtTable, i);
int_T dt = dtTransGetDataType(dtTable, i);
int_T dtSize = dtSizes[dt];
int_T elSize = dtSize * (tranIsComplex ? 2 : 1);
int_T nEls = dtTransNEls(dtTable, i);
int_T nBytes = elSize * nEls;
nBytesTotal += nBytes;
}
/*
* Send the message header.
*/
error = SendMsgHdrToHost(EXT_GETPARAMS_RESPONSE,nBytesTotal);
if (error != EXT_NO_ERROR) goto EXIT_POINT;
/*
* Take pass 2 through the transitions and send the parameters.
*/
for (i=0; i<nTrans; i++) {
char_T *tranAddress = dtTransGetAddress(dtTable, i);
boolean_T tranIsComplex = (boolean_T)dtTransGetComplexFlag(dtTable, i);
int_T dt = dtTransGetDataType(dtTable, i);
int_T dtSize = dtSizes[dt];
int_T elSize = dtSize * (tranIsComplex ? 2 : 1);
int_T nEls = dtTransNEls(dtTable, i);
int_T nBytes = elSize * nEls;
error = SendMsgDataToHost(tranAddress, nBytes);
if (error != EXT_NO_ERROR) goto EXIT_POINT;
}
} else {
/*
* We've got no params in the model.
*/
error = SendMsgHdrToHost(EXT_GETPARAMS_RESPONSE,0);
if (error != EXT_NO_ERROR) goto EXIT_POINT;
}
EXIT_POINT:
return(error);
} /* end ProcessGetParamsMsg */
/* Function: ProcessReceiveUserDataMsg ================================================
* Receive and process the message EXT_RECEIVE_USER_DATA.
*/
PRIVATE boolean_T ProcessReceiveUserDataMsg(const int_T msgSize)
{
const char *msg;
uint16_T channel;
/*
* Receive message and set the reception buffer 'userTelBuf_rxd'.
*/
msg = GetMsg(msgSize);
/* on error -> return with EXT_ERROR */
if (msg == NULL) return EXT_ERROR;
/* otherwise... */
/* determine channel number */
channel = (uint16_T)msg[1];
/* store message contents in the corresponding data buffer (incl. leading 4 bytes [tel size, channel, 2 reserved]) */
(void)memcpy(userTelBuf[channel]->buf, msg, (uint16_T)msgSize);
// would be safer... (tested -> works) FW-01-03
//memcpy(&(userTelBuf[channel]->buf[4]), &msg[4], userTelBuf[channel]->buf_size);
/* indicate the arrival of the new data telegram */
userTelBuf[channel]->buffer_full = 1;
/* successful exit*/
return EXT_NO_ERROR;
} /* end ProcessReceiveUserDataMsg */
/* Function: ProcessSetUserData ================================================
* send user data to the host
*/
PRIVATE void ProcessSetUserData(void)
{
int_T req_channel;
/* reset next_user_channel_index if required */
if(next_user_channel_index == num_user_channels_active) next_user_channel_index = 0;
/* get channel number to be serviced next */
req_channel = user_txd_queue[next_user_channel_index++];
/* check if the contents of the selected buffer have changed */
if(userTelBuf[req_channel]->buffer_full == 1) {
uint8_T *buf = userTelBuf[req_channel]->buf;
/* yes -> send user telegram (first byte = telegram size, set during mdlStart() of the associated S-Function) */
(void)ExtSetHostUserData((int_T)buf[0], (const signed char *)buf);
/* clear buffer full flag */
userTelBuf[req_channel]->buffer_full = 0;
} /* new data available */
} /* end ProcessSetUserData */
/*********************
* Visible Functions *
*********************/
/* Function: ExtSetWaitForStartMsg ============================================
* Abstract:
* Define the target behaviour w/h regard to 'wait for start msg'
*/
PUBLIC void ExtSetWaitForStartMsg(unsigned int w4start)
{
/* fw-10-05 */
if(w4start == TRUE) {
/* wait for start Msg from host */
extUD->waitForStartMsg = TRUE;
startModel = FALSE;
} else {
/* don't wait, start upon reset */
extUD->waitForStartMsg = FALSE;
startModel = TRUE;
}
} /* end ExtSetWaitForStartMsg */
/* Function: ExtWaitForStartMsg ================================================
* Abstract:
* Return true if waiting for host to tell us when to start.
*/
PUBLIC boolean_T ExtWaitForStartMsg(void)
{
return(ExtWaitForStartMsgFromHost(extUD));
} /* end ExtWaitForStartMsg */
/* Function: rt_UploadServerWork ===============================================
* Abstract:
* Upload model signals to host.
*/
PUBLIC boolean_T rt_UploadServerWork(void) {
int_T nSet, nBytesToSet;
boolean_T error = EXT_NO_ERROR;
char *bufPtr;
#if DEBUG2SCI0 >= 3
SCI0_OutString("rt_UploadServerWork: IN\n\r");
#endif
//if(TXactive) PORTB |= 0x02; /* LED2 on */
//if(bufenable) PORTB |= 0x04; /* LED3 on */
if ((ringBuf.nRecords > 0) && bufenable && TXactive) {
//PORTB |= 0x08;
/* Check whether tail has reached the end of the buffer, marked by mc_main '0' */
if (*(ringBuf.buf + ringBuf.tail + 3) == 0) {
/* '+3' ... byte inversion on 9S12 -- fw-03-05 */
// if (*(ringBuf.buf + ringBuf.tail) == 0) {
ringBuf.tail = 0;
//abort_LED(19);
}
nBytesToSet = *(ringBuf.buf + ringBuf.tail + 3); /* '+3' ... 9S12 -- fw-03-05 */
// nBytesToSet = *(ringBuf.buf + ringBuf.tail);
bufPtr = (char *) (ringBuf.buf + ringBuf.tail);
error = ExtSetHostData(extUD, nBytesToSet, bufPtr, &nSet );
if (error || (nSet != nBytesToSet)) {
if(nBytesToSet < 0) abort_LED(11);
if(nSet == 0) abort_LED(33);
abort_LED(26);
}
else {
ringBuf.tail += nSet;
/* decrease message counter -- fw-03-05 */
ringBuf.nRecords--;
}
/* deactivate TXactive flag (re-activated on demand, by the host) -- (FW-10-02) */
TXactive = FALSE;
//PORTB &= ~0x08;
}
//PORTB &= ~0x02; /* LED2 off */
//PORTB &= ~0x04; /* LED3 off */
#if DEBUG2SCI0 >= 3
SCI0_OutString("rt_UploadServerWork: OUT\n\r");
#endif
/* this is only reached if error == EXT_NO_ERROR */
return error;
} /* end rt_UploadServerWork */
/* Function: rt_ExtModeInit ====================================================
* Abstract:
* Called once at program startup to do any initialization related to external
* mode.
*/
PUBLIC void rt_ExtModeInit(void)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -