我有一个使用高级(5 级)GPIO 中断和高级定时器中断的项目。以前它与 ESP-IDF V4.4 配合得很好。这周我更新了IDF到V5.0版本,编译烧写后,GPIO中断和定时器中断都不起作用了。有谁知道哪里出了问题,或者可能是 idf v5.0 的错误?有没有关于高级中断的文档可以参考?
芯片:ESP32S3-N8R2。
IDF 从 v4.4 更新到 v5.0。
语言:C++ 和汇编
5 级 GPIO 中断 ID:
31,5 级定时器中断 ID 16,使用 CCOMPARE_2。
GPIO或定时器中断的注册成功,但是一旦GPIO或定时器中断触发,两个CPU核心都卡在了某个地方。5 级 intr 处理程序中有代码清除 GPIO 中断标志并设置 ccompare_2,但不知何故它可能不适用于 idf v5。下面附上
main.cpp和
Sampling_Int.S
的代码。该代码适用于 idf v4,无论中断处理程序和系统主任务运行在哪个 CPU 核心。
主.cpp:
代码:
全选
#include
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "xtensa/core-macros.h"
#include "driver/gpio.h"
#include "soc/soc.h"
#include "soc/periph_defs.h"
#include "esp_log.h"
//#include "esp_rom_gpio.h"
#include "rom/ets_sys.h"
#define PPS_PIN 8
uint32_t AlarmValue = 240000000;
uint32_t IntCounter[2];
void RegisterInt(void *you_need_this)
{
gpio_set_intr_type((gpio_num_t)PPS_PIN, GPIO_INTR_POSEDGE);
gpio_intr_enable((gpio_num_t)PPS_PIN);
gpio_config_t cfg;
cfg.intr_type=GPIO_INTR_POSEDGE;
cfg.pin_bit_mask=(1ULL<
cfg.mode=GPIO_MODE_INPUT;
cfg.pull_up_en=GPIO_PULLUP_DISABLE;
cfg.pull_down_en=GPIO_PULLDOWN_DISABLE;
ESP_ERROR_CHECK(gpio_config(&cfg));
WSR(CCOMPARE_2, 2400000);
ESP_LOGE("Intr", "Try to enable timer intr.");
xt_ints_on(1 << 16);
ESP_LOGE("Intr", "Try to enable PPS intr.");
xt_ints_on(1 << 31);
ESP_LOGE("Intr", "Try to register PPS intr.");
intr_matrix_set(0, ETS_GPIO_INTR_SOURCE, 31);
ESP_LOGE("Intr", "Register Intr done.");
vTaskDelete(NULL);
}
void Output(void *you_need_this)
{
int iii=0;
while(1)
{
printf("n[%d]Interrupt Counter =%lu",++iii,IntCounter[0]);
vTaskDelay(500/portTICK_PERIOD_MS);
}
}
extern "C"
void app_main(void)
{
xTaskCreatePinnedToCore(Output,"Out",4096,NULL,0,NULL,0);
vTaskDelay(3000/portTICK_PERIOD_MS);
xTaskCreatePinnedToCore(RegisterInt,"allocEXTGPIOINT",4096,NULL,0,NULL,0);
while(1)
vTaskDelay(1000/portTICK_PERIOD_MS);
}
Sampling_Int.S:
代码:全选
#include
#include
#include
#include "soc/gpio_reg.h"
#define PPS_PIN 8
#define PPS_INT_Sta_REG GPIO_STATUS_REG
#define PPS_INT_W1TC_REG GPIO_STATUS_W1TC_REG
#define PPS_Mask (1<
.section .iram1,"ax"
_l5_intr_stack:
.space 64
//Interrupt Handler
.section .iram1,"ax"
.global xt_highint5
.type xt_highint5,@function
.align 4
xt_highint5:
/////////////////////////////////////////////////////////////////////////////////////////////////////
//save register values. It takes around 15 cpu cycles to save the register valeus.
movi a0, _l5_intr_stack
s32i a5, a0, 0
s32i a6, a0, 4
s32i a7, a0, 8
s32i a4, a0, 44
s32i a3, a0, 48
s32i a2, a0, 52
s32i a1, a0, 56
rsr a1, SAR
s32i a1, a0, 60
//////////////////Interrupt handling start////////////////////////////////
YourCodeHere:
//----------------------------
//increase ccompare_2 by 60M
movi a5, AlarmValue
l32i a7, a5, 0
movi a6, 60000000
add a7, a7, a6
wsr a7, CCOMPARE_2
s32i a7, a5, 0
//---------------------------
//reset intr flag (no matter if it is gpio interrupt)
movi a3, GPIO_STATUS_W1TC_REG //get REG to clear the interrupt status
movi a4, PPS_Mask //load Pin mask
s32i a4, a3, 0 //write the mask to Int clear REG
memw
//increase IntCounter[0] by 1
movi a3, IntCounter
l32i a4, a3, 0
addi a4, a4, 1
s32i a4, a3, 0
SAVE_EXIT:
movi a0, _l5_intr_stack
l32i a5, a0, 60
wsr a5, SAR //restore shift register
l32i a5, a0, 0
l32i a6, a0, 4
l32i a7, a0, 8
l32i a4, a0, 44
l32i a3, a0, 48
l32i a2, a0, 52
l32i a1, a0, 56
//---------------------------------------------------------------
//return
EXIT:
rsr a0, EXCSAVE_5 /* restore a0 */
rfi 5
.global ld_include_highint_hdl_my
ld_include_highint_hdl_my:
CMakeLists.txt:
代码:全选
idf_component_register(SRCS
"main.cpp"
"Sampling_Int.S"
INCLUDE_DIRS ".")
target_link_libraries(${COMPONENT_TARGET} "-u ld_include_highint_hdl_my")