void initial_pins_setup(void) { int i; for (i=0; i<initial_pins_size; i++) { const struct initial_pin_s *ip = &initial_pins[i]; gpio_out_setup(READP(ip->pin), READP(ip->flags) & IP_OUT_HIGH); } }
/** * Walk all active monitors. * * @param[in] monitor If NULL, the first monitor is returned and the monitor pool is locked (thread lib is globally locked)<br> * If non-NULL, the next monitor is returned. * @return a pointer to a monitor, or NULL if all monitors walked (and thread lib is globally unlocked). * * @note As this is currently implemented, this must be called to walk ALL monitors. It can't * be used to look for a specific monitor and then quit. * */ hythread_monitor_t VMCALL hythread_monitor_walk (hythread_monitor_t monitor) { hythread_monitor_pool_t pool; hythread_library_t lib = get_default_library (); ASSERT (lib); ASSERT (lib->monitor_pool); ASSERT (lib->monitor_pool->entries); ASSERT (MACRO_SELF () != 0); if (monitor == NULL) { GLOBAL_LOCK (MACRO_SELF (), CALLER_MONITOR_WALK); pool = READP (lib->monitor_pool); monitor = &pool->entries[0]; if (READU (monitor->count) != FREE_TAG) return monitor; } else { pool = pool_for_monitor (lib, monitor); if (pool == NULL) { /* should never happen */ GLOBAL_UNLOCK (MACRO_SELF ()); return NULL; } } do { if (monitor >= &pool->entries[MONITOR_POOL_SIZE - 1]) { if ((pool = READP (pool->next)) == NULL) { /* we've walked all monitors */ GLOBAL_UNLOCK (MACRO_SELF ()); return NULL; } monitor = &pool->entries[0]; } else { monitor++; } } while (READU (monitor->count) == FREE_TAG); return monitor; }
/* * Return a monitor's tracing information. * * @param[in] monitor (non-NULL) * @return pointer to the monitor's tracing information (may be NULL) * */ HyThreadMonitorTracing *VMCALL hythread_monitor_get_tracing (hythread_monitor_t monitor) { ASSERT (monitor); return READP (monitor->tracing); }
/* * Return the monitor pool holding a monitor. * * @param[in] lib threading library (non-NULL) * @param[in] monitor * @return pointer to pool on success, NULL on failure (invalid monitor?) */ static hythread_monitor_pool_t pool_for_monitor (hythread_library_t lib, hythread_monitor_t monitor) { hythread_monitor_pool_t pool = READP (lib->monitor_pool); /* find out which pool the monitor is from (cache this, maybe?) (NOTE: technically, this search invokes undefined behaviour (comparing pointers from different malloc's). But it should work on every platform with a flat memory model. */ ASSERT (lib); ASSERT (monitor); ASSERT (pool); while (monitor < &pool->entries[0] || monitor > &pool->entries[MONITOR_POOL_SIZE - 1]) { if ((pool = READP (pool->next)) == NULL) { break; } } return pool; }
// Encode and transmit a "response" message void console_sendf(const struct command_encoder *ce, va_list args) { // Verify space for message uint_fast8_t tpos = transmit_pos, max_size = READP(ce->max_size); if (tpos + max_size > sizeof(transmit_buf)) // Not enough space for message return; // Generate message uint8_t *buf = &transmit_buf[tpos]; uint_fast8_t msglen = command_encode_and_frame(buf, ce, args); // Start message transmit transmit_pos = tpos + msglen; usb_notify_bulk_in(); }
/** * Return a thread's flags. * * @param[in] thread (non-NULL) * @param[in] blocker if non-NULL, will be set to the monitor on which the thread is blocked (if any) * @return flags * */ UDATA VMCALL hythread_get_flags (hythread_t thread, hythread_monitor_t * blocker) { UDATA flags; ASSERT (thread); MUTEX_ENTER (thread->mutex); if (blocker) { *blocker = READP (thread->monitor); } flags = READU (thread->flags); MUTEX_EXIT (thread->mutex); return flags; }
static void usb_write_packet_progmem(const uint8_t *data, uint8_t len) { while (len--) UEDATX = READP(*data++); }
/** * Return a monitor's name. * * @param[in] monitor (non-NULL) * @return pointer to the monitor's name (may be NULL) * * @see hythread_monitor_init_with_name * */ const char *VMCALL hythread_monitor_get_name (hythread_monitor_t monitor) { ASSERT (monitor); return READP (monitor->name); }