首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用GDB在Cortex-M上进行软重置

使用GDB在Cortex-M上进行软重置
EN

Stack Overflow用户
提问于 2017-12-01 17:06:56
回答 2查看 1.7K关注 0票数 3

我正在为一些内部的Cortex-M4内核开发一套调试工具。我正在使用一个gcc/binutils工具链构建嵌入式(无操作系统) ELF镜像,并使用QEMU的一个修改版本来模拟它们。我在图像的开始处(即0)创建了中断向量表,并正确初始化了堆栈指针和开始地址(即main的地址)。

目标程序运行正常,使用GDB remote协议构建的调试工具工作正常。

我现在想知道的是如何从GDB启动一个软重置。也就是说,安排目标程序重新初始化,将堆栈指针重置为向量表中的初始值,并将PC返回到起始地址。

我已经向自己演示了将PC值设置为0并运行内核的操作是不合适的,结果是调用了我的"UsageFault“异常处理程序。(我假设内核处于错误的模式,无法执行此类操作)。

有没有一种技术,即通过使用GDB远程协议的寄存器写入,我可以软重置模拟的内核,也就是说,不需要重新启动QEMU会话?

EN

回答 2

Stack Overflow用户

发布于 2017-12-02 02:51:06

可通过将SYSRESETREQ位+密钥写入AIRCR寄存器来进行软件重启:

代码语言:javascript
复制
AIRCR_REG_ADDRESS = 0xe000ed0c
AIRCR_KEY = 0x05fa0000
AIRCR_SYSRESETREQ_BIT = 0x00000004

AIRCR_REG = AIRCR_KEY | AIRCR_SYSRESETREQ_BIT

更多信息请访问here

这是与所有皮质-M一起工作

票数 1
EN

Stack Overflow用户

发布于 2017-12-06 17:05:01

这是Cortex-M3的代码片段,我使用它跳转到任何包含有效代码的位置(包括跳转到0):

代码语言:javascript
复制
   IRQn_Type interrupt = (IRQn_Type)0;
   app_fn jump = *(app_fn *)(jumpaddr + sizeof(int));     //Reset is 2nd in table
   uint32_t stack_adr = *(uint32_t *)(jumpaddr);         //Stack pointer is 1st in table

   //Disable interrupts before jumping
   SysTick->CTRL &= ~ST_CTRL_ENABLE;

   while (interrupt <= CANActivity_IRQn)
   {
      NVIC_DisableIRQ(interrupt);
      interrupt++;
   }

   //Set the new stack pointer
   __set_MSP(stack_adr);

   //Set the new vector address
   SCB->VTOR = (location & 0x1FFFFF80);

   //Leap of faith!
   jump();

此代码假设jumpaddr是向量表的基地址,因为堆栈指针在表中是第一个,重置处理程序在表中是第二个。

禁用中断是必须的,因为您可能会在移动堆栈指针后触发中断,这通常会导致异常。

当然,这样做不会重置任何外设,因此需要在再次启用中断之前完成。

编辑:

您可以找到__set_MSP here的内容。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47589934

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档