Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pico 2 W - FreeRTOS - cyw43_arch_init within Task causes Panic #2101

Open
jondurrant opened this issue Nov 26, 2024 · 14 comments
Open

Pico 2 W - FreeRTOS - cyw43_arch_init within Task causes Panic #2101

jondurrant opened this issue Nov 26, 2024 · 14 comments
Assignees

Comments

@jondurrant
Copy link

I'm using Raspberry Pi version of FreeRTOS, current version which was last updated about 3 months ago. Linking: pico_cyw43_arch_lwip_sys_freertos and calling cyw43_arch_init from within a task. I get error as below. Any suggestions?

Error:
assertion "!(raw_irq_mask[get_core_num()] & gpio_mask)" failed: file "/Users/jondurrant/pico/pico-sdk-2.1
.0/src/rp2_common/hardware_gpio/gpio.c", line 222, function: gpio_add_raw_irq_handler_with_order_priority
_masked

This is a migration of code that runs flawlessly on Pico W.

@jondurrant
Copy link
Author

SDK is 2.1.0

@peterharperuk
Copy link
Contributor

Could you be calling cyw43_arch_init twice? That's the only way I could think that this could happen off the top of my head. I assume it's the cyw43_irq_init call that's causing the problem.

This is a migration of code that runs flawlessly on Pico W.

I can't think why this would be different on Pico W.

@jondurrant
Copy link
Author

Certain this is only calling once at the top of the main thread.

@kilograham
Copy link
Contributor

a stack trace would be helpful

@jondurrant
Copy link
Author

Stack trace:

Thread #1 [rp2350.dap.core0] 1 (Name: rp2350.dap.core0, state: breakpoint) (Suspended : Signal : SIGTRAP:Trace/breakpoint trap)
_exit() at newlib_interface.c:45 0x100046dc
__assert_func() at newlib_interface.c:168 0x100047a6
gpio_add_raw_irq_handler_with_order_priority_masked() at gpio.c:222 0x10000a82
gpio_add_raw_irq_handler_with_order_priority() at gpio.h:674 0x1001789a
cyw43_irq_init() at cyw43_driver.c:56 0x1001789a
handle_sync_func_call() at async_context_freertos.c:189 0x10017dea
async_context_base_execute_once() at async_context_base.c:101 0x10008a36
process_under_lock() at async_context_freertos.c:49 0x10017cda
async_context_task() at async_context_freertos.c:72 0x10017dbc
0x100050c0
Thread #2 [rp2350.dap.core1] 2 (Name: rp2350.dap.core1, state: debug-request) (Suspended : Container)
0xda
0x146

@jondurrant
Copy link
Author

So some further debugging on this I can confirm that cyw43_irq_init is being called twice. This is happening somewhere in the cyw43_arch_init code. Trying to get my head around why....

@kilograham
Copy link
Contributor

This might be related to SMP - does the problem go away if you turn off SMP?

@jondurrant
Copy link
Author

This is running single core. To confirm I got the config correct the stack trace above shows no functions running on the second core.

@jondurrant
Copy link
Author

jondurrant commented Nov 27, 2024

The multiple calls to cyw43_irq_init are from the async_context_task looping. It looks to me like the task is being reset on the queue to need work.

the async context: core.when_pending.work_pending on first time through goes from True to False correctly I think. Then the function ulTaskNotifyTake is updating this to be True again. That is either a memory corruption or could another task be updating this.

@peterharperuk
Copy link
Contributor

It seems odd that I don't see this with the pico-examples. Are you doing anything different to the examples? https://github.com/raspberrypi/pico-examples/blob/master/pico_w/wifi/freertos/iperf/picow_freertos_iperf.c#L103
I think that you will get SMP now if configNUMBER_OF_CORES > 1. Any chance you could post your code from main up to this point and your Freertos config header file?

@jondurrant
Copy link
Author

jondurrant commented Nov 27, 2024

Of course let me post the code and config. It is very odd and I am only calling cyw43_arch_init in my trimmed down test. I am really scratching my head with what is going on. So very grateful for the help.
bug.tar.zip
Also at https://github.com/jondurrant/pico2w-exp/tree/main/WifiConnect which might be easier to browse.

@peterharperuk
Copy link
Contributor

peterharperuk commented Nov 27, 2024

I think this is a bug. I'm a bit stumped why it only occurs when configNUMBER_OF_CORES = 1
In the following function...

uint32_t async_context_freertos_execute_sync(async_context_t *self_base, uint32_t (*func)(void *param), void *param) {
    async_context_freertos_t *self = (async_context_freertos_t*)self_base;
    hard_assert(xSemaphoreGetMutexHolder(self->lock_mutex) != xTaskGetCurrentTaskHandle());
    sync_func_call_t call;
    call.worker.do_work = handle_sync_func_call;
    call.func = func;
    call.param = param;
    call.sem = xSemaphoreCreateBinary();
    async_context_add_when_pending_worker(self_base, &call.worker);  <- WORKER IS PENDING ALREADY
    async_context_set_work_pending(self_base, &call.worker); <- WORKER MADE PENDING AGAIN.

The following might be the fix.

sync_func_call_t call = {0};

peterharperuk added a commit to peterharperuk/pico-sdk that referenced this issue Nov 27, 2024
We need to do this to avoid work_pending being set twice.

Fixes raspberrypi#2101
@jondurrant
Copy link
Author

Thanks Peter. Nice to know I am not going nuts. I'll try that fix and also perhaps running under SMP. Kind of weird though, I can't work out how the work_pending is being reset.

@jondurrant
Copy link
Author

I can confirm that the following line fixes the issue
sync_func_call_t call = {0};

Thank you for diagnosing so quickly. Look forward to the official update.

@peterharperuk peterharperuk self-assigned this Nov 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants