20719 Button callback context and interrupt execution time

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
naroc_3877611
Level 1
Level 1

I'm developing an application using the 20719 silicon, namely the CYBT-423028-02 module. The application is designed to collect data from a sensor over a hardware serial bus, and forward it over the Bluetooth connection using the serial port profile.

The basic application is working in that it catches the sensor pin interrupt and does the appropriate transaction to collect the data which is then forwarded over Bluetooth. The issue I'm having is that if I start pushing the data rate towards what I require for the application (250 samples per second), the module will crash. From experimentation, I've found that the module will crash even if I do not initialize the Bluetooth stack at all (commenting out wiced_bt_stack_init call) and only have the application reading data from the sensor. But it won't crash if I remove the call to actually read the sensor, which is an approximate 300us SPI transaction. If I just toggle a pin state and return, the module will continue running normally.

So from this information, I'm guessing that if you get a callback generated by a pin interrupt which was registered with wiced_platform_register_button_callback, you must return within a set time period. What is this time period exactly, and where is it documented? Further, does this callback execute from interrupt context and is holding off other critical system interrupts, which is why the chip is crashing? If that's the case, is there a way for me to tell the module that I need to execute something from the main context instead so that I don't hold off the module's critical functions? Normally I would use a worker thread, but WICED Studio does not implement the RTOS for this module as far as I am aware (it has the header file, but is missing the (SDK directory)/WICED/RTOS folder which defines the RTOS).

Thanks for any help in advance, let me know if you need more information to answer my questions in paragraph 3.

0 Likes
2 Replies
AnjanaM_61
Moderator
Moderator
Moderator
5 comments on KBA First comment on KBA 5 questions asked

Hi,

Q)I'm guessing that if you get a callback generated by a pin interrupt which was registered with wiced_platform_register_button_callback, you must return within a set time period. What is this time period exactly, and where is it documented?

A) I think your interrupt routine is holding the CPU more than 2s.

The Watchdog Timer module in CYW20719 is based on a 32-bit down counter that is used to detect and recover from

malfunctions. During normal operation, the device regularly resets the watchdog timer before the count value reaches

zero to prevent it from elapsing, or timing out. If, due to a hardware fault or program error, the device fails to reset the

watchdog, the timer will elapse and generate a system reset on time out. The process of resetting the watchdog timer’s

counter is referred to as “kicking or petting the dog”. The default watchdog timeout is set to 2 seconds and watchdog

petting is done in the idle thread. Production applications need not pet the watchdog. Any application that attempts to

hold the CPU longer than 2 seconds will trigger the watchdog and reboot the system.

Q) RTOS functions

A) Please refer to wiced_rtos.h file (/20719-B1_Bluetooth/include/20719/wiced_rtos.h)

Comment: For fixing the issue, please make sure your interrupt routine is not holding CPU more than 2s.

Also please try to increase the size of buffer pool in wiced_bt_cfg_buf_pools of config file.

Note: wiced_bt_stack_init is mandatory to call regardless of whether you are using any BT functionalities or not.

Thanks,
Anjana

Well, this is thoroughly embarrassing. It turns out that I forgot to make the registered pointer to the callback function in my interrupt routine volatile, so I was ending up in a situation where it would all work for about 300ms or so before some operation in memory just happened to affect the cache and subsequently send my instruction counter to the wrong place. Oops, after fixing that things seem to work better now.

I'm also making a note of ensuring that wiced_bt_stack_init should always be called on init even in test code per your comment, so thanks for that.

But perhaps you could still help me understand the RTOS issue I was having. For example, adding the following code to the device will cause the application to crash. Making the pointer to the worker thread volatile does not help. There's no examples in the SDK that use the worker thread implementation for me to check and make sure I'm doing this the right way (unless I missed it). I'm using the WICED Studio 6.2.1.2 environment and the CYBT_423028_EVAL platform files if that helps, no other modifications to the SDK nor IDE.

________________________________

In file main.c:

#include "wiced_rtos.h"

#include "spi_hal.h" // My custom interface for the SPI bus

...

static wiced_worker_thread_t * worker_thread;

static wiced_result_t test_function(void* arg)

{

    uint8_t testarr[4] = {0x20, 0x00, 0x01, 0xAA};

    (void)arg;

    // For testing, don't assert CS because we don't want to send this to the sensor,

    // just catch it with a serial bus sniffer.

    // Pass bus selection, length, pointer to buffer

    spi_write(spi1, 4, testarr);

    return (WICED_SUCCESS);

}

...

// Called from BTM_ENABLED_EVT

static void application_init(void) {

    ...

    // My SPI bus initialization call which I know works (bus selection, pin selection, cs pin selection, clk speed)

    app_spi_setup(spi1, MASTER_P10_CLK_P28_MOSI_P29_MISO, SPI_CS_PIN, 500000);

    ...

    // Create and initialize a worker thread, and tell it to execute the test function

    worker_thread = wiced_rtos_create_worker_thread();

    wiced_rtos_init_worker_thread(local_worker_thread_pointer, 2, 4096, 16);

    wiced_rtos_send_asynchronous_event(local_worker_thread_pointer, test_function, NULL);

    ...

}

0 Likes