kopia lustrzana https://github.com/espressif/esp-idf
gpio/driver: Sped the gpio_intr_service ISR up by 1.5 uSeconds (+-50% faster).
Removed as much branching (if statements) from the gpio_intr_service ISR, as possible and split the while loop into two. Also forced writing the two status*_w1tc variables only once, instead of every time after calling the external function hooks. The measurements below, was done using the following tools: Toolchain version: crosstool-ng-1.22.0-80-g6c4433a Compiler version: 5.2.0 Here follows a comparison of the gpio_intr_service ISR's execution time, using a DS1054 oscilloscope. All the time spent calling external functions, via the function pointers gpio_isr_func[gpio_num].fn, were disregarded. With OPTIMIZATION_FLAGS = -Og, 1.34 uSeconds faster: 3.22 uSec (with this patch) 4.56 uSec (with commitpull/3216/head71c90ac4
) 100 - (100 * 4.56 / 3.22) = 42% faster With OPTIMIZATION_FLAGS = -Os, 1.65 uSeconds faster: 2.89 uSec (with this patch) 4.54 uSec (with commit71c90ac4
) 100 - (100 * 4.54 / 2.89) = 57% faster Signed-off-by: Konstantin Kondrashov <konstantin@espressif.com> Merges https://github.com/espressif/esp-idf/pull/2861
rodzic
d34ca0b897
commit
b8dc48ab18
|
@ -327,37 +327,37 @@ esp_err_t gpio_reset_pin(gpio_num_t gpio_num)
|
|||
return ESP_OK;
|
||||
}
|
||||
|
||||
void IRAM_ATTR gpio_intr_service(void* arg)
|
||||
static inline void IRAM_ATTR gpio_isr_loop(uint32_t status, const uint32_t gpio_num_start) {
|
||||
while (status) {
|
||||
int nbit = __builtin_ffs(status) - 1;
|
||||
status &= ~(1 << nbit);
|
||||
int gpio_num = gpio_num_start + nbit;
|
||||
if (gpio_isr_func[gpio_num].fn != NULL) {
|
||||
gpio_isr_func[gpio_num].fn(gpio_isr_func[gpio_num].args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void IRAM_ATTR gpio_intr_service(void* arg)
|
||||
{
|
||||
//GPIO intr process
|
||||
uint32_t gpio_num = 0;
|
||||
//read status to get interrupt status for GPIO0-31
|
||||
uint32_t gpio_intr_status;
|
||||
gpio_intr_status = GPIO.status;
|
||||
//read status1 to get interrupt status for GPIO32-39
|
||||
uint32_t gpio_intr_status_h;
|
||||
gpio_intr_status_h = GPIO.status1.intr_st;
|
||||
|
||||
if (gpio_isr_func == NULL) {
|
||||
return;
|
||||
}
|
||||
do {
|
||||
if (gpio_num < 32) {
|
||||
if (gpio_intr_status & BIT(gpio_num)) { //gpio0-gpio31
|
||||
if (gpio_isr_func[gpio_num].fn != NULL) {
|
||||
gpio_isr_func[gpio_num].fn(gpio_isr_func[gpio_num].args);
|
||||
|
||||
//read status to get interrupt status for GPIO0-31
|
||||
const uint32_t gpio_intr_status = GPIO.status;
|
||||
if (gpio_intr_status) {
|
||||
gpio_isr_loop(gpio_intr_status, 0);
|
||||
GPIO.status_w1tc = gpio_intr_status;
|
||||
}
|
||||
GPIO.status_w1tc = BIT(gpio_num);
|
||||
|
||||
//read status1 to get interrupt status for GPIO32-39
|
||||
const uint32_t gpio_intr_status_h = GPIO.status1.intr_st;
|
||||
if (gpio_intr_status_h) {
|
||||
gpio_isr_loop(gpio_intr_status_h, 32);
|
||||
GPIO.status1_w1tc.intr_st = gpio_intr_status_h;
|
||||
}
|
||||
} else {
|
||||
if (gpio_intr_status_h & BIT(gpio_num - 32)) {
|
||||
if (gpio_isr_func[gpio_num].fn != NULL) {
|
||||
gpio_isr_func[gpio_num].fn(gpio_isr_func[gpio_num].args);
|
||||
}
|
||||
GPIO.status1_w1tc.intr_st = BIT(gpio_num - 32);
|
||||
}
|
||||
}
|
||||
} while (++gpio_num < GPIO_PIN_COUNT);
|
||||
}
|
||||
|
||||
esp_err_t gpio_isr_handler_add(gpio_num_t gpio_num, gpio_isr_t isr_handler, void* args)
|
||||
|
|
Ładowanie…
Reference in New Issue