/*
*********************************************************************************************************
*
* 模块名称 : TCPnet网络协议栈测试
* 文件名称 : app_tcpnet_lib.c
* 版 本 : V1.0
* 说 明 : 测试的功能说明
* 1. 强烈推荐将网线接到路由器或者交换机上面测试,因为已经使能了DHCP,可以自动获取IP地址。
* 2. 客户端的例子相比服务器的例子稍麻烦些,因为客户端的例子需要用户知道电脑端IP和端口号。
* 并根据实际情况设置IP和端口号的宏定义,这个配置在文件app_tcpnet_lib.c开头,测试的时
* 候板子要连接这个IP和端口(下面是默认配置,一定要根据实际情况重新配置,如果不会配置,
* 看本例程对应的教程即可):
* #define IP1 192
* #define IP2 168
* #define IP3 1
* #define IP4 2
* #define PORT_NUM 1001
* 3. 本例程创建了一个socket客户端,采用的TCP通信协议,而且使能了局域网域名NetBIOS,用户只
* 需在电脑端ping armfly就可以获得板子的IP地址。
* 4. 测试例子前,需要用户先在电脑端用网络调试软件创建TCP Server,然后让板子的客户端去连接。
* 5. 网络调试助手发送命令字符1,板子回复字符1到8以及回车和换行两个字符,共10个。
* 6. 网络调试助手发送命令字符2,板子回复1024个字符,前4个字符是abcd,最后4个字符是efgh,
* 中间的1016个全部是字符0。
*
* 修改记录 :
* 版本号 日期 作者 说明
* V1.0 2017-04-17 Eric2013 首发
*
* Copyright (C), 2015-2020, 安富莱电子 www.armfly.com
*
*********************************************************************************************************
*/
#include "includes.h"
u16 megPerror = 0;
extern char myMachineID[];
extern u8 error_type;
/*
*********************************************************************************************************
* 用于本文件的调试
*********************************************************************************************************
*/
#if 1
#define printf_debug printf
#else
#define printf_debug(...)
#endif
extern char str[128];
extern u8 str_len ;
/*
*********************************************************************************************************
* 宏定义,远程服务器的IP和端口
*********************************************************************************************************
*/
/* 要访问的远程服务器IP和端口配置,也就是电脑端调试助手设置的IP和端口号 */
#define IP1 172
#define IP2 17
#define IP3 110
#define IP4 193
#define PORT_NUM 3001
#define sPORT_NUM 3000
#define LogPORT_NUM 3500
/*
*********************************************************************************************************
* 变量
*********************************************************************************************************
*/
/* RL-TCPnet API的返回值 */
const char* ReVal_Table[] =
{
" 0: SCK_SUCCESS Success ",
"-1: SCK_ERROR General Error ",
"-2: SCK_EINVALID Invalid socket descriptor ",
"-3: SCK_EINVALIDPARA Invalid parameter ",
"-4: SCK_EWOULDBLOCK It would have blocked. ",
"-5: SCK_EMEMNOTAVAIL Not enough memory in memory pool ",
"-6: SCK_ECLOSED Connection is closed or aborted ",
"-7: SCK_ELOCKED Socket is locked in RTX environment ",
"-8: SCK_ETIMEOUT Socket, Host Resolver timeout ",
"-9: SCK_EINPROGRESS Host Name resolving in progress ",
"-10: SCK_ENONAME Host Name not existing ",
};
uint8_t sendbuf[5];
char dbuf[1024] __attribute__((at(0x20000000)));
char rbuf[61440] __attribute__((at(0x20010000)));
u32 rbufIndex = 0;
extern u8 backReagentInf;
char* packet;
//extern u8 dateSetFlag;
extern u8 app_time_tick;
extern S_ITEM my_Item;
extern OS_TID HandleTaskCPM;
extern S_COMP_CPM comp_CPM;
extern u8 item_save_index;
//extern u8 selfTest;
extern OS_TID HandleTaskITEM;
extern OS_TID HandleTaskSAB;
extern OS_TID HandleTaskRAA;
extern OS_TID HandleTaskRAB;
extern OS_TID HandleTaskRAC;
extern u8 firstGet4106;
//extern u8 isReturnError;
extern u8 scanTest;
extern u8 Cmd202BufferIndex;
extern S_INSTRUMENT myInstrement;
//#define PoolBlocks 60
//#define PoolPerBlockSize 1024
///* 声明一个内存池,64 块,每块大小 1024 字节 */
//_declare_box(reciveBuff, PoolPerBlockSize, PoolBlocks);
//TCP接收指针数组
//u8 *reciveBuff;
//u8 reciveBuffIndex = 0;
extern uint8_t C3T_data_buff[4096];
extern u16 C3T_index_save;
extern u16 C3T_index_run;
extern u8 EthLogFlag ;
extern S_REAGENT_MEAS s_reagent_meas;
extern ERROR_INF now_Error;
//声明一个用于 接收处理的网络邮箱
os_mbx_declare(net_rec_mailbox, 5);
//声明一个用于 发送处理的网络邮箱
os_mbx_declare(net_send_mailbox, 5);
u8 eepromWriteSta1 = 0, eepromWriteSta2 = 0;
//u8 sendAI104=0;
u8 indexLinshi = 0;
u32 ScodeIndex = 0;
u32 DebugSamInfBufIndex = 0;
S_SAMPLE_INF DebugSamInfBuf[10];
u32 unitID, unitDA, unitOffset;
extern u8 SABmode;
extern S_BARCODE_SCAN s_barcode_Scan;
/*
*********************************************************************************************************
* 函 数 名: 网络接收线程
* 功能说明: TCPnet应用
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void TcpRec(u8 appPriority)
{
int len;
int sock, res;
unsigned long sck_mode;
SOCKADDR_IN addr;
u8 rcFlag = 0;
int rc_index = 0;
int save_index = 0;
int num3 = 0;
int num4 = 0;
char num6 = 0;
int num5 = 0;
int send_flag = 0;
int send_lenght = 0;
int current_Cmd;
/* 初始化内存池,4 字节对齐,*/
// _init_box (reciveBuff, sizeof (reciveBuff), PoolBlocks);
//创建接收邮箱 初始化
os_mbx_init(&net_rec_mailbox, sizeof(net_rec_mailbox));
while(1)
{
/* 创建一个socket
第1个参数AF_INET:当前仅支持这个类型的地址族。
第2个参数SOCK_STREAM:表示数据流通信类型,即使用的TCP。
第3个参数0 :配置为0的话,自动跟第2个参数进行协议匹配,这里就是TCP协议。
*/
sock = socket(AF_INET, SOCK_STREAM, 0);
/* 设置使能KEEP ALIVE,让客户端和服务器保存连接 */
sck_mode = 1;
res = ioctlsocket(sock, FIO_KEEP_ALIVE, &sck_mode);
if(res == SCK_SUCCESS)
{
printf_debug("KEEP ALIVE设置成功\r\n");
}
else
{
printf_debug("KEEP ALIVE设置失败\r\n");
}
/* 端口号设置为3001 */
addr.sin_port = htons(PORT_NUM);
/* 与函数socket中的AF_INET作用一样 */
addr.sin_family = PF_INET;
addr.sin_addr.s_b1 = IP1;
addr.sin_addr.s_b2 = IP2;
addr.sin_addr.s_b3 = IP3;
addr.sin_addr.s_b4 = IP4;
/* 客户端连接远程服务器,如果远程服务器还未创建,此函数会立即返回 */
res = connect(sock, (SOCKADDR*)&addr, sizeof(addr));
printf_debug("TCP接收线程状态%s\r\n", ReVal_Table[abs(res)]);
while(1)
{
/*
socket数据接收函数,如果recv工作在阻塞模式,使用这个函数注意以下事项:
1. 此函数的溢出时间受到Net_Config.c中宏定义 BSD_RCVTOUT 的限制。溢出时间到会自动退出。
2. 这个函数接收到一次数据包就会返回,大于或者小于设置的缓冲区大小都没有关系,如果数据量
大于接收缓冲区大小,用户只需多次调用函数recv进行接收即可。
3. 实际接收到数据大小通过判断此函数的返回值即可。
*/
//rc_index = 0;
res = recv(sock, dbuf, sizeof(dbuf), 0);
if(res <= 0)
{
// if(MsgIndex>0)
// {
// _free_box(reciveBuff,pucMsg[MsgIndex]);
// MsgIndex--;
// }
printf_debug("接收函数返回状态%s\r\n", ReVal_Table[abs(res)]);
if((res == SCK_EINVALID) || (res == SCK_ECLOSED))
{
break;
}
//break;
}
else
{
//printf_debug("收到一个包----当前时间为--%d---,时基序号为---%d---\r\n",app_time_tick,app_time_tick_number);
while(rc_index < res)
{
num6 = dbuf[rc_index];
if(rcFlag > 0)
{
//存一个数据
rbuf[num5++] = num6;
}
switch(rcFlag)
{
case 0:
//0x02 开始标志
if(num6 == 2)
{
//printf_debug("开始收完02!!----当前时间为--%d---,时基序号为---%d---\r\n",app_time_tick,app_time_tick_number);
//将2存进来
//rbuf[num5++] = num6;
//num5++;
#if Dubug_Log
//printf_debug("开始收完02!!----当前时间为--%d---,时基序号为---%d---\r\n",app_time_tick,app_time_tick_number);
printf_debug("%02X::%d:%d::[RcvTCPnet]:I-A:Rcv start Flag.\r\n", RTC->TR, app_time_tick_number, app_time_tick);
#endif
current_Cmd = 0;
save_index = 0;
rcFlag = 1;
}
break;
case 1:
if(save_index < 36)
{
if(save_index > 15 && save_index < 20)
{
//计算命令代号 CMD
current_Cmd |= (255 & num6) << 8 * (save_index - 16);
}
save_index++;
}
else
{
rcFlag = 2;
num3 = (255 & num6);
save_index = 1;
}
break;
case 2:
if(save_index < 4)
{
//计算有效数据长度
num3 |= (255 & num6) << 8 * save_index;
save_index++;
}
else
{
if(num3 > 0)
{
rcFlag = 3;
}
else
{
rcFlag = 4;
num4 = (255 & num6);
}
save_index = 1;
}
break;
case 3:
{
if(save_index < num3)
{
save_index++;
}
else
{
rcFlag = 4;
num4 = (255 & num6);
save_index = 1;
}
break;
}
case 4:
{
if(save_index < 4)
{
//计算CRC校验
num4 = (num4 << 8 | (255 & num6));
save_index++;
}
else
{
rcFlag = 0;
if(num6 == 3)
{
//将接收到的整段命令数据发送到邮箱 根据命令代号存储吗? 因考虑优先级问题
uint8_t* pucMsg;
//根据命令类型 获取存储信息的结构体地址
pucMsg = getCreatReciveData(current_Cmd);
if(pucMsg != 0)
{
memcpy(pucMsg, rbuf, num5 - 5);
printf_debug("%02X,%d-%02d,%02d,I2A,ID=%d,bytes=%d.\r\n", RTC->TR, app_time_tick_number, app_time_tick, appPriority, current_Cmd, num5 - 1);
current_Cmd = 0;
if(os_mbx_send(&net_rec_mailbox, pucMsg, 100) != OS_R_OK)
{
#if Dubug_Log
printf_debug("%02X::%d:%d::[RcvTCPnet]:I-A:ID=%d,Rcv to mail Failed.\r\n", RTC->TR, app_time_tick_number, app_time_tick, current_Cmd);
#endif
}
else
{
#if Dubug_Log
printf_debug("%02X::%d:%d::[RcvTCPnet]:I-A:ID=%d,Rcv to mail Succeed.\r\n", RTC->TR, app_time_tick_number, app_time_tick, current_Cmd);
#endif
}
}
else
{
megPerror++;
printf_debug("%02X,%d-%02d,%02d,I2A,No.%d,Rcv abnormal Command.\r\n", RTC->TR, app_time_tick_number, app_time_tick, appPriority, megPerror);
}
//_free_box(reciveBuff,pucMsg);
}
else
{
//printf_debug("数据接收不正确!!!!");
printf_debug("%02X,%d-%02d,%02d,I2A,Rcv Error Cmd\r\n", RTC->TR, app_time_tick_number, app_time_tick, appPriority);
//数据存在问题
}
num5 = 0;
}
break;
}
}
rc_index++;
}
//printf_debug("处理完了这个包----当前时间为--%d---,时基序号为---%d---\r\n",app_time_tick,app_time_tick_number);
rc_index = 0;
}
}
/*
远程服务器断开连接和sock句柄无效,程序都会执行到这里,我们在这里关闭socket,
程序返回到第一个大while循环的开头重新创建socket并连接。
*/
closesocket(sock);
}
}
/*
*********************************************************************************************************
* 函 数 名: 网络接收处理线程
* 功能说明: TCPnet应用
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void TcpRecHander(u8 appPriority)
{
uint8_t* pMsg;
uint8_t i;
CmdHed* myCmdHed;
void* myCmd;
OS_RESULT xResult;
const uint16_t usMaxBlockTime = 200; /* 延迟周期 */
uint8_t index;
uint8_t startSta = 0xAB;
uint8_t reagErrBit = 0;
u32 temp_volume=0;
u8 temp_sta=0;
while(1)
{
//等待网络接收邮箱中 是否有待处理的数据
xResult = os_mbx_wait(&net_rec_mailbox, (void*)&pMsg, usMaxBlockTime);
if(xResult == OS_R_OK || xResult == OS_R_MBX)
{
//前36个字节为 命令头
myCmdHed = (CmdHed*) pMsg;
printf_debug("%02X,%d-%02d,%02d,I2A,ID=%d,Rcv Command\r\n", RTC->TR, app_time_tick_number, app_time_tick, appPriority, myCmdHed->ulCmd);
switch(myCmdHed->ulCmd)
{
case I2A_ComponentSetup:
{
ISA_param_init();
Device6500InitStatus = IniStatus_Get10002;
printf_debug("%02X,%d-%02d,%02d,I2A_ComponentSetup\r\n", RTC->TR, app_time_tick_number, app_time_tick, appPriority);
break;
}
case I2A_ComponentAction:
{
Device6500InitStatus = IniStatus_Get10004;
printf_debug("%02X,%d-%02d,%02d,I2A_ComponentAction\r\n", RTC->TR, app_time_tick_number, app_time_tick, appPriority);
break;
}
case I2A_ReagentCalibration:
{
Device6500InitStatus = IniStatus_Get10006;
printf_debug("%02X,%d-%02d,%02d,I2A_ReagentCalibration\r\n", RTC->TR, app_time_tick_number, app_time_tick, appPriority);
break;
}
case I2A_StartSetup:
{
Device6500InitStatus = IniStatus_Get10008;
printf_debug("%02X,%d-%02d,%02d,I2A_StartSetup\r\n", RTC->TR, app_time_tick_number, app_time_tick, appPriority);
break;
}
case I2A_AdminAuthority:
{
comp_CBC.usCkeckMode = i_S_I2A_AdminAuthority.isPlanAssign;
s_Device.usIsAdjustMode= i_S_I2A_AdminAuthority.netDebug;
s_Device.usIsCloseLight = i_S_I2A_AdminAuthority.closeLight;
//UseLamp();
OpenLamp();
Device6500InitStatus = IniStatus_Get10010;
printf_debug("%02X,%d-%02d,%02d,I2A_AdminAuthority\r\n", RTC->TR, app_time_tick_number, app_time_tick, appPriority);
break;
}
case I2A_ErrorSolution:
{
Device6500InitStatus = IniStatus_Get10012;
printf_debug("%02X,%d-%02d,%02d,I2A_ErrorSolution\r\n", RTC->TR, app_time_tick_number, app_time_tick, appPriority);
break;
}
case I2A_SynchroTime:
{
Device6500InitStatus = IniStatus_Get10014;
//日期设置
myCurrentTime._usYear = i_S_I2A_SynchroTime.year;
myCurrentTime._ucMonth = i_S_I2A_SynchroTime.month;
myCurrentTime._ucDay = i_S_I2A_SynchroTime.day;
myCurrentTime._ucHour = i_S_I2A_SynchroTime.hour;
myCurrentTime._ucMinute = i_S_I2A_SynchroTime.minute;
myCurrentTime._ucSecond = i_S_I2A_SynchroTime.second;
RTC_mySetDate(myCurrentTime._usYear, myCurrentTime._ucMonth, myCurrentTime._ucDay);
RTC_mySetTime(myCurrentTime._ucHour, myCurrentTime._ucMinute, myCurrentTime._ucSecond);
printf_debug("%02X,%d-%02d,%02d,I2A_SynchroTime\r\n", RTC->TR, app_time_tick_number, app_time_tick, appPriority);
break;
}
case I2A_AssayGroup:
{
Device6500InitStatus = IniStatus_Get10016;
printf_debug("%02X,%d-%02d,%02d,I2A_AssayGroup\r\n", RTC->TR, app_time_tick_number, app_time_tick, appPriority);
break;
}
case I2A_RegisterReagent:
{
if(i_S_I2A_RegisterReagent.registerReagent.table)
{
index = 42+i_S_I2A_RegisterReagent.registerReagent.position;
}
else
{
index = i_S_I2A_RegisterReagent.registerReagent.rack*7+i_S_I2A_RegisterReagent.registerReagent.position;
}
temp_volume =i_S_I2A_RegisterReagentList.reagentList[index].volume;
memcpy(&i_S_I2A_RegisterReagentList.reagentList[index], &i_S_I2A_RegisterReagent.registerReagent, sizeof(i_S_I2A_RegisterReagent.registerReagent));
i_S_I2A_RegisterReagentList.reagentList[index].volume =temp_volume;
printf_debug("%02X,%d-%02d,%02d,I2A_RegisterReagent table-%d,rack-%d,pos-%d \r\n", RTC->TR, app_time_tick_number, app_time_tick,appPriority,
i_S_I2A_RegisterReagent.registerReagent.table,
i_S_I2A_RegisterReagent.registerReagent.rack,
i_S_I2A_RegisterReagent.registerReagent.position);
break;
}
case I2A_RegisterReagentList:
{
printf_debug("%02X,%d-%02d,%02d,I2A_RegisterReagent_Once\r\n", RTC->TR, app_time_tick_number, app_time_tick, appPriority);
break;
}
case I2A_ReagentVolumeDetection:
{
// s_reagent_meas.usMeasRAAStage =1;
// s_reagent_meas.usMeasSAAStage =1;
ReagMeasStartCheck();
printf_debug("%02X,%d-%02d,%02d,I2A_ReagentVolumeDetection\r\n", RTC->TR, app_time_tick_number, app_time_tick, appPriority);
break;
}
case I2A_RequestCheckStart:
{
//设备状态自检
temp_sta =1;
//清除标记的过程中的错误信息
ClearErrorInf(ERROR_CLEAR_START);
//请求开始时 打开光源
//UseLamp();
OpenLamp();
//外设状态检验
if(ExternalDeviceStartCheck())
{
printf_debug("%02X,%d-%02d,%02d,I2A_DetectStart,device external error\r\n", RTC->TR, app_time_tick_number, app_time_tick, appPriority);
temp_sta=0;
}
//舱盖和急停按键
if(Instrument_cover_status_check())
{
printf_debug("%02X,%d-%02d,%02d,I2A_DetectStart,device cover_status error\r\n", RTC->TR, app_time_tick_number, app_time_tick, appPriority);
temp_sta=0;
}
//如果当前比色杯供给发生问题 再次点击开始时 继续供给
if(comp_CSCU.usSupplyError)
{
printf_debug("%02X,%d-%02d,%02d,I2A_DetectStart,CSU dish back \r\n", RTC->TR, app_time_tick_number, app_time_tick, appPriority);
Cscu_Dish_Back_SetEvt();
temp_sta=0;
}
if(a_S_A2I_SystemStatus.systemStatus.machineStatus == InstrumentStatus_Ready)
{
os_dly_wait(500);
if(CheckNoLampLight(0,0,1000) == 0)
{
SaveCheckErrorCode(22044,ERROR_CLEAR_CLOSE);
printf_debug("%02X,%d-%02d,%02d,I2A_DetectStart,Light Error\r\n", RTC->TR, app_time_tick_number, app_time_tick, appPriority);
temp_sta=0;
}
}
//开始检查有错误 返回
a_S_A2I_ReplyCheckStart.ratify = temp_sta;
TcpSendMail(&a_S_A2I_ReplyCheckStart.STARTFlag);
break;
}
case I2A_DetectStart:
{
// //清除标记的过程中的错误信息
// ClearErrorInf(ERROR_CLEAR_START);
//
// //外设状态检验
// if(ExternalDeviceStartCheck())
// {
// printf_debug("%02X,%d-%02d,%02d,I2A_DetectStart,device external error\r\n", RTC->TR, app_time_tick_number, app_time_tick, appPriority);
// break;
// }
// //舱盖和急停按键
// if(Instrument_cover_status_check())
// {
// printf_debug("%02X,%d-%02d,%02d,I2A_DetectStart,device cover_status error\r\n", RTC->TR, app_time_tick_number, app_time_tick, appPriority);
// break;
// }
// //如果当前比色杯供给发生问题 再次点击开始时 继续供给
// if(comp_CSCU.usSupplyError)
// {
// printf_debug("%02X,%d-%02d,%02d,I2A_DetectStart,CSU dish back \r\n", RTC->TR, app_time_tick_number, app_time_tick, appPriority);
// Cscu_Dish_Back_SetEvt();
// break;
//
// }
SetLockSta(LOCK_STA_LOCK);
if(a_S_A2I_SystemStatus.systemStatus.machineStatus ==InstrumentStatus_Interrupted)
{
Protocol_Limit_Cancel();
ItemPauseCancel();
printf_debug("%02X,%d-%02d,%02d,I2A_DetectStart,interrupted status change to processing\r\n", RTC->TR, app_time_tick_number, app_time_tick, appPriority);
}
a_S_A2I_SystemStatus.systemStatus.machineStatus = InstrumentStatus_Processing;
//临时添加 保证开始的时候开启
my_Item.usProcotolReqEnable=1;
my_Item.usEnable =1;
printf_debug("%02X,%d-%02d,%02d,I2A_DetectStart\r\n", RTC->TR, app_time_tick_number, app_time_tick, appPriority);
break;
}
case I2A_TubeProtocol:
{
os_evt_set(ITEM_PROTO_RSP, HandleTaskITEM);
printf_debug("%02X,%d-%02d,%02d,I2A_TubeProtocol\r\n", RTC->TR, app_time_tick_number, app_time_tick, appPriority);
break;
}
case I2A_ParamDebug:
{
send_adjust_param();
printf_debug("%02X,%d-%02d,%02d,I2A_TubeProtocol\r\n", RTC->TR, app_time_tick_number, app_time_tick, appPriority);
break;
}
case I2A_AdjustTemperature:
{
SetAdjustTemperaInfo();
break;
}
case I2A_WarningClear:
{
ClearErrorInf(ERROR_CLEAR_CLOSE);
break;
}
case I2A_SmpRackLockSta:
{
UpdataSmpRackLockSta();
break;
}
case I2A_ReagRackLockSta:
{
UpdataReagRackLockSta();
break;
}
case I2A_ReplyTipNotify:
{
ClearWarningInf();
break;
}
case I2A_ForceOperation:
{
ForceOperation();
break;
}
case I2A_ShieldChannel:
{
DetChannelShield();
break;
}
case I2A_CheckChannelWare:
{
if(i_S_I2A_CheckChannelWare.enable)
EnableBackOptFrameInfo();
else
DisableBackOptFrameInfo();
break;
}
case I2A_ForceUnlock:
{
//释放所有架状态
//ReleaseAllRackLockSta();
if(i_S_I2A_ForceUnlock.area ==1)
{
i_S_I2A_ForceUnlock.reserved[0] = i_S_I2A_ForceUnlock.rackNo;
}
else
{
if(i_S_I2A_ForceUnlock.table ==2)
i_S_I2A_ForceUnlock.reserved[0] = 10;
else
i_S_I2A_ForceUnlock.reserved[0] = 11+i_S_I2A_ForceUnlock.rackNo;
}
ReleaseRackLockSta(i_S_I2A_ForceUnlock.reserved[0]);
break;
}
case I2A_MotorParamStrp:
{
SetMotorParam();
Device6500InitStatus = IniStatus_Get10036;
break;
}
case I2A_BloodCalibration:
{
Device6500InitStatus = IniStatus_Get10038;;
break;
}
case I2A_TubeCalibration:
{
Device6500InitStatus = IniStatus_Get10040;
break;
}
case I2A_DetWaveParam:
{
Device6500InitStatus = IniStatus_Get10042;
break;
}
case I2A_IAP_DATA:
{
//发送更新数据
SendAppData();
break;
}
case I2A_IAP_END:
{
SetIapEnd();
break;
}
default:
{
break;
}
}
}
}
}
/*
*********************************************************************************************************
* 函 数 名: 网络发送线程
* 功能说明: TCPnet应用
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void SendTCPnetTest(u8 appPriority)
{
int len;
int sock, res;
unsigned long sck_mode;
SOCKADDR_IN addr;
u8 lenIndex = 0;
u8 lenNum = 0;
int send_flag = 0;
int send_lenght = 0;
uint8_t* pMsg;
OS_RESULT xResult;
u32 SendId = 0;
u8 nullP;
const uint16_t usMaxBlockTime = 200; /* 延迟周期 */
//创建接收邮箱 初始化
os_mbx_init(&net_send_mailbox, sizeof(net_send_mailbox));
while(1)
{
/* 创建一个socket
第1个参数AF_INET:当前仅支持这个类型的地址族。
第2个参数SOCK_STREAM:表示数据流通信类型,即使用的TCP。
第3个参数0 :配置为0的话,自动跟第2个参数进行协议匹配,这里就是TCP协议。
*/
sock = socket(AF_INET, SOCK_STREAM, 0);
/* 设置使能KEEP ALIVE,让客户端和服务器保存连接 */
sck_mode = 1;
res = ioctlsocket(sock, FIO_KEEP_ALIVE, &sck_mode);
if(res == SCK_SUCCESS)
{
//printf_debug("KEEP ALIVE设置成功\r\n");
}
else
{
//printf_debug("KEEP ALIVE设置失败\r\n");
}
/* 端口号设置为1001 */
addr.sin_port = htons(sPORT_NUM);
/* 与函数socket中的AF_INET作用一样 */
addr.sin_family = PF_INET;
addr.sin_addr.s_b1 = IP1;
addr.sin_addr.s_b2 = IP2;
addr.sin_addr.s_b3 = IP3;
addr.sin_addr.s_b4 = IP4;
/* 客户端连接远程服务器,如果远程服务器还未创建,此函数会立即返回 */
res = connect(sock, (SOCKADDR*)&addr, sizeof(addr));
//printf_debug("TCP发送线程状态%s\r\n", ReVal_Table[abs(res)]);
//客户端已连接 发送 设备信息 给远程主机
if(res == 0)
{
ScodeIndex = 0;
//TcpSendMail(&_sGreInf.STARTFlag);
//首次连接后 设备初始状态标志位 置位初始等待设备序列号状态
//DeviceInitStatus = IniStatus_WaitMachineId;
Device6500InitStatus = IniStatus_WaitSetup;
a_S_A2I_SystemStatus.systemStatus.machineStatus = InstrumentStatus_NotReady;
if(s_Device.usInitStatus ==CO_INIT)
{
s_Device.usIsWakeUpStage =1;
}
else
{
task_net_connect();
}
//LedStartStatus();
while(1)
{
/*
socket数据接收函数,如果recv工作在阻塞模式,使用这个函数注意以下事项:
1. 此函数的溢出时间受到Net_Config.c中宏定义 BSD_RCVTOUT 的限制。溢出时间到会自动退出。
2. 这个函数接收到一次数据包就会返回,大于或者小于设置的缓冲区大小都没有关系,如果数据量
大于接收缓冲区大小,用户只需多次调用函数recv进行接收即可。
3. 实际接收到数据大小通过判断此函数的返回值即可。
*/
//等待发送邮箱 队列
//此处为等待邮箱 不存在是否连接的问题 需要判定 是否连接正常
xResult = os_mbx_wait(&net_send_mailbox, (void*)&pMsg, 200);
if(xResult == OS_R_OK || xResult == OS_R_MBX)
{
len = 0;
SendId = 0;
//获取待发送数据的长度
lenIndex = 0;
while(lenIndex < 4)
{
lenNum = (u8)(*(pMsg + 37 + lenIndex));
len |= (255 & lenNum) << 8 * lenIndex;
lenNum = (u8)(*(pMsg + 17 + lenIndex));
SendId |= (255 & lenNum) << 8 * lenIndex;
lenIndex++;
}
#if Dubug_Log
printf_debug("%02X,%d-%02d,%02d,A:ID=%d:Send start.\r\n", RTC->TR, app_time_tick_number, app_time_tick, appPriority, SendId);
#endif
res = send(sock, (char*)pMsg, len + 46, 0);
if(res < 0)
{
printf_debug("%02X,%d-%02d,%02d,A2I,ID=%d:Send Faild!:Error=%s\r\n", RTC->TR, app_time_tick_number, app_time_tick, appPriority, SendId, ReVal_Table[abs(res)]);
if((res == SCK_EINVALID) || (res == SCK_ECLOSED))
{
now_Error.CanID = 1;
now_Error.Comstr[0] = 'N';
now_Error.Comstr[1] = 'E';
now_Error.Comstr[2] = 'T';
now_Error.CommandStr[0] = 'N';
now_Error.CommandStr[1] = 'O';
now_Error.ulErrCode = 31000;
//触发中断
//taskRunErr =1;
// err_set_evt();
bsp_instrumentInitPara();
//可能还需要初始化其他的变量
// s_Device.usInitStatus = UN_INIT;
Device6500InitStatus = IniStatus_WaitConnect;
Usertask_Delete();
DeviceAllPowerOff();
break;
}
}
else
{
printf_debug("%02X,%d-%02d,%02d,A2I,ID=%d success\r\n", RTC->TR, app_time_tick_number, app_time_tick, appPriority, SendId, res);
// str_len = sprintf(str,"%02X,%d-%02d,%02d,A:ID=%d success\r\n", RTC->TR,app_time_tick_number,app_time_tick,appPriority,SendId);
// printfNet_str(str,str_len);
}
}
else
{
if(res < 0)
{
printf_debug("%02X,%d-%02d,%02d,Disconnect\r\n", RTC->TR, app_time_tick_number, app_time_tick, appPriority);
if((res == SCK_EINVALID) || (res == SCK_ECLOSED))
{
now_Error.CanID = 1;
now_Error.Comstr[0] = 'N';
now_Error.Comstr[1] = 'E';
now_Error.Comstr[2] = 'T';
now_Error.CommandStr[0] = 'N';
now_Error.CommandStr[1] = 'O';
now_Error.ulErrCode = 31000;
//触发中断
taskRunErr =1;
// err_set_evt();
// s_Device.usInitStatus = UN_INIT;
DeviceInitStatus = IniStatus_WaitConnect;
break;
}
}
}
}
}
//清空发送邮箱中数据
while(os_mbx_wait(&net_send_mailbox, (void*)&pMsg, 20) != OS_R_TMO);
closesocket(sock);
os_dly_wait(3000);
}
}
/*
*********************************************************************************************************
* 函 数 名: 网络日志发送线程
* 功能说明: TCPnet应用
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void SendTCPnetLog(void)
{
int len;
u16 tempSave = 0;
int sock, res;
unsigned long sck_mode;
SOCKADDR_IN addr;
u8 lenIndex = 0;
u8 lenNum = 0;
int send_flag = 0;
int send_lenght = 0;
uint8_t* pMsg;
OS_RESULT xResult;
u32 SendId = 0;
u8 nullP;
const uint16_t usMaxBlockTime = 200; /* 延迟周期 */
/* 设置延迟周期 */
const uint16_t usFrequency = 200; /* 延迟周期 */
os_itv_set(usFrequency);
while(1)
{
/* 创建一个socket
第1个参数AF_INET:当前仅支持这个类型的地址族。
第2个参数SOCK_STREAM:表示数据流通信类型,即使用的TCP。
第3个参数0 :配置为0的话,自动跟第2个参数进行协议匹配,这里就是TCP协议。
*/
sock = socket(AF_INET, SOCK_STREAM, 0);
/* 设置使能KEEP ALIVE,让客户端和服务器保存连接 */
sck_mode = 1;
res = ioctlsocket(sock, FIO_KEEP_ALIVE, &sck_mode);
if(res == SCK_SUCCESS)
{
//printf_debug("KEEP ALIVE设置成功\r\n");
}
else
{
//printf_debug("KEEP ALIVE设置失败\r\n");
}
/* 端口号设置为1001 */
addr.sin_port = htons(LogPORT_NUM);
/* 与函数socket中的AF_INET作用一样 */
addr.sin_family = PF_INET;
addr.sin_addr.s_b1 = IP1;
addr.sin_addr.s_b2 = IP2;
addr.sin_addr.s_b3 = IP3;
addr.sin_addr.s_b4 = IP4;
/* 客户端连接远程服务器,如果远程服务器还未创建,此函数会立即返回 */
res = connect(sock, (SOCKADDR*)&addr, sizeof(addr));
//printf_debug("TCP发送线程状态%s\r\n", ReVal_Table[abs(res)]);
//客户端已连接 发送 设备信息 给远程主机
if(res == 0)
{
while(1)
{
/*
socket数据接收函数,如果recv工作在阻塞模式,使用这个函数注意以下事项:
1. 此函数的溢出时间受到Net_Config.c中宏定义 BSD_RCVTOUT 的限制。溢出时间到会自动退出。
2. 这个函数接收到一次数据包就会返回,大于或者小于设置的缓冲区大小都没有关系,如果数据量
大于接收缓冲区大小,用户只需多次调用函数recv进行接收即可。
3. 实际接收到数据大小通过判断此函数的返回值即可。
*/
EthLogFlag = 1;
// if(C3T_index_save != C3T_index_run)
// {
// tempSave = C3T_index_save;
// pMsg = &C3T_data_buff[C3T_index_run];
// if(tempSave > C3T_index_run)
// {
// res = send(sock, (char*)pMsg, tempSave - C3T_index_run, 0);
// C3T_index_run = tempSave;
// }
// else
// {
// res = send(sock, (char*)pMsg, 4096 - C3T_index_run, 0);
// C3T_index_run = 0;
// }
// if(res < 0)
// {
// if((res == SCK_EINVALID) || (res == SCK_ECLOSED))
// {
// EthLogFlag = 0;
// break;
// }
// }
// }
if(C3T_index_run)
{
if(C3T_index_run ==1 )
pMsg = &C3T_data_buff[0];
else
pMsg = &C3T_data_buff[2048];
res = send(sock, (char*)pMsg, 2048, 0);
C3T_index_run = 0;
if(res < 0)
{
if((res == SCK_EINVALID) || (res == SCK_ECLOSED))
{
EthLogFlag = 0;
break;
}
}
}
//无数据的发送的时候 保持网络连接状态
else
{
// //此处判定连接是否还正常
pMsg = &nullP;
res = send(sock, (char*)pMsg, 0, 0);
if(res < 0)
{
if((res == SCK_EINVALID) || (res == SCK_ECLOSED))
{
break;
}
}
}
os_itv_wait();
}
}
closesocket(sock);
os_itv_wait();
}
}
void TcpSendMail(void* _pMsg)
{
//tsk_lock ();
CmdHed* sendCmdHed;
packet = (char*)_pMsg ;
//修改开机命令序号
ScodeIndex++;
sendCmdHed = (CmdHed*)(packet + 1);
sendCmdHed ->ulCmdId = ScodeIndex;
sendCmdHed->sTime = myCurrentTime;
strcpy((char*)sendCmdHed->stMachineID, myMachineID);
// *(pMsg+33) = ScodeIndex;
// *(pMsg+34) = ScodeIndex>>8;
// *(pMsg+35) = ScodeIndex>>16;
// *(pMsg+36) = ScodeIndex>>24;
if(os_mbx_send(&net_send_mailbox, packet, 100) != OS_R_OK)
{
#if Dubug_Log
printf_debug("%02X::%d:%d::[TcpSendMail]:SendMail Faild! - ID=%d\r\n", RTC->TR, app_time_tick_number, app_time_tick, sendCmdHed->ulCmd);
#endif
}
else
{
#if Dubug_Log
printf_debug("%02X::%d:%d::[TcpSendMail]:SendMail Success! - ID=%d\r\n", RTC->TR, app_time_tick_number, app_time_tick, sendCmdHed->ulCmd);
#endif
}
//tsk_unlock ();
}
uint8_t* getCreatReciveData(int m_ulCmd)
{
uint8_t* ad;
switch(m_ulCmd)
{
case I2A_ComponentSetup:
{
ad = (uint8_t*)&i_S_I2A_ComponentSetup;
break;
}
case I2A_ComponentAction:
{
ad = (uint8_t*)&i_S_I2A_ComponentAction;
break;
}
case I2A_ReagentCalibration:
{
ad = (uint8_t*)&i_S_I2A_ReagentCalibration;
break;
}
case I2A_StartSetup:
{
ad = (uint8_t*)&i_S_I2A_StartSetup;
break;
}
case I2A_AdminAuthority:
{
ad = (uint8_t*)&i_S_I2A_AdminAuthority;
break;
}
case I2A_ErrorSolution:
{
ad = (uint8_t*)&i_S_I2A_ErrorSolution;
break;
}
case I2A_SynchroTime:
{
ad = (uint8_t*)&i_S_I2A_SynchroTime;
break;
}
case I2A_AssayGroup:
{
ad = (uint8_t*)&i_S_I2A_AssayGroup;
break;
}
case I2A_RegisterReagent:
{
ad = (uint8_t*)&i_S_I2A_RegisterReagent;
break;
}
case I2A_RegisterReagentList:
{
ad = (uint8_t*)&i_S_I2A_RegisterReagentList;
break;
}
case I2A_ReagentVolumeDetection:
{
ad = (uint8_t*)&i_S_I2A_ReagentVolumeDetection;
break;
}
case I2A_DetectStart:
{
ad = (uint8_t*)&i_S_I2A_DetectStart;
break;
}
case I2A_TubeProtocol:
{
ad = (uint8_t*)&i_S_I2A_TubeProtocol;
break;
}
case I2A_ParamDebug:
{
ad = (uint8_t*)&i_S_I2A_ParamAdjustInfo;
break;
}
case I2A_AdjustTemperature:
{
ad = (uint8_t*)&i_S_I2A_AdjustTemperature;
break;
}
case I2A_WarningClear:
{
ad = (uint8_t*)&i_S_I2A_WarningClear;
break;
}
case I2A_SmpRackLockSta:
{
ad = (uint8_t*)&i_S_I2A_SmpRackLockSta;
break;
}
case I2A_ReagRackLockSta:
{
ad = (uint8_t*)&i_S_I2A_ReagRackLockSta;
break;
}
case I2A_ReplyTipNotify:
{
ad = (uint8_t*)&i_S_I2A_ReplyTipNotify;
break;
}
case I2A_ForceOperation:
{
ad = (uint8_t*)&i_S_I2A_ForceOpe;
break;
}
case I2A_ShieldChannel:
{
ad = (uint8_t*)&i_S_I2A_ShieldChannel;
break;
}
case I2A_CheckChannelWare:
{
ad = (uint8_t*)&i_S_I2A_CheckChannelWare;
break;
}
case I2A_RequestCheckStart:
{
ad = (uint8_t*)&i_S_I2A_RequestCheckStart;
break;
}
case I2A_ForceUnlock:
{
ad = (uint8_t*)&i_S_I2A_ForceUnlock;
break;
}
case I2A_IAP_DATA:
{
ad =(uint8_t*)&i_S_I2A_IAP_DATA;
break;
}
case I2A_IAP_END:
{
ad =(uint8_t*)&i_S_I2A_IAP_END;
break;
}
case I2A_MotorParamStrp:
{
ad =(uint8_t*)&i_S_I2A_MotorSetup;
break;
}
case I2A_BloodCalibration:
{
ad =(uint8_t*)&i_S_I2A_BloodCalibration;
break;
}
case I2A_TubeCalibration:
{
ad =(uint8_t*)&i_S_I2A_TubeCalibration;
break;
}
case I2A_DetWaveParam:
{
ad =(uint8_t*)&i_S_I2A_DetWaveParam;
break;
}
default:
printf_debug("%02X::%d:%d::[ReciveData]:I->A:ERR=Unstated Command.ErrID=%d\r\n", RTC->TR, app_time_tick_number, app_time_tick, m_ulCmd);
ad = 0;
break;
}
return ad;
}
/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/