extern void eoprot_fun_UPDT_mc_joint_status(const EOnv* nv, const eOropdescriptor_t* rd) { #if defined(ENABLE_DEBUG_CONTROLMODESTATUS) eOmc_joint_status_t *js = (eOmc_joint_status_t*)rd->data; s_debug_monitor_controlmodestatus(eo_nv_GetBRD(nv), eoprot_ID2index(rd->id32), js->basic.controlmodestatus); #endif feat_manage_motioncontrol_data(nvBoardNum2FeatIdBoardNum(eo_nv_GetBRD(nv)), rd->id32, (void *)rd->data); }
extern void eoprot_fun_ONSAY_mn(const EOnv* nv, const eOropdescriptor_t* rd) { // marco.accame on 18 mar 2014: this function is called when a say<id32, data> rop is received // and the id32 is about the management endpoint. this function is common to every board. // it is used this function and not another one because inside the hostTransceiver object it was called: // eoprot_config_onsay_endpoint_set(eoprot_endpoint_management, eoprot_fun_ONSAY_mn); // the aim of this function is to wake up a thread which is blocked because it has sent an ask<id32> // the wake up funtionality is implemented in one mode only: // a. in initialisation, someone sets some values and then reads them back. // the read back sends an ask<id32, signature=0xaa000000>. in such a case the board sends back // a say<id32, data, signature = 0xaa000000>. thus, if the received signature is 0xaa000000, then // we must unblock using feat_signal_network_reply(). if(0xaa000000 == rd->signature) { // case a: if(fakestdbool_false == feat_signal_network_reply(eo_nv_GetBRD(nv), rd->id32, rd->signature)) { char str[256] = {0}; char nvinfo[128]; eoprot_ID2information(rd->id32, nvinfo, sizeof(nvinfo)); snprintf(str, sizeof(str), "eoprot_fun_ONSAY_mn() received an unexpected message w/ 0xaa000000 signature for %s", nvinfo); embObjPrintWarning(str); return; } } }
extern void eoprot_fun_ONSAY_mc(const EOnv* nv, const eOropdescriptor_t* rd) { // marco.accame on 18 mar 2014: this function is called when a say<id32, data> rop is received // and the id32 is about the motion control endpoint. this function is common to every board. // it is used this function and not another one because inside the hostTransceiver object it was called: // eoprot_config_onsay_endpoint_set(eoprot_endpoint_motioncontrol, eoprot_fun_ONSAY_mc); // the aim of this function is to wake up a thread which is blocked because it has sent an ask<id32> // the wake up funtionality is implemented in two modes, depending on the wait mechanism used: // a. in initialisation, embObjMotionControl sets some values and then reads them back. // the read back sends an ask<id32, signature=0xaa000000>. in such a case the board sends back // a say<id32, data, signature = 0xaa000000>. thus, if the received signature is 0xaa000000, then // we must unblock using feat_signal_network_reply(). // b. during runtime, some methods send a blocking ask<id32> without signature. It is the case of instance // of getPidRaw() which waits with a eoThreadEntry::synch() call. in such a case the board send back a // normal say<id32, data> with nos signature. in this case we unlock with wake(). if(0xaa000000 == rd->signature) { // case a: if(fakestdbool_false == feat_signal_network_reply(eo_nv_GetBRD(nv), rd->id32, rd->signature)) { char str[256] = {0}; char nvinfo[128]; eoprot_ID2information(rd->id32, nvinfo, sizeof(nvinfo)); snprintf(str, sizeof(str), "eoprot_fun_ONSAY_mc() received an unexpected message w/ 0xaa000000 signature for %s", nvinfo); embObjPrintWarning(str); return; } } else { //case b: wake(nv); } }
static void wake(const EOnv* nv) { eOprotID32_t id32 = 0; eOprotProgNumber_t prognum = 0 ; void *mchandler = (void*) feat_MC_handler_get(eo_nv_GetIP(nv), eo_nv_GetID32(nv)); if(NULL == mchandler) { printf("eoMC class not found\n"); return; } id32 = eo_nv_GetID32(nv); prognum = eoprot_endpoint_id2prognum(eo_nv_GetBRD(nv), id32); if(eobool_false == feat_MC_mutex_post(mchandler, prognum) ) { char nvinfo[128]; char ipinfo[20]; char str[256] = {0}; eoprot_ID2information(id32, nvinfo, sizeof(nvinfo)); eo_common_ipv4addr_to_string(eo_nv_GetIP(nv), ipinfo, sizeof(ipinfo)); snprintf(str, sizeof(str),"while releasing mutex for IP %s and NV %s", ipinfo, nvinfo); feat_PrintWarning(str); } }
extern void eoprot_fun_UPDT_mn_comm_cmmnds_command_replyarray(const EOnv* nv, const eOropdescriptor_t* rd) { if(fakestdbool_false == feat_signal_network_reply(eo_nv_GetBRD(nv), rd->id32, rd->signature)) { printf("ERROR: eoprot_fun_UPDT_mn_comm_cmmnds_command_replyarray() has received an unexpected message\n"); return; } }
static void wake(const EOnv* nv) { eOprotID32_t id32 = 0; eOprotProgNumber_t prognum = 0 ; void *mchandler = (void*) feat_MC_handler_get(nvBoardNum2FeatIdBoardNum(eo_nv_GetBRD(nv)), eo_nv_GetID32(nv)); if(NULL == mchandler) { printf("eoMC class not found\n"); return; } id32 = eo_nv_GetID32(nv); prognum = eoprot_endpoint_id2prognum(eo_nv_GetBRD(nv), id32); if(fakestdbool_false == feat_MC_mutex_post(mchandler, prognum) ) { char nvinfo[128]; char str[256] = {0}; eoprot_ID2information(id32, nvinfo, sizeof(nvinfo)); snprintf(str, sizeof(str),"while releasing mutex in BOARD %d for variable %s", eo_nv_GetBRD(nv)+1, nvinfo); embObjPrintWarning(str); } }
extern void eoprot_fun_UPDT_mn_comm_cmmnds_command_replyarray(const EOnv* nv, const eOropdescriptor_t* rd) { // marco.accame on 19 mar 2014: the ethResource class sends a set<command, value> and it blocks to wait a reply. // the reply arrives in the form sig<command, value>. the signature in here does not work, as it works only with // ask<> / say<>. if(eo_ropcode_sig == rd->ropcode) { // in here we have a sig and we cannot have the 0xaa000000 signature if(fakestdbool_false == feat_signal_network_reply(eo_nv_GetBRD(nv), rd->id32, rd->signature)) { printf("ERROR: eoprot_fun_UPDT_mn_comm_cmmnds_command_replyarray() has received an unexpected message\n"); return; } } }
void eoprot_fun_UPDT_mn_appl_status(const EOnv* nv, const eOropdescriptor_t* rd) { static const char* states[] = { "applstate_config", "applstate_running", "applstate_error", "not initted" }; char str[256] = {0}; eOmn_appl_status_t* appstatus = (eOmn_appl_status_t*) rd->data; const char* state = (appstatus->currstate > 2) ? (states[3]) : (states[appstatus->currstate]); snprintf(str, sizeof(str), "MANAGEMENT-appl-status: sign = 0x%x, board EB%d -> name = %s", rd->signature, eo_nv_GetBRD(nv)+1, appstatus->name); printf("%s\n", str); snprintf(str, sizeof(str), " version = %d.%d, built on date %d %d %d, at hour %d:%d", appstatus->version.major, appstatus->version.minor, appstatus->buildate.day, appstatus->buildate.month, appstatus->buildate.year, appstatus->buildate.hour, appstatus->buildate.min); printf("%s\n", str); snprintf(str, sizeof(str), " state = %s", state); printf("%s\n", str); fflush(stdout); if((eo_ropcode_say == rd->ropcode) && (0xaa000000 == rd->signature)) { if(fakestdbool_false == feat_signal_network_reply(eo_nv_GetBRD(nv), rd->id32, rd->signature)) { printf("ERROR: eoprot_fun_UPDT_mn_appl_status() has received an unexpected message\n"); return; } } }
void boardtransceiver_fun_UPDT_mc_joint_cmmnds_interactionmode(const EOnv* nv, const eOropdescriptor_t* rd) { EOnv_hid aNV = {0}; eOnvBRD_t brd = eo_nv_GetBRD(nv); EOnvSet* mynvset = arrayofnvsets[brd]; eOprotIndex_t index = eoprot_ID2index(rd->id32); eOenum08_t* pmode = (eOenum08_t*) rd->data; eOnvID32_t id32status = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, index, eoprot_tag_mc_joint_status); eo_nvset_NV_Get(mynvset, eok_ipv4addr_localhost, id32status, &aNV); eOmc_joint_status_t jointstatus = {0}; uint16_t size = 0; eOresult_t res = eo_nv_Get(&aNV, eo_nv_strg_volatile, &jointstatus, &size); jointstatus.interactionmodestatus = *pmode; eo_nv_Set(&aNV, &jointstatus, eobool_true, eo_nv_upd_dontdo); }
static void s_eoprot_print_mninfo_status(eOmn_info_basic_t* infobasic, uint8_t * extra, const EOnv* nv, const eOropdescriptor_t* rd) { #undef DROPCODES_FROM_LIST #define CAN_PRINT_FULL_PARSING static const eOerror_code_t codecanprint = EOERRORCODE(eoerror_category_System, eoerror_value_SYS_canservices_canprint); #if defined(DROPCODES_FROM_LIST) static const eOerror_code_t codes2drop_value[] = { EOERRORCODE(eoerror_category_System, eoerror_value_SYS_canservices_parsingfailure), EOERRORCODE(eoerror_category_System, eoerror_value_SYS_canservices_rxmaisbug), EOERRORCODE(eoerror_category_System, eoerror_value_SYS_canservices_rxfromwrongboard), EOERRORCODE(eoerror_category_System, eoerror_value_SYS_transceiver_rxseqnumber_error) }; static const int codes2drop_number = sizeof(codes2drop_value) / sizeof(eOerror_code_t); int i; for(i=0; i<codes2drop_number; i++) { if(codes2drop_value[i] == infobasic->properties.code) { return; } } #endif { char str[384] = {0}; static const char * sourcestrings[] = { "LOCAL", "CAN1", "CAN2", "UNKNOWN" }; static const char nullverbalextra[] = "no extra info despite we are in verbal mode"; static const char emptyextra[] = "NO MORE"; uint32_t sec = infobasic->timestamp / 1000000; uint32_t msec = (infobasic->timestamp % 1000000) / 1000; uint32_t usec = infobasic->timestamp % 1000; eOmn_info_type_t type = EOMN_INFO_PROPERTIES_FLAGS_get_type(infobasic->properties.flags); eOmn_info_source_t source = EOMN_INFO_PROPERTIES_FLAGS_get_source(infobasic->properties.flags); uint16_t address = EOMN_INFO_PROPERTIES_FLAGS_get_address(infobasic->properties.flags); eOmn_info_extraformat_t extraf = EOMN_INFO_PROPERTIES_FLAGS_get_extraformat(infobasic->properties.flags); uint16_t forfutureuse = EOMN_INFO_PROPERTIES_FLAGS_get_futureuse(infobasic->properties.flags); const char * str_source = NULL; const char * str_code = NULL; const char * str_extra = NULL; uint8_t *p64 = NULL; str_source = (source > eomn_info_source_can2) ? (sourcestrings[3]) : (sourcestrings[source]); str_code = eoerror_code2string(infobasic->properties.code); str_extra = NULL; if(eomn_info_extraformat_verbal == extraf) { str_extra = (NULL == extra) ? (nullverbalextra) : ((const char *)extra); } else { str_extra = emptyextra; } p64 = (uint8_t*)&(infobasic->properties.par64); if(codecanprint == infobasic->properties.code) { uint16_t len = 0; char canframestring[7] = {0}; #if defined(CAN_PRINT_FULL_PARSING) feat_embObjCANPrintHandler(eo_nv_GetBRD(nv), infobasic); return; #endif // it is a canprint: treat it in a particular way. // in first step: just print the 6 bytes (at most) of the payload: now on 03/03/15 we have implemented first step // in second step: do the same inside ethResources // in third step: inside ethResources it is called the proper class can_string_generic with one instance per can board. // maybe to save memory, we can instantiate the can_string_generic in runtime only when the can board sends a canprint. // this third step allows to concatenate the can print frames into a single message as robotInterface // does with can-based robots len = infobasic->properties.par16; if((len > 2) && (len <=8)) { // we have a valid canframe memcpy(canframestring, &p64[2], len-2); canframestring[len-2] = 0; // string terminator snprintf(str, sizeof(str), " from BOARD %d, src %s, adr %d, time %ds %dm %du: CANPRINT: %s [size = %d, D0 = 0x%.2x, D1 = 0x%.2x]", eo_nv_GetBRD(nv)+1, str_source, address, sec, msec, usec, canframestring, len, p64[0], p64[1] ); } else { snprintf(str, sizeof(str), " from BOARD %d, src %s, adr %d, time %ds %dm %du: CANPRINT is malformed (code 0x%.8x, par16 0x%.4x par64 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x) -> %s + INFO = %s", eo_nv_GetBRD(nv)+1, str_source, address, sec, msec, usec, infobasic->properties.code, infobasic->properties.par16, p64[7], p64[6], p64[5], p64[4], p64[3], p64[2], p64[1], p64[0], str_code, str_extra ); } } else { // treat it as the normal case if(EOERRORCODE(eoerror_category_System, eoerror_value_SYS_transceiver_rxseqnumber_error) == infobasic->properties.code) { // marco.accame on 14apr15: // the ems may issue such an error code at reception of first udp packet from a freshly launched robotInterface. // the reason is that robotinterface send a ropframe with sequencenumber = 1 and the EMS may expect a bigger number // because of a previous launch of robotinterface. // best solution is to change fw of ems so that it sends a info with a different code (eoerror_value_SYS_transceiver_rxseqnumber_restarted). // that will be from fw version 1.73. // in the meantime, i transform the first report of eoerror_value_SYS_transceiver_rxseqnumber_error into a info plus an explanation. // i will remove it later on. static uint8_t alreadyreceived[32] = {0}; static const char realigned[] = "BUT QUITE SURELY THAT IS DUE to ROBOTINTERFACE JUST RESTARTED THUS RESETTING ITS SEQNUM"; uint8_t brd = eo_nv_GetBRD(nv); if((brd < sizeof(alreadyreceived)) && (0 == alreadyreceived[eo_nv_GetBRD(nv)])) { alreadyreceived[eo_nv_GetBRD(nv)] = 1; type = eomn_info_type_info; str_extra = realigned; } } snprintf(str, sizeof(str), " from BOARD %d, src %s, adr %d, time %ds %dm %du: (code 0x%.8x, par16 0x%.4x par64 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x) -> %s + INFO = %s", eo_nv_GetBRD(nv)+1, str_source, address, sec, msec, usec, infobasic->properties.code, infobasic->properties.par16, p64[7], p64[6], p64[5], p64[4], p64[3], p64[2], p64[1], p64[0], str_code, str_extra ); } if(type == eomn_info_type_debug) { embObjPrintDebug(str); } if(type == eomn_info_type_info) { embObjPrintInfo(str); } if(type == eomn_info_type_warning) { embObjPrintWarning(str); } if(type == eomn_info_type_error) { embObjPrintError(str); } if(type == eomn_info_type_fatal) { embObjPrintFatal(str); } } }
void eoprot_fun_UPDT_mn_appl_status(const EOnv* nv, const eOropdescriptor_t* rd) { static const char* states[] = { "applstate_config", "applstate_running", "applstate_error", "not initted" }; char str[256] = {0}; eOmn_appl_status_t* appstatus = (eOmn_appl_status_t*) rd->data; const char* state = (appstatus->currstate > 2) ? (states[3]) : (states[appstatus->currstate]); snprintf(str, sizeof(str), "MANAGEMENT-appl-status: sign = 0x%x, board EB%d -> name = %s", rd->signature, eo_nv_GetBRD(nv)+1, appstatus->name); printf("%s\n", str); snprintf(str, sizeof(str), " version = %d.%d, built on date %d %d %d, at hour %d:%d", appstatus->version.major, appstatus->version.minor, appstatus->buildate.day, appstatus->buildate.month, appstatus->buildate.year, appstatus->buildate.hour, appstatus->buildate.min); printf("%s\n", str); //if running, print the control loop timings if (appstatus->currstate == 1) { snprintf(str, sizeof(str), " control loop timings: RX->%dus, DO->%dus, TX->%dus", appstatus->cloop_timings[0], appstatus->cloop_timings[1], appstatus->cloop_timings[2]); printf("%s\n", str); } snprintf(str, sizeof(str), " state = %s", state); printf("%s\n", str); fflush(stdout); }
void eoprot_fun_UPDT_mn_appl_status(const EOnv* nv, const eOropdescriptor_t* rd) { static const char* states[] = { "applstate_config", "applstate_running", "applstate_error", "not initted" }; char str[128] = {0}; eOmn_appl_status_t* appstatus = (eOmn_appl_status_t*) rd->data; const char* state = (appstatus->currstate > 2) ? (states[3]) : (states[appstatus->currstate]); snprintf(str, sizeof(str), "MANAGEMENT-appl-status: sign = 0x%x, board EB%d -> state = %s, msg = %s ", rd->signature, eo_nv_GetBRD(nv)+1, state, appstatus->filler06); printf("%s\n", str); }
extern void eoprot_fun_UPDT_mn_info_status(const EOnv* nv, const eOropdescriptor_t* rd) { char str[128] = {0}; eOmn_info_status_t* infostatus = (eOmn_info_status_t*) rd->data; snprintf(str, sizeof(str), "MANAGEMENT-info: sign = 0x%x, board EB%d: -> info.status.type = %d, info.status.string = %s", rd->signature, eo_nv_GetBRD(nv)+1, infostatus->type, infostatus->string); printf("%s\n", str); }
static void s_eoprot_print_mninfo_status(eOmn_info_basic_t* infobasic, uint8_t * extra, const EOnv* nv, const eOropdescriptor_t* rd) { char str[256] = {0}; #if 0 uint64_t txsec = rd->time / 1000000; uint64_t txmsec = (rd->time % 1000000) / 1000; uint64_t txusec = rd->time % 1000; if(1 == rd->control.plustime) { txsec = rd->time / 1000000; txmsec = (rd->time % 1000000) / 1000; txusec = rd->time % 1000; } else { txsec = txmsec = txusec = 0; } #endif static const char * typestrings[] = { "[INFO]", "[DEBUG]", "[WARNING]", "[ERROR", "[FATAL]", "[UNKNOWN]" }; static const char * sourcestrings[] = { "LOCAL", "CAN1", "CAN2", "UNKNOWN" }; static const char nullverbalextra[] = "no extra info despite we are in verbal mode"; static const char emptyextra[] = "extra info"; uint32_t sec = infobasic->timestamp / 1000000; uint32_t msec = (infobasic->timestamp % 1000000) / 1000; uint32_t usec = infobasic->timestamp % 1000; eOmn_info_type_t type = EOMN_INFO_PROPERTIES_FLAGS_get_type(infobasic->properties.flags); eOmn_info_source_t source = EOMN_INFO_PROPERTIES_FLAGS_get_source(infobasic->properties.flags); uint16_t address = EOMN_INFO_PROPERTIES_FLAGS_get_address(infobasic->properties.flags); eOmn_info_extraformat_t extraf = EOMN_INFO_PROPERTIES_FLAGS_get_extraformat(infobasic->properties.flags); uint16_t forfutureuse = EOMN_INFO_PROPERTIES_FLAGS_get_futureuse(infobasic->properties.flags); const char * str_type = (type > eomn_info_type_fatal) ? (typestrings[5]) : (typestrings[type]); const char * str_source = (source > eomn_info_source_can2) ? (sourcestrings[3]) : (sourcestrings[source]);; const char * str_code = eoerror_code2string(infobasic->properties.code); const char * str_extra = NULL; if(eomn_info_extraformat_verbal == extraf) { str_extra = (NULL == extra) ? (nullverbalextra) : ((const char *)extra); } else { str_extra = emptyextra; } snprintf(str, sizeof(str), "%s from BOARD %d, source %s, address %d, time %ds %dm %du: (code 0x%x, param 0x%x) -> %s + %s", str_type, eo_nv_GetBRD(nv)+1, str_source, address, sec, msec, usec, infobasic->properties.code, infobasic->properties.param, str_code, str_extra ); printf("%s\n", str); fflush(stdout); }
extern void eoprot_fun_UPDT_mn_info_status(const EOnv* nv, const eOropdescriptor_t* rd) { char str[256] = {0}; eOmn_info_status_t* infostatus = (eOmn_info_status_t*) rd->data; uint64_t sec = rd->time / 1000000; uint64_t msec = (rd->time % 1000000) / 1000; uint64_t usec = rd->time % 1000; if(1 == rd->control.plustime) { sec = rd->time / 1000000; msec = (rd->time % 1000000) / 1000; usec = rd->time % 1000; } else { sec = msec = usec = 0; } const char * infotype[] = { "eomn_info_type_info", "eomn_info_type_debug", "eomn_info_type_warning", "eomn_info_type_error", "unknown" }; const char * sss = (infostatus->properties.type > 3) ? (infotype[4]) : (infotype[infostatus->properties.type]); snprintf(str, sizeof(str), "[INFO]-> mn-info: ropsign = 0x%x, roptime = %04ds+%03dms+%03dus, BOARD = %d: -> info.status.properties.type = %s, info.status.data = %s", rd->signature, (uint32_t)sec, (uint32_t)msec, (uint32_t)usec, eo_nv_GetBRD(nv)+1, sss, infostatus->data); printf("%s\n", str); fflush(stdout); }