Skip to content

Commit

Permalink
added method to get alarm_pool core_num so stdio_usb_init can fail early
Browse files Browse the repository at this point in the history
  • Loading branch information
kilograham committed Aug 8, 2022
1 parent cde95d8 commit d095c41
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 4 deletions.
8 changes: 8 additions & 0 deletions src/common/pico_time/include/pico/time.h
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,14 @@ alarm_pool_t *alarm_pool_create(uint hardware_alarm_num, uint max_timers);
*/
uint alarm_pool_hardware_alarm_num(alarm_pool_t *pool);

/**
* \brief Return the core number the alarm pool was initialized on (and hence callbacks are called on)
* \ingroup alarm
* \param pool the pool
* \return the core used by the pool
*/
uint alarm_pool_core_num(alarm_pool_t *pool);

/**
* \brief Destroy the alarm pool, cancelling all alarms and freeing up the underlying hardware alarm
* \ingroup alarm
Expand Down
6 changes: 6 additions & 0 deletions src/common/pico_time/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ typedef struct alarm_pool {
uint8_t *entry_ids_high;
alarm_id_t alarm_in_progress; // this is set during a callback from the IRQ handler... it can be cleared by alarm_cancel to prevent repeats
uint8_t hardware_alarm_num;
uint8_t core_num;
} alarm_pool_t;

#if !PICO_TIME_DEFAULT_ALARM_POOL_DISABLED
Expand Down Expand Up @@ -190,6 +191,7 @@ void alarm_pool_post_alloc_init(alarm_pool_t *pool, uint hardware_alarm_num) {
hardware_alarm_set_callback(hardware_alarm_num, alarm_pool_alarm_callback);
pool->lock = spin_lock_instance(next_striped_spin_lock_num());
pool->hardware_alarm_num = (uint8_t) hardware_alarm_num;
pool->core_num = get_core_num();
pools[hardware_alarm_num] = pool;
}

Expand Down Expand Up @@ -286,6 +288,10 @@ uint alarm_pool_hardware_alarm_num(alarm_pool_t *pool) {
return pool->hardware_alarm_num;
}

uint alarm_pool_core_num(alarm_pool_t *pool) {
return pool->core_num;
}

static void alarm_pool_dump_key(pheap_node_id_t id, void *user_data) {
alarm_pool_t *pool = (alarm_pool_t *)user_data;
#if PICO_ON_DEVICE
Expand Down
3 changes: 2 additions & 1 deletion src/rp2_common/pico_stdio/include/pico/stdio.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,10 @@ typedef struct stdio_driver stdio_driver_t;
* When stdio_usb is configured, this method can be optionally made to block, waiting for a connection
* via the variables specified in \ref stdio_usb_init (i.e. \ref PICO_STDIO_USB_CONNECT_WAIT_TIMEOUT_MS)
*
* \return true if at least one output was successfully initialized, false otherwise.
* \see stdio_uart, stdio_usb, stdio_semihosting
*/
void stdio_init_all(void);
bool stdio_init_all(void);

/*! \brief Initialize all of the present standard stdio types that are linked into the binary.
* \ingroup pico_stdio
Expand Down
9 changes: 7 additions & 2 deletions src/rp2_common/pico_stdio/stdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,20 +267,25 @@ int __printflike(1, 0) WRAPPER_FUNC(printf)(const char* format, ...)
return ret;
}

void stdio_init_all(void) {
bool stdio_init_all(void) {
// todo add explicit custom, or registered although you can call stdio_enable_driver explicitly anyway
// These are well known ones

bool rc = false;
#if LIB_PICO_STDIO_UART
stdio_uart_init();
rc = true;
#endif

#if LIB_PICO_STDIO_SEMIHOSTING
stdio_semihosting_init();
rc = true;
#endif

#if LIB_PICO_STDIO_USB
stdio_usb_init();
rc |= stdio_usb_init();
#endif
return rc;
}

int WRAPPER_FUNC(getchar)(void) {
Expand Down
7 changes: 6 additions & 1 deletion src/rp2_common/pico_stdio_usb/stdio_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ static uint8_t low_priority_irq_num;
#endif

static int64_t timer_task(__unused alarm_id_t id, __unused void *user_data) {
assert(stdio_usb_core_num == get_core_num()); // if this fails, you have initialized stdio_usb on the wrong core
int64_t repeat_time;
if (critical_section_is_initialized(&one_shot_timer_crit_sec)) {
critical_section_enter_blocking(&one_shot_timer_crit_sec);
Expand Down Expand Up @@ -147,6 +146,12 @@ stdio_driver_t stdio_usb = {
};

bool stdio_usb_init(void) {
if (get_core_num() != alarm_pool_core_num(alarm_pool_get_default())) {
// included an assertion here rather than just returning false, as this is likely
// a coding bug, rather than anything else.
assert(false);
return false;
}
#ifndef NDEBUG
stdio_usb_core_num = (uint8_t)get_core_num();
#endif
Expand Down

0 comments on commit d095c41

Please sign in to comment.