Wifi Driver Receive Buffer Access/Interrupt
Wifi Driver Receive Buffer Access/Interrupt
Hi All,
I'm currently trying to implement a synchronization Protocol called 'SyncTSF', where the core idea is to always keep the System time adjusted to the Wi-Fi TSF-Timer value. Now, as per standard, the local TSF timer of an STA is automatically synched to the AP's TSF timer value by applying an offset contained in a beacons Timestamp field. To eliminate skew-related synchronization errors, the System time should be updated asap after the TSF timer has been updated. To achieve that, I would like to trigger an interrupt every time a frame was received and update my system clock. Is there any way to achieve this behavior while not using promiscuous mode? I couldn't find anything in the docs or the Wi-Fi drivers source code.
Cheers,
Dennis
I'm currently trying to implement a synchronization Protocol called 'SyncTSF', where the core idea is to always keep the System time adjusted to the Wi-Fi TSF-Timer value. Now, as per standard, the local TSF timer of an STA is automatically synched to the AP's TSF timer value by applying an offset contained in a beacons Timestamp field. To eliminate skew-related synchronization errors, the System time should be updated asap after the TSF timer has been updated. To achieve that, I would like to trigger an interrupt every time a frame was received and update my system clock. Is there any way to achieve this behavior while not using promiscuous mode? I couldn't find anything in the docs or the Wi-Fi drivers source code.
Cheers,
Dennis
-
- Posts: 5
- Joined: Wed Mar 31, 2021 6:40 am
Re: Wifi Driver Receive Buffer Access/Interrupt
Have a lock at the MAC_INTR
https://www.espressif.com/sites/default ... ual_en.pdf
And ETS_WMAC_INUM in the git repo:
https://github.com/espressif/esp-idf/se ... _WMAC_INUM
https://www.espressif.com/sites/default ... ual_en.pdf
And ETS_WMAC_INUM in the git repo:
https://github.com/espressif/esp-idf/se ... _WMAC_INUM
Re: Wifi Driver Receive Buffer Access/Interrupt
Hi David,
first of all, thank you for your answer! It definitely pointed me into the right direction. I have now tried to install an interrupt using the ETS_WIFI_MAC_INTR_SOURCE in the following fashion:
1.) I created a freeRTOS Event group to handle some events of my SyncTSF service. The only thing the interrupt is supposed to do at the moment is to set an event bit when it's triggered, which will then in turn signal the event handler to print a message on the console. Here is how I create the task:
2.) The interrupt is allocated and started within that same task if the SyncTSF start function sets the dedicated bit. In that way I make sure the interrupt is created on the same core the task is running. The code of this specific section looks like this:
3.) Finally, as I said, the interrupt handler which sets the SYNC_TSF_WIFI_PROBE_RCVD Bit to trigger the Event:
4.) Now, when I do everything as described, I immediately get a core panic with the following message after the interrupt is entered for the first time:
This only happens when I create my event handler task on core 0. If I try to create it on core 1, the interrupt handler is never entered. I also tried to increase the watchdog timeout value, but that didn't help either. When I try the functions provided in the rom/ets_sys.h library, it has the same effect (nothing happens basically == the interrupt is either never entered or not created at all). I know that what I'm doing isn't thread safe but that shouldn't be the reason for the core panic. Since this interrupt source is probably used also by the WiFi PHY driver, could that be the reason for this kind of behavior? What am I missing here?
first of all, thank you for your answer! It definitely pointed me into the right direction. I have now tried to install an interrupt using the ETS_WIFI_MAC_INTR_SOURCE in the following fashion:
1.) I created a freeRTOS Event group to handle some events of my SyncTSF service. The only thing the interrupt is supposed to do at the moment is to set an event bit when it's triggered, which will then in turn signal the event handler to print a message on the console. Here is how I create the task:
Code: Select all
void syncTSF_init(void){
syncTSF_event_group = xEventGroupCreate();
syncTSF_event_group_mutex = xSemaphoreCreateMutex();
xTaskCreatePinnedToCore(&syncTSF,
"SyncTSF",
2048,
&syncTSF_interrupt_handle,
4,
syncTSF_task,
0);
}
Code: Select all
static void syncTSF(void *pvParameters){
const EventBits_t xBitsToWaitFor = ( SYNC_TSF_STARTED | SYNC_TSF_STOPPED | SYNC_TSF_WIFI_PROBE_RCVD );
EventBits_t xEventGroupValue;
const TickType_t xTicksToWait = 200 / portTICK_PERIOD_MS;
for(;;){
xEventGroupValue = xEventGroupWaitBits(syncTSF_event_group, xBitsToWaitFor, pdFALSE, pdFALSE, xTicksToWait);
/* Print the Event Bits for debugging */
ESP_LOGI(TAG, "Event Bits value: %d", (uint32_t) xEventGroupValue);
/* This is where the message gets printed in case the interrupt handler sets the SYNC_TSF_WIFI_PROBE_RCVD Bit */
if((xEventGroupValue & ( SYNC_TSF_RUNNING | SYNC_TSF_WIFI_PROBE_RCVD )) ==
( SYNC_TSF_RUNNING | SYNC_TSF_WIFI_PROBE_RCVD )){
ESP_LOGI(TAG, "Interupt triggered");
}
}
else if((xEventGroupValue & SYNC_TSF_STARTED) && syncTSF_intr_handle == NULL){
ESP_LOGI(TAG, "SyncTSF Service Started");
/* Allocate Interrupt */
esp_intr_alloc( ETS_WIFI_MAC_INTR_SOURCE,
ESP_INTR_FLAG_SHARED,
&syncTSF_interrupt_handle,
NULL,
&syncTSF_intr_handle);
/* Set the Service in running state */
xEventGroupSetBits(syncTSF_event_group, SYNC_TSF_RUNNING);
xEventGroupClearBits(syncTSF_event_group, SYNC_TSF_STARTED);
esp_intr_enable(syncTSF_intr_handle);
}
}
}
Code: Select all
void syncTSF_interrupt_handle(void *arg){
xEventGroupClearBitsFromISR(syncTSF_event_group, SYNC_TSF_WIFI_PROBE_RCVD);
}
Code: Select all
␛[0;32mI (3153) SyncTSF: Event Bits value: 2␛[0m
␛[0;32mI (3163) SyncTSF: SyncTSF Service Started␛[0m
Guru Meditation Error: Core 0 panic'ed (Interrupt wdt timeout on CPU0).
Re: Wifi Driver Receive Buffer Access/Interrupt
You didn't clear the interrupt
Re: Wifi Driver Receive Buffer Access/Interrupt
Hi WiFive,
thanks for taking a look into it. Can you explain what you mean by 'clearing' the interrupt? I haven't encountered this terminus in the context of the ESP32 and I can't find a reference to this anywhere in the api or the technical reference manual.
Thanks a lot!
Dennis
thanks for taking a look into it. Can you explain what you mean by 'clearing' the interrupt? I haven't encountered this terminus in the context of the ESP32 and I can't find a reference to this anywhere in the api or the technical reference manual.
Thanks a lot!
Dennis
-
- Posts: 5
- Joined: Wed Mar 31, 2021 6:40 am
Re: Wifi Driver Receive Buffer Access/Interrupt
One way is to let the wifi driver setup the interrupt handler. Then you could replace it with your own and call the "original" wmac handler. Assuming it to clear/acknowledge the interrupt properly.
Example:
Example:
Code: Select all
#include <freertos/FreeRTOS.h>
#include <esp_intr_alloc.h>
static xt_handler wmac_xt_handler;
/*
* My ISR routine for WMAC interuppt
*/
void IRAM_ATTR m_isr_wmac(void* param)
{
// Do stuff here
/*
* Call previous configured interrupt handler
* Assume it will enable the interrupt properly.
*/
wmac_xt_handler(param);
}
/*
* m_isr_init must be called after the wifi module has ben configured.
* In order to get the correct interrupt handler
*/
void m_isr_init(void)
{
if (xt_int_has_handler(ETS_WMAC_INUM, xPortGetCoreID()))
{
ESP_INTR_DISABLE(ETS_WMAC_INUM);
wmac_xt_handler = xt_set_interrupt_handler(ETS_WMAC_INUM, &m_isr_wmac, NULL);
ESP_INTR_ENABLE(ETS_WMAC_INUM);
}
else
{
printf("m_isr_init: wmac_isr not set\n");
}
}
void m_isr_deinit(void)
{
if (wmac_xt_handler)
{
ESP_INTR_DISABLE(ETS_WMAC_INUM);
xt_set_interrupt_handler(ETS_WMAC_INUM, wmac_xt_handler, NULL);
ESP_INTR_ENABLE(ETS_WMAC_INUM);
}
}
Re: Wifi Driver Receive Buffer Access/Interrupt
So, I finally had the time to come back to this and try your example. Worked like a charm. Thanks, David!
-
- Posts: 27
- Joined: Sun Jan 14, 2018 7:47 pm
Re: Wifi Driver Receive Buffer Access/Interrupt
I can't find ETS_WIFI_MAC_INTR_SOURCE in the linked technical documentation pdf. Where can i find a description of this interrupt source?
Who is online
Users browsing this forum: No registered users and 113 guests