lindahnu 发表于 2024-7-2 18:02

CM32M433R 用户模式如何切换回机器模式

本帖最后由 lindahnu 于 2024-7-2 18:03 编辑

N级别处理器内核从User Mode切换到Machine Mode只能通过异常、响应中断或者NMI的方式发生:

响应异常进入异常处理模式。请参见第3.4节了解其详情。

注意:软件可以通过调用ecall指令强行进入ecall异常处理函数。

响应中断进入中断处理模式。请参见第5.6节了解其详情。

响应NMI进入NMI处理模式。请参见第4.3节了解其详情。

根据芯来科技的文档说明,进入用户模式后,Led()执行ecall命令就会进入异常中断ECALL_Exception_Handler,这时候是在M模式了吗?代码怎么能从异常中断回到主函数继续执行while循环里的语句呢?

/** @addtogroup CM32M4xxR_StdPeriph_Examples
* @{
*/
#define MACHINE_MODE_STACK_SIZE                        0x400
static uint8_t sMachineModeStack = {0};
//Configure test_array Acess Permission on PMP
void PMP_Config() {
      PMP_Region_InitTypeDef pmp_init;
      pmp_init.Number = PMP_REGION_NUMBER0;
      pmp_init.Enable = PMP_REGION_ENABLE;   // Enable Configuration
      pmp_init.Lock = PMP_REGION_UNLOCK; //
      pmp_init.BaseAddress = 0;//
      pmp_init.Size = PMP_REGION_SIZE_4GB;    //Setting array size
      pmp_init.AddressMatching = PMP_ADDRESS_MATCHING_NAPOT; //Setting PMP Size to NAPOT mode -> 2^n
      pmp_init.AccessPermission = PMP_ACCESS_RWX; //Setting array permission is Read Only
      PMP_ConfigRegion(&pmp_init);
      sPMP_Region_InitTypeDef spmp_init;
      spmp_init.Number = SPMP_REGION_NUMBER0;
      spmp_init.Enable = SPMP_REGION_ENABLE;
      spmp_init.Lock = SPMP_REGION_UNLOCK;
      spmp_init.BaseAddress = 0;
      spmp_init.Size = SPMP_REGION_SIZE_4GB;
      spmp_init.AddressMatching = SPMP_ADDRESS_MATCHING_NAPOT;
      spmp_init.UserMode = SPMP_USERMODE_RESET;
      spmp_init.AccessPermission = SPMP_ACCESS_RWX;
      sPMP_ConfigRegion(&spmp_init);
}
/**
* @brief Jump User Mode
*/
void JumpUserMode(uint32_t func)
{
      __RV_CSR_WRITE(CSR_MSCRATCH, sMachineModeStack + MACHINE_MODE_STACK_SIZE);
      __RV_CSR_CLEAR(CSR_MSTATUS, MSTATUS_MPP);
      __RV_CSR_WRITE(CSR_MEPC, func);
      __ASMvolatile ( "mret ");
}
void ECALL_Exception_Handler(unsigned long mcause,unsigned long sp)
{
   uint32_t saved_regs = sp;
   uint32_t mepc = ((uint32_t *)saved_regs);
   printf("ECALL Exception Trigger\r\n");
   ((uint32_t *)saved_regs) = mepc + 4;
}
/**
* @brief User Mode Application
*/
void Led()
{
      LedInit(LED2_PORT, LED2_PIN);
      __ECALL();
}
/**
* @brief Main function
*/
int main(void) {
      /* System Clocks Configuration */
      PMP_Config();
      Exception_Register_EXC(UmodeEcall_EXCn, (unsigned long)ECALL_Exception_Handler);
      JumpUserMode((uint32_t)Led);
      while (1) {
            LedBlink(LED2_PORT, LED2_PIN);
            delay_ms(1000);
      }
}

LOVEEVER 发表于 2024-7-15 14:41

N级别处理器内核从User Mode切换到Machine Mode只能通过异常、响应中断或者NMI的方式发生

szt1993 发表于 2024-7-17 19:27

恢复出厂设置就可以的
页: [1]
查看完整版本: CM32M433R 用户模式如何切换回机器模式