[RISC-V MCU 应用开发] CM32M433R 用户模式如何切换回机器模式

[复制链接]
1890|2
 楼主| lindahnu 发表于 2024-7-2 18:02 | 显示全部楼层 |阅读模式
本帖最后由 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循环里的语句呢?

  1. /** @addtogroup CM32M4xxR_StdPeriph_Examples
  2. * @{
  3. */
  4. #define MACHINE_MODE_STACK_SIZE                        0x400
  5. static uint8_t sMachineModeStack[MACHINE_MODE_STACK_SIZE] = {0};
  6. //Configure test_array Acess Permission on PMP
  7. void PMP_Config() {
  8.         PMP_Region_InitTypeDef pmp_init;
  9.         pmp_init.Number = PMP_REGION_NUMBER0;
  10.         pmp_init.Enable = PMP_REGION_ENABLE;   // Enable Configuration
  11.         pmp_init.Lock = PMP_REGION_UNLOCK; //
  12.         pmp_init.BaseAddress = 0;  //
  13.         pmp_init.Size = PMP_REGION_SIZE_4GB;    //Setting array size
  14.         pmp_init.AddressMatching = PMP_ADDRESS_MATCHING_NAPOT; //Setting PMP Size to NAPOT mode -> 2^n
  15.         pmp_init.AccessPermission = PMP_ACCESS_RWX; //Setting array permission is Read Only
  16.         PMP_ConfigRegion(&pmp_init);
  17.         sPMP_Region_InitTypeDef spmp_init;
  18.         spmp_init.Number = SPMP_REGION_NUMBER0;
  19.         spmp_init.Enable = SPMP_REGION_ENABLE;
  20.         spmp_init.Lock = SPMP_REGION_UNLOCK;
  21.         spmp_init.BaseAddress = 0;
  22.         spmp_init.Size = SPMP_REGION_SIZE_4GB;
  23.         spmp_init.AddressMatching = SPMP_ADDRESS_MATCHING_NAPOT;
  24.         spmp_init.UserMode = SPMP_USERMODE_RESET;
  25.         spmp_init.AccessPermission = SPMP_ACCESS_RWX;
  26.         sPMP_ConfigRegion(&spmp_init);
  27. }
  28. /**
  29. * [url=home.php?mod=space&uid=247401]@brief[/url] Jump User Mode
  30. */
  31. void JumpUserMode(uint32_t func)
  32. {
  33.         __RV_CSR_WRITE(CSR_MSCRATCH, sMachineModeStack + MACHINE_MODE_STACK_SIZE);
  34.         __RV_CSR_CLEAR(CSR_MSTATUS, MSTATUS_MPP);
  35.         __RV_CSR_WRITE(CSR_MEPC, func);
  36.         __ASM  volatile ( "mret ");
  37. }
  38. void ECALL_Exception_Handler(unsigned long mcause,unsigned long sp)
  39. {
  40.    uint32_t saved_regs = sp;
  41.    uint32_t mepc = ((uint32_t *)saved_regs)[12];
  42.    printf("ECALL Exception Trigger\r\n");
  43.    ((uint32_t *)saved_regs)[12] = mepc + 4;
  44. }
  45. /**
  46. * [url=home.php?mod=space&uid=247401]@brief[/url] User Mode Application
  47. */
  48. void Led()
  49. {
  50.         LedInit(LED2_PORT, LED2_PIN);
  51.         __ECALL();
  52. }
  53. /**
  54. * @brief Main function
  55. */
  56. int main(void) {
  57.         /* System Clocks Configuration */
  58.         PMP_Config();
  59.         Exception_Register_EXC(UmodeEcall_EXCn, (unsigned long)ECALL_Exception_Handler);
  60.         JumpUserMode((uint32_t)Led);
  61.         while (1) {
  62.             LedBlink(LED2_PORT, LED2_PIN);
  63.             delay_ms(1000);
  64.         }
  65. }
LOVEEVER 发表于 2024-7-15 14:41 | 显示全部楼层
N级别处理器内核从User Mode切换到Machine Mode只能通过异常、响应中断或者NMI的方式发生
szt1993 发表于 2024-7-17 19:27 | 显示全部楼层
恢复出厂设置就可以的
您需要登录后才可以回帖 登录 | 注册

本版积分规则

15

主题

31

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部