bool handle_cwSpecialCommand(CAbstractPeer& peer, const char **pkt) { int debugCommand = 0; eCommWebErrorCodes retCode = cwErrSuccess; do { if(!skipInt(pkt, &debugCommand)) { retCode = cwErrInvalidCommandParams; break; } switch(debugCommand) { case 0: restartSystem(); break; case 1: if(!skipInt(pkt, &debugCommand)) { retCode = cwErrInvalidCommandParams; break; } deviceDeleteLog(debugCommand); break; } }while(false); reply_cwReplyToCommand(peer, retCode); }
/*************************** * Trap handler * * addr = addr of instruction that caused the trap * code = code for the trap * 1 Undefined instruction * 2 Software trap * 3 Prefetch abort * 4 Data abort */ void armTrapHandler (int addr, int code) { sysPrint("***************************\r\n"); sysPrint("TRAP "); sysOutputHexInt(code); sysPrint(" AT 0x"); sysOutputHexInt(addr); sysPrint("\r\n"); sysPrint("***************************\r\n"); restartSystem(); }
// 消息线程处理:先接收网络协议的头,然后判断,如果头正确,则处理命令或继续接收命令参数后再处理 int TcpMsgRecvThread() { int ret = -1; char *recvBuf = NULL; NET_HEAD *netHead = NULL; char *pData = NULL; NET_HEAD keepalive; CLIENT_INFO *clientInfo = NULL; MSG_HEAD msgHead; int nRight = 0; fd_set fset; struct timeval to; pthread_detach(pthread_self()); pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); // 填充Keepalive数据 keepalive.nFlag = HDVS_FLAG; keepalive.nCommand = NETCMD_KEEP_ALIVE; keepalive.nErrorCode = 0; keepalive.nBufSize = 0; keepalive.nReserve = 0; // 分配发送recvBuf recvBuf = (char *)malloc(NETCMD_MAX_SIZE); // 100K if (recvBuf == NULL) { net_debug(); restartSystem(); return -1; } netHead = (NET_HEAD*)recvBuf; pData = recvBuf + sizeof(NET_HEAD); g_server_info.bServerExit = 0; while (!g_server_info.bServerExit) { pthread_mutex_lock(&g_server_info.msgThreadMutex); //printf("%s %d\n", __func__, __LINE__); // 等待用户登陆,加入命令线程池 while (g_server_info.msgWaitThreadNum == 0) { pthread_cond_wait(&g_server_info.msgThreadCond, &g_server_info.msgThreadMutex); if (g_server_info.bServerExit) { break; } } // 判断用户是否退出 if (g_server_info.bServerExit) { pthread_mutex_unlock(&g_server_info.msgThreadMutex); continue; } // 查找已登陆的用户,但还未加入线程池 clientInfo = FindWaitProccessClient(); if ((clientInfo == NULL)||(clientInfo->nflag == UDP_FLAG)) { pthread_mutex_unlock(&g_server_info.msgThreadMutex); printf("udp message quit!\n"); break; } if (clientInfo->hMsgSocket <= 0) { continue; } // 更新用户线程池计数 g_server_info.msgProcessThreadNum++; g_server_info.msgWaitThreadNum--; if (g_server_info.msgWaitThreadNum < 0) { g_server_info.msgWaitThreadNum = 0; } pthread_mutex_unlock(&g_server_info.msgThreadMutex); // FD_ZERO(&fset); memset(&to, 0, sizeof(to)); clientInfo->nKeepAlive = 0; clientInfo->status = RUN; nRight = clientInfo->level; while (STOP != clientInfo->status) { // 网络心跳 clientInfo->nKeepAlive ++; if (clientInfo->nKeepAlive >= 10) { net_debug(); printf("TCP_CMD_ERROR(%d): NOT KEEPALIVE!\n", clientInfo->hMsgSocket); break; } //接收网络协议的头 ret = 0; ret = TcpReceive(clientInfo->hMsgSocket, (char *)netHead, sizeof(NET_HEAD)); //ret = recv(clientInfo->hMsgSocket, (char *)netHead, sizeof(NET_HEAD), 0); if (ret < 0) { net_debug(); printf("TCP_CMD_ERROR(%d): RECEIVE ERROR(NET_HEAD)!\n", clientInfo->hMsgSocket); break; } if (ret == 0) { printf("TCP_CMD_ERROR(%d): RECEIVE TIMEOUT(NET_HEAD)!\n", clientInfo->hMsgSocket); continue; } // 判断网络帧头是否正确 if (netHead->nFlag != HDVS_FLAG) { printf("TCP_CMD_ERROR(%d): NET FLAG ERROR!\n", clientInfo->hMsgSocket); printf_bytes(recvBuf, 32); continue; } // 判断是否是心跳,如果是的话,则回复 if (netHead->nCommand == NETCMD_KEEP_ALIVE) { //printf("NETCMD_KEEP_ALIVE(%d): %d\n", clientInfo->hMsgSocket, netHead->nReserve); clientInfo->nKeepAlive = 0; ret = send(clientInfo->hMsgSocket, &keepalive, sizeof(NET_HEAD), 0); if (ret < 0) { printf("TCP_CMD_ERROR(%d): SEND KEEPALIVE ERROR!\n", clientInfo->hMsgSocket); net_debug(); } continue; } //printf("NetHead BufferSize: %d\n", netHead->nBufSize); // 接收网络命令参数 if (netHead->nBufSize>0 && netHead->nBufSize<NETCMD_MAX_SIZE-sizeof(NET_HEAD)) { ret = TcpReceive(clientInfo->hMsgSocket, pData, netHead->nBufSize); //ret = recv(clientInfo->hMsgSocket, pData, netHead->nBufSize, 0); if (ret < 0) { net_debug(); printf("TCP_CMD_ERROR(%d): RECEIVE ERROR(CONTEXT)!\n", clientInfo->hMsgSocket); break; } if (ret == 0) { net_debug(); printf("TCP_CMD_ERROR(%d): RECEIVE TIMEOUT(CONTEXT)!\n", clientInfo->hMsgSocket); continue; } } // 如果没有心跳,但有参数传过来,也可当心跳 clientInfo->nKeepAlive = 0; // 解析命令 msgHead.nSock = clientInfo->hMsgSocket; msgHead.nCmd = netHead->nCommand; msgHead.nRight = nRight; msgHead.nErrorCode = 0; msgHead.nBufSize = netHead->nBufSize; msgHead.nflag = TCP_FLAG; g_server_info.nupdate_flag = TCP_FLAG; printf("%s %d %x\n", __func__, __LINE__, netHead->nCommand); ParseCommand(&msgHead, pData); } clientInfo->status = STOP; // 释放命令线程池的节点 //printf("Cmd Exit(%d)!\n", clientInfo->hMsgSocket); StopUdpNode(clientInfo->hMsgSocket); StopTcpNode(clientInfo->hMsgSocket); pthread_cond_signal(&g_server_info.dataQuitThreadCond); WakeupStreamWait(); usleep(1); // 刷新线程池的计数 pthread_mutex_lock(&g_server_info.msgQuitThreadMutex); g_server_info.msgQuitThreadNum ++; g_server_info.msgProcessThreadNum --; if (g_server_info.msgProcessThreadNum < 0) { g_server_info.msgProcessThreadNum = 0; } pthread_mutex_unlock(&g_server_info.msgQuitThreadMutex); pthread_cond_signal(&g_server_info.msgQuitThreadCond); } g_server_info.nMsgThreadCount--; // 释放接收BUFFER if (recvBuf) { free(recvBuf); recvBuf = NULL; } return 0; }
/** * Program entrypoint. * * appAddr - addr of app to run * param - passed from bootloader, or 0 if running under gdb * */ int arm_main(int bootAddr, int appAddr, int param, int cmdLineParamsAddr) { wait(); #ifdef DB_DEBUG extern int db_debug_enabled; db_debug_enabled = param; // record the app address for the debugger's benefit extern int db_app_addr; db_app_addr = appAddr; #endif // remember bootstrap address for suite.c flash_addr_of_bootstrap = bootAddr; // initialize trap handlers initTrapHandlers(); // set up vectors for java-controlled interrupts set_up_java_interrupts(); // start the system timer init_watchdog_timer(); // now everything is set up enable the interrupts enableARMInterrupts(); iprintf("\n"); iprintf("Squawk VM Starting ("); iprintf(BUILD_DATE); iprintf(")...\n"); char* startupArgs = (char*)cmdLineParamsAddr; char *fakeArgv[SQUAWK_STARTUP_ARGS_MAX + 2]; fakeArgv[0] = "dummy"; // fake out the executable name char* suiteArg = "-flashsuite:00000000"; int res = sprintf(&suiteArg[12], "%x", appAddr); if (res == -1) { iprintf("ERROR - Debug call to sprintf failed\n"); exit(-1); } fakeArgv[1] = suiteArg; int fakeArgc = 2; int index = 0; /* The startupArgs structure comprises a sequence of null-terminated string * with another null to indicate the end of the structure */ while (startupArgs[index] != 0) { fakeArgv[fakeArgc] = &startupArgs[index]; //iprintf("Parsed arg: %s\n", fakeArgv[fakeArgc]); fakeArgc++; if (fakeArgc > SQUAWK_STARTUP_ARGS_MAX + 2) { iprintf("Number of startup args exceeds maximum permitted\n"); exit(-1); } while (startupArgs[index] != 0) { index++; } // skip over the terminating null index++; } /* char* suiteArg = "-flashsuite:00000000"; int res = sprintf(&suiteArg[12], "%x", appAddr); if (res == -1) { iprintf("ERROR - Debug call to sprintf failed\n"); exit(-1); } // Set available memory //int freeMem = (&__java_memory_end - &__java_memory_start); //iprintf("Free memory calculated to be %i\n", freeMem); char* mxArg = "-Xmx:00000000"; res = sprintf(&mxArg[5], "%08i", 120000); if (res == -1) { iprintf("ERROR - call to sprintf failed\n"); exit(-1); } //iprintf("MX arg is: %s\n", mxArg); // Hardcode command line arguments #if KERNEL_SQUAWK char* kernelSuiteArg = "-K-flashsuite:00000000"; res = sprintf(&kernelSuiteArg[14], "%x", appAddr); if (res == -1) { iprintf("ERROR - Debug call to sprintf failed\n"); exit(-1); } int fakeArgc = 10; char *fakeArgv[] = {"dummy", "-verbose", "-Xkernel", "-K-Xmx:40000", "-Xmx:50000", "-K-Xmxnvm:128", "-Xmxnvm:128", suiteArg, kernelSuiteArg, "squawk.application.Startup"}; #else int fakeArgc = 6; char *fakeArgv[] = {"dummy", "-verbose", mxArg, "-Xmxnvm:128", suiteArg, "squawk.application.Startup"}; // -Xmxnvm:125 set on 9 May as, empirically, the lowest value that the lisp2 collector will run with. Strange... // -Xmx:145000 is all the available memory (approximately). // TODO calculate a value for -Xmx #endif */ main(fakeArgc, fakeArgv); sysPrint("\r\nmain function returned, restarting\r\n"); disableARMInterrupts(); restartSystem(); }
void osfinish() { disableARMInterrupts(); restartSystem(); }