ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Среда
29 апреля
1584250 Топик полностью
il-2 (Сегодня, 07:08, просмотров: 31) ответил Nikolay_Po на В общем, казалось бы, победил, поправив ключи компилятора. Но нет: стал опять падать. Причём, в зависимости от кода (использовал IQmath_RV32 или float - пробовал и то, и другое) получал целый ряд причин отказа mcause - от 4й до 7й (interrupt = 0):
Могу выдвинуть такое предположение: 

Раз проблемы нет с обычными прерываниями и появляются с аппаратными, значит регистры при прерываниях неправильно (или вообще не) сохраняются-восстанавливаются.

В регистре MSTATUS есть биты MPPOP и MPOP, которые отвечают за то, какое было выполнено прерывание - программное(0) или аппаратное(1).

Если ты для запрета/разрешения прерываний пишешь значения в MSTATUS со сброшенными MPPOP, MPOP - то это может сбить механизм возврата из прерывания. Например вошел в прерывание HPE, там как-то сбросил MPOP - и выход из прерывания будет уже программный (с извлечением регистров из программного стека).

Ну - я во всяком случае так понимаю работу этих MPPOP, MPOP

Я у себя для запрета/разрешения прерываний использую прямую запись в MSTATUS, при этом в MPPOP,MPOP напрямую пишу 0(Если в проекте поддержка программных прерываний) или 1(если прерывания HPE).

как-то так:

// Project CPU config:

/**====================================================================================**

* @brief CH5xx PFIC and privilege configuration

**====================================================================================**/

#define CPU_CONF_PRIVILEGE_LEVEL 3 /**< @brief CPU privilege work mode (3(Machine), 0(User - do not use, this mode dont have glodal interrupt disable/enable control ???)) */

#define CPU_CONF_PFIC_NEST_LEVEL 2 /**< @brief Interrupt nesting level (1(No nesting), 2(2-level)) */

#define CPU_CONF_PFIC_HPE_ENABLE 1 /**< @brief Interrupt HPE(Hardware Prologue/Epilogue) (0(Disable), 1(Enable)) */

...



/**==========================================================================**

* @brief Static value for write to MSTATUS:

* bit 24,23 - MPPOP,MPOP - stack flags for sub-active and active(current/nested) interrupts

* bit 12,11 - MPP privileged mode

**==========================================================================**/

#define CPU_CONF_MSTATUS_STATIC_VAL (((CPU_CONF_PRIVILEGE_LEVEL)<<11) | ((CPU_CONF_PFIC_HPE_ENABLE)?0:0x18000000))

static C_INLINE void CPU_RT_Lock(void) /**< @brief Disable all interrupts (lock CPU) */

{

#if ( CPU_CONF_PRIVILEGE_LEVEL == 3 ) /* Machine level */

// __bitclr_MSTATUS(0x08);

__set_MSTATUS(CPU_CONF_MSTATUS_STATIC_VAL | 0x80);

#else

#error "Unsupported privilege level"

#endif

#if ( defined(DCPU_CORE_RISCV_WCH_V2A) || defined(DCPU_CORE_RISCV_WCH_V2C) )

__nop(); // Fill 2-level flow instruction line for QingKe V2A,V2C

#elif ( defined(DCPU_CORE_RISCV_WCH_V3A) || defined(DCPU_CORE_RISCV_WCH_V3B) || defined(DCPU_CORE_RISCV_WCH_V3C) \

|| defined(DCPU_CORE_RISCV_WCH_V4A) || defined(DCPU_CORE_RISCV_WCH_V4B) || defined(DCPU_CORE_RISCV_WCH_V4C) || defined(DCPU_CORE_RISCV_WCH_V4F) )

__nop(); __nop(); // Fill 3-level flow instruction line for QingKe V3A,V3B,V3C,V4A,V4B,V4C,V4F

#else

#error "Unsupported CPU core"

#endif

}

static C_INLINE void CPU_RT_Unlock(void) /**< @brief Enable all interrupts (unlock CPU) */

{

#if ( CPU_CONF_PRIVILEGE_LEVEL == 3 ) /* Machine level */

// __bitset_MSTATUS(0x08);

__set_MSTATUS(CPU_CONF_MSTATUS_STATIC_VAL | 0x88);

#else

#error "Unsupported privilege level"

#endif

}

static C_INLINE ufast_t CPU_RT_LockStatus(void) /**< @brief Get CPU lock status (0x08 - CPU unlocked (interrupts enabled), 0x00 - CPU locked (interrupts disabled)) */

{

#if ( CPU_CONF_PRIVILEGE_LEVEL == 3 ) /* Machine level */

return __get_MSTATUS() & 0x08;

#else

#error "Unsupported privilege level"

#endif

}

static C_INLINE void CPU_RT_LockRestore(ufast_t lock_state) /**< @brief Restore CPU lock state, gived by CPU_RT_LockStatus() */

{

#if ( CPU_CONF_PRIVILEGE_LEVEL == 3 ) /* Machine level */

if ( lock_state )

CPU_RT_Unlock();

else

CPU_RT_Lock();

#else

#error "Unsupported privilege level"

#endif

}