#include #include #include #include #include #include #include #define WEAK __attribute__((weak)) #define IFNOTWEAK(v) ((&v == NULL) ? 0 : (v)) #define SETNOTWEAK(v,a) { if (&v != NULL) v = a; } extern uint8_t* __brkval; LogCSR *csrbuffer; uint16_t dbgPtr; uint32_t lasterror; uint8_t dummy_can_usage(void){ return 0; }; uint8_t can_usage(void) __attribute__((weak,alias("dummy_can_usage"))); extern int32_t _dbg_jetcan_requests WEAK, _dbg_jetcan_misses WEAK, _dbg_jetcan_timeouts WEAK, _dbg_jetcan_rtt WEAK, _dbg_jetcan_rtt_min WEAK, _dbg_jetcan_rtt_max WEAK; int rt_node_proc(int op,int regno,uint8_t *type,void *buffer){ uint16_t ui16; switch (op & RNPOP_MASK){ case RNPOP_READ: if ((regno >= 0x00F0) && (regno < 0x0100)) { csrbuffer = get_csr_log(); *(int32_t*)buffer = (int32_t)csrbuffer->mcucsr[ regno & 0x0F]; return 0; }; if ((regno >= 0x8600) && (regno < 0x8700)) { ui16 = (regno & 0xFF); *(int32_t*)buffer = output_read( ui16 ); return 0; }; if ((regno >= 0x8700) && (regno < 0x8800)) { ui16 = (regno & 0xFF); if (*type & RDT_FLOAT){ *(float*)buffer = fp4816_to_float( output_current(ui16) ); } else{ *(int32_t*)buffer = output_current(ui16)>>16; }; return 0; }; if ((regno >= 0xA000) && (regno < 0xB000)) { *(int32_t*)buffer = *(int32_t*)(regno & 0x0FFF); return 0; }; if ((regno >= 0xB000) && (regno < 0xB100)) { list_t *l = _threading_threads.next; thread_t *thread; ui16 = (regno >> 4) & 0x0F; while ((l != &_threading_threads) && (ui16--)){ l = l->next; }; thread = (thread_t*)l; if (&(thread->list) != &_threading_threads){ switch (regno & 0x0F){ case 0: *(int32_t*)buffer = (uint32_t)(unsigned int)thread; break; case 1: *(int32_t*)buffer = ((int)(thread->start))<<1; break; case 2: *(int32_t*)buffer = (int)(thread->stack.base); break; case 3: *(int32_t*)buffer = (int)(thread->stack.size); break; case 4: *(int32_t*)buffer = (int)(thread->stack.stackpointer); break; case 5: *(int32_t*)buffer = (int)(thread->stack.min_free); break; case 6: *(int32_t*)buffer = thread->statistic.scheduled_time.seconds; break; case 7: *(int32_t*)buffer = thread->statistic.scheduled_time.cycles; break; default: *(int32_t*)buffer = 0; }; } else { *(int32_t*)buffer = 0; }; return 0; }; switch (regno) { case 0x0001: rb2_convert( RDT_INT32, (void*)&rt_ram.eeprom.serial.code, *type, &*(int32_t*)buffer ); return 0; case 0x0002: rb2_convert( RDT_INT32, (void*)&rt_ram.flags.code, *type, &*(int32_t*)buffer ); return 0; case 0x0003: rb2_convert( RDT_INT8, (void*)&rt_ram.accesscode.accessmask, *type, &*(int32_t*)buffer ); return 0; case 0x0004: rb2_convert( RDT_INT16, (void*)&rt_ram.accesscode.servicepartner, *type, &*(int32_t*)buffer ); return 0; case 0x0005: rb2_convert( RDT_INT32, (void*)&rt_ram.eeprom.last_auth, *type, &*(int32_t*)buffer ); return 0; case 0x0006: rb2_convert( RDT_INT32, (void*)&rt_ram.eeprom.count_poweron, *type, &*(int32_t*)buffer ); return 0; case 0x0007: rb2_convert( RDT_INT32, (void*)&rt_ram.eeprom.secs_powered, *type, &*(int32_t*)buffer ); return 0; case 0x0008: rb2_convert( RDT_INT32, (void*)&rt_ram.eeprom.secs_running, *type, &*(int32_t*)buffer ); return 0; case 0x0009: rb2_convert( RDT_INT32, (void*)&rt_ram.eeprom.next_service, *type, &*(int32_t*)buffer ); return 0; case 0x000A: rb2_convert( RDT_INT32, (void*)&rt_ram.eeprom.service_partner, *type, &*(int32_t*)buffer ); return 0; case 0x000B: rb2_convert( RDT_INT32, (void*)&rt_ram.eeprom.service_set_time, *type, &*(int32_t*)buffer ); return 0; case 0x000C: *(int32_t*)buffer = runtime_is_running(); *type = RDT_INT32; return 0; case 0x000E: *(int32_t*)buffer = (&__rb2_instance)->axes; *type = RDT_INT32; return 0; case 0x000F: *(int32_t*)buffer = rb2_known_endpoints(); *type = RDT_INT32; return 0; case 0x0018: rb2_convert( RDT_INT32, (void*)&rt_ram.identity.hardware_id, *type, &*(int32_t*)buffer ); return 0; case 0x0019: rb2_convert( RDT_INT32, (void*)&rt_ram.identity.hardware_revision, *type, &*(int32_t*)buffer ); return 0; case 0x001A: rb2_convert( RDT_INT32, (void*)&rt_ram.identity.software_revision, *type, &*(int32_t*)buffer ); return 0; case 0x001B: rb2_convert( RDT_INT32, (void*)&rt_ram.identity.functional_groups, *type, &*(int32_t*)buffer ); return 0; case 0x001C: *(int32_t*)buffer = unixtime(); return 0; case 0x0020: rb2_convert( RDT_INT16, (void*)&__brkval, *type, &*(int32_t*)buffer ); return 0; case 0x0021: *(int32_t*)buffer = (int32_t)(int)__malloc_heap_end; return 0; case 0x0022: rb2_convert( RDT_INT32, (void*)&_systick_secs, *type, &*(int32_t*)buffer ); return 0; case 0x0023: *(int32_t*)buffer = rt_dbg->atomic_ip; return 0; case 0x0024: *(int32_t*)buffer = rt_dbg->spinlock_ip; return 0; case 0x0025: *(int32_t*)buffer = _assert_current(); return 0; case 0x0026: *(int32_t*)buffer = _assert_current_error(); return 0; case 0x0027: *(int32_t*)buffer = systick_ticks() & 0x7FFFFFFFul; return 0; #if defined(DEBUG_SCHEDULING) case 0x0050: *(int32_t*)buffer = _ts_sys_time.seconds; return 0; case 0x0051: *(int32_t*)buffer = _ts_sys_time.cycles; return 0; case 0x0052: *(int32_t*)buffer = _ts_irq_time.seconds; return 0; case 0x0053: *(int32_t*)buffer = _ts_irq_time.cycles; return 0; case 0x0054: *(int32_t*)buffer = _ts_timer_resolution; return 0; case 0x0055: *(int32_t*)buffer = _ts_timer_cycles_per_increment; return 0; case 0x0056: *(int32_t*)buffer = _ts_timer_increments_per_second; return 0; case 0x0057: *(int32_t*)buffer = __freq_cpu; return 0; case 0x0058: *(int32_t*)buffer = _st_lag_current; return 0; case 0x0059: *(int32_t*)buffer = _st_lag_min; return 0; case 0x005A: *(int32_t*)buffer = _st_lag_max; return 0; case 0x005B: *(int32_t*)buffer = ((uint32_t)rt_dbg->last_late_vect[0] << 1) | ((uint32_t)rt_dbg->last_late_vect[1] << 17); return 0; case 0x005C: *(int32_t*)buffer = ((uint32_t)rt_dbg->last_late_vect[2] << 1) | ((uint32_t)rt_dbg->last_late_vect[3] << 17);; return 0; #endif case 0x005D: *(int32_t*)buffer = _dbg_rb2_usart_sync; return 0; case 0x005E: *(int32_t*)buffer = _dbg_rb2_usart_sync_min; return 0; case 0x005F: *(int32_t*)buffer = _dbg_rb2_usart_sync_max; return 0; case 0x0060: *(int32_t*)buffer = _dbg_rb2_usart_rxtele; return 0; case 0x0061: *(int32_t*)buffer = _dbg_rb2_usart_txtele; return 0; case 0x0062: *(int32_t*)buffer = IFNOTWEAK(_dbg_jetcan_requests); return 0; case 0x0063: *(int32_t*)buffer = IFNOTWEAK(_dbg_jetcan_timeouts); return 0; case 0x0064: *(int32_t*)buffer = IFNOTWEAK(_dbg_jetcan_rtt); return 0; case 0x0065: *(int32_t*)buffer = IFNOTWEAK(_dbg_jetcan_rtt_min); return 0; case 0x0066: *(int32_t*)buffer = IFNOTWEAK(_dbg_jetcan_rtt_max); return 0; case 0x0067: *(int32_t*)buffer = IFNOTWEAK(_dbg_jetcan_misses); return 0; case 0x00E9: *(int32_t*)buffer = can_usage(); return 0; case 0x00EA: rb2_convert( RDT_INT32, (void*)&lasterror, *type, &*(int32_t*)buffer ); return 0; case 0x00EB: rb2_convert( RDT_INT16, (void*)&dbgPtr, *type, &*(int32_t*)buffer ); return 0; case 0x00EC: rb2_convert( RDT_INT8, (void*)dbgPtr, *type, &*(int32_t*)buffer ); return 0; case 0x00ED: rb2_convert( RDT_INT16, (void*)dbgPtr, *type, &*(int32_t*)buffer ); return 0; case 0x00EE: rb2_convert( RDT_INT32, (void*)dbgPtr, *type, &*(int32_t*)buffer ); return 0; case 0x00EF: csrbuffer = get_csr_log(); *(int32_t*)buffer = (int32_t)csrbuffer->wp; return 0; }; break; case RNPOP_WRITE: if ((regno >= 0x8600) && (regno < 0x8700)) { ui16 = (regno & 0xFF); if (*(int32_t*)buffer){ output_on(ui16); } else { output_off(ui16); }; return 0; }; if ((regno >= 0xA000) && (regno < 0xB000)) { *(int32_t*)(regno & 0x0FFF) = *(int32_t*)buffer; return 0; }; switch (regno) { case 0x0001: if (rt_authorized(RTA_MANUFACT1)) { rb2_convert( *type, &*(int32_t*)buffer, RDT_INT32, (void*)&rt_ram.eeprom.serial.code ); return 0; }; case 0x0004: rt_authenticate( *(int32_t*)buffer ); return 0; case 0x0006: if (rt_authorized(RTA_MANUFACT1)) { rb2_convert( *type, &*(int32_t*)buffer, RDT_INT32, (void*)&rt_ram.eeprom.count_poweron ); return 0; }; case 0x0007: if (rt_authorized(RTA_MANUFACT1)) { rb2_convert( *type, &*(int32_t*)buffer, RDT_INT32, (void*)&rt_ram.eeprom.secs_powered ); return 0; }; case 0x0008: if (rt_authorized(RTA_MANUFACT1)) { rb2_convert( *type, &*(int32_t*)buffer, RDT_INT32, (void*)&rt_ram.eeprom.secs_running ); return 0; }; case 0x0009: if (rt_authorized(RTA_SERVICE2)) { rb2_convert( *type, &*(int32_t*)buffer, RDT_INT32, (void*)&rt_ram.eeprom.next_service ); runtime_signal(); rt_ram.eeprom.service_set_time = rt_ram.eeprom.secs_powered; rt_ram.eeprom.service_partner = rt_ram.accesscode.servicepartner; runtime_signal(); return 0; }; case 0x000C: runtime_set_running( *(int32_t*)buffer ? 1 : 0 ); return 0; case 0x001C: unixtime_set( *(int32_t*)buffer ); return 0; case 0x0025: _assert_read(); return 0; #if defined(DEBUG_SCHEDULING) case 0x0059: _st_lag_min = *(int32_t*)buffer; return 0; case 0x005A: _st_lag_max = *(int32_t*)buffer; return 0; #endif case 0x005D: _dbg_rb2_usart_sync = *(int32_t*)buffer; return 0; case 0x005E: _dbg_rb2_usart_sync_min = *(int32_t*)buffer; return 0; case 0x005F: _dbg_rb2_usart_sync_max = *(int32_t*)buffer; return 0; case 0x0060: _dbg_rb2_usart_rxtele = *(int32_t*)buffer; return 0; case 0x0061: _dbg_rb2_usart_txtele = *(int32_t*)buffer; return 0; case 0x0062: SETNOTWEAK(_dbg_jetcan_requests, *(int32_t*)buffer); return 0; case 0x0063: SETNOTWEAK(_dbg_jetcan_timeouts, *(int32_t*)buffer); return 0; case 0x0064: SETNOTWEAK(_dbg_jetcan_rtt, *(int32_t*)buffer); return 0; case 0x0065: SETNOTWEAK(_dbg_jetcan_rtt_min, *(int32_t*)buffer); return 0; case 0x0066: SETNOTWEAK(_dbg_jetcan_rtt_max, *(int32_t*)buffer); return 0; case 0x0067: SETNOTWEAK(_dbg_jetcan_misses, *(int32_t*)buffer); return 0; case 0x00EB: if (rt_authorized(RTA_DEVELOPER)) { rb2_convert( *type, &*(int32_t*)buffer, RDT_INT16, (void*)&dbgPtr ); return 0; }; case 0x00EC: if (rt_authorized(RTA_DEVELOPER)) { rb2_convert( *type, &*(int32_t*)buffer, RDT_INT8, (void*)dbgPtr ); return 0; }; case 0x00ED: if (rt_authorized(RTA_DEVELOPER)) { rb2_convert( *type, &*(int32_t*)buffer, RDT_INT16, (void*)dbgPtr ); return 0; }; case 0x00EE: if (rt_authorized(RTA_DEVELOPER)) { rb2_convert( *type, &*(int32_t*)buffer, RDT_INT32, (void*)dbgPtr ); return 0; }; }; break; default: return -EPARAM; }; return -ENOFILE; }; uint8_t runtime_register_proc(RB2_REGISTER *regno,RB2_TELEGRAM *telegram) { uint8_t t = telegram->flags.type; return rt_node_proc( telegram->flags.read ? RNPOP_READ : RNPOP_WRITE, telegram->regno, &t, &telegram->i32); };