/** * Debug support function. * * @param A pointer to a StringBuffer object to receive the output. */ void PMU::printDebug(StringBuilder* output) { EventReceiver::printDebug(output); output->concatf("-- CPU freq %d MHz\n", _cpu_clock_rate); output->concatf("-- Charge state %s\n", getChargeStateString()); output->concatf("-- STAT1 %s\n", (_er_flag(DIGITAB_PMU_FLAG_STAT1) ? "hi" : "lo")); output->concatf("-- STAT2 %s\n", (_er_flag(DIGITAB_PMU_FLAG_STAT2) ? "hi" : "lo")); output->concatf("-- _stat1_delta %u\n", _stat1_delta); output->concatf("-- _stat2_delta %u\n", _stat2_delta); output->concatf("-- _stat1_change_time %lu\n", _stat1_change_time); output->concatf("-- _stat2_change_time %lu\n", _stat2_change_time); output->concatf("-- _stat1_prior_delta %lu\n", _stat1_prior_delta); output->concatf("-- _stat2_prior_delta %lu\n", _stat2_prior_delta); }
/** * Calling this method will cause the class to send the event that represents the * current state of the IMU data. This is the means by which we send IMU data to * a counterparty. * * @return non-zero on error. */ int8_t LegendManager::send_map_event() { event_legend_frame_ready.specific_target = NULL; if (operating_legend && _er_flag(LEGEND_MGR_FLAGS_LEGEND_SENT)) { operating_legend->copy_frame(); Kernel::staticRaiseEvent(&event_legend_frame_ready); return 0; } return -1; }
// Calling causes a pointer dance that reconfigures the data we send to the host. // Don't do anything unless the legend is stable. This is concurrency-control. int8_t LegendManager::setLegend(ManuLegend* nu_legend) { if (_er_flag(LEGEND_MGR_FLAGS_LEGEND_STABLE)) { // Only reconfigure if stable. _er_clear_flag(LEGEND_MGR_FLAGS_LEGEND_STABLE); // Mark as unstable. _er_clear_flag(LEGEND_MGR_FLAGS_LEGEND_SENT); if (!nu_legend->finallized()) { // Finallize the ManuLegend prior to installing it. nu_legend->finallize(); } bool should_enable_pid = false; if (event_legend_frame_ready.isScheduled()) { event_legend_frame_ready.enableSchedule(false); should_enable_pid = true; } // Store a pointer to our dataset in the event that is to carry them. // It is important that this argument NOT be reaped. event_legend_frame_ready.abort(); // We don't want this to proc while the dataset is in flux. event_legend_frame_ready.clearArgs(); event_legend_frame_ready.addArg((void*) nu_legend->dataset_local, nu_legend->datasetSize()); // Now we need to declare the new IMU Legend to the rest of the system. We will not re-enable // the frame broadcast until the callback for this event happens. This assures that the message // order to anyone listening is what we intend. StringBuilder* legend_string = new StringBuilder(); nu_legend->formLegendString(legend_string); ManuvrMsg* legend_broadcast = Kernel::returnEvent(DIGITABULUM_MSG_IMU_LEGEND); legend_broadcast->specific_target = nu_legend->owner; legend_broadcast->priority(EVENT_PRIORITY_LOWEST + 1); legend_broadcast->setOriginator((EventReceiver*) this); legend_broadcast->addArg(legend_string)->reapValue(true); if (should_enable_pid) { event_legend_frame_ready.enableSchedule(true); } return 0; } return -1; }
/** * If we find ourselves in this fxn, it means an event that this class built (the argument) * has been serviced and we are now getting the chance to see the results. The argument * to this fxn will never be NULL. * * Depending on class implementations, we might choose to handle the completed Event differently. We * might add values to event's Argument chain and return RECYCLE. We may also free() the event * ourselves and return DROP. By default, we will return REAP to instruct the Kernel * to either free() the event or return it to it's preallocate queue, as appropriate. If the event * was crafted to not be in the heap in its own allocation, we will return DROP instead. * * @param event The event for which service has been completed. * @return A callback return code. */ int8_t LegendManager::callback_proc(ManuvrMsg* event) { /* Setup the default return code. If the event was marked as mem_managed, we return a DROP code. Otherwise, we will return a REAP code. Downstream of this assignment, we might choose differently. */ int8_t return_value = (0 == event->refCount()) ? EVENT_CALLBACK_RETURN_REAP : EVENT_CALLBACK_RETURN_DROP; /* Some class-specific set of conditionals below this line. */ switch (event->eventCode()) { case DIGITABULUM_MSG_IMU_READ: switch (last_imu_read) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: last_imu_read++; return EVENT_CALLBACK_RETURN_RECYCLE; case 16: last_imu_read = 0; break; default: if (getVerbosity() > 2) local_log.concat("LegendManager::callback_proc(IMU_READ): Bad arg\n"); last_imu_read = 0; break; } break; case DIGITABULUM_MSG_IMU_INIT: switch (last_imu_read) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: last_imu_read++; if (getVerbosity() > 6) local_log.concat("LegendManager::callback_proc(IMU_INIT): RECYCLING\n"); // We still have IMUs left to deal with. Recycle the event... return EVENT_CALLBACK_RETURN_RECYCLE; case 16: last_imu_read = 0; if (getVerbosity() > 6) local_log.concat("LegendManager::callback_proc(IMU_INIT): DROPPING\n"); break; default: if (getVerbosity() > 2) local_log.concat("LegendManager::callback_proc(IMU_READ): Bad arg\n"); last_imu_read = 0; break; } break; case DIGITABULUM_MSG_IMU_LEGEND: // We take this as an indication that our notice of altered Legend was sent. _er_set_flag(LEGEND_MGR_FLAGS_LEGEND_SENT); break; case DIGITABULUM_MSG_IMU_MAP_STATE: *(_ptr_sequence) = *(_ptr_sequence) + 1; if (operating_legend && _er_flag(LEGEND_MGR_FLAGS_LEGEND_SENT)) { operating_legend->copy_frame(); Kernel::staticRaiseEvent(&event_legend_frame_ready); return 0; } break; case DIGITABULUM_MSG_IMU_QUAT_CRUNCH: { uint8_t temp_uint_8; if (0 == event->getArgAs(&temp_uint_8)) { if (iius[temp_uint_8 % 17].has_quats_left()) { return_value = EVENT_CALLBACK_RETURN_RECYCLE; } } else { local_log.concat("LegendManager::callback_proc(): QUAT crunch had no argument?!.\n"); } } break; default: if (getVerbosity() > 5) { local_log.concat("LegendManager::callback_proc(): Default case.\n"); #if defined(__MANUVR_DEBUG) event->printDebug(&local_log); #endif Kernel::log(&local_log); } break; } flushLocalLog(); return return_value; }