简体   繁体   English

使用GDB在Cortex-M上进行软复位

[英]Soft reset on a Cortex-M using GDB

I'm working on a set of debugging tools for some in-house Cortex-M4 cores. 我正在为一些内部Cortex-M4内核开发一套调试工具。 I'm building embedded (no OS) ELF images using a gcc/binutils toolchain and simulating them using a modified version of QEMU. 我正在使用gcc / binutils工具链构建嵌入式(无OS)ELF图像,并使用修改后的QEMU版本对其进行仿真。 I'm creating the interrupt vector tables at the start (ie 0) of my images, and correctly initialising the stack pointer, and start address (ie the address of main). 我正在图像的开头(即0)创建中断向量表,并正确初始化堆栈指针和起始地址(即main的地址)。

The target programs are running as expected, and the debug tools which are built using the GDB remote protocol are working correctly. 目标程序正在按预期运行,并且使用GDB远程协议构建的调试工具可以正常工作。

What I'm currently trying to understand is how to initiate a soft-reset from GDB. 我目前想了解的是如何从GDB启动软重置。 That is, arrange for the target program to be reinitialised with the stack pointer reset to the initial value in the vector table, and the PC back at the start address. 也就是说,安排将目标程序重新初始化,堆栈指针复位为向量表中的初始值,然后PC返回起始地址。

I have already demonstrated to myself that the action of setting the PC value to 0, and running the core is not appropriate, and the result was that my "UsageFault" exception handler was invoked. 我已经向我自己证明了将PC值设置为0并运行内核的操作是不合适的,其结果是调用了我的“ UsageFault”异常处理程序。 (I assume that the core is in the wrong mode to execute this kind of action). (我假设核心处于执行这种操作的错误模式)。

Is there a technique, ie by register writes using GDB remote protocol that I can soft-reset the simulated core, that is without having to power-cycle the QEMU session? 是否有一种技术,即通过使用GDB远程协议的寄存器写操作,可以对模拟内核进行软复位,而无需重新启动QEMU会话?

You can make SW restart by writing SYSRESETREQ bit + KEY into AIRCR register: 您可以通过将SYSRESETREQ位+ KEY写入AIRCR寄存器来使SW重新启动:

AIRCR_REG_ADDRESS = 0xe000ed0c
AIRCR_KEY = 0x05fa0000
AIRCR_SYSRESETREQ_BIT = 0x00000004

AIRCR_REG = AIRCR_KEY | AIRCR_SYSRESETREQ_BIT

More info is here 更多信息在here

This is working with all cortex-M 这适用于所有cortex-M

This is a snippet of code for a Cortex-M3 I use to jump to any location with valid code in (including jumping to 0): 这是Cortex-M3的一小段代码,我使用它来跳转到具有有效代码的任何位置(包括跳转到0):

   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();

This code assumes jumpaddr is the base address of a vector table, as the stack pointer is first in the table and reset handler is second in the table. 此代码假定jumpaddr是向jumpaddr的基地址,因为堆栈指针在表中排在第一位,而重置处理程序在表中排在第二位。

Disabling interrupts is a must as you could have an interrupt go off after you have moved the stack pointer which normally causes an exception. 禁用中断是必须的,因为在移动堆栈指针(通常会导致异常)之后,中断可能会中断。

Of course, doing it this way will not reset any peripherals so that would need to be done before enabling the interrupts again. 当然,以这种方式进行操作不会重置任何外设,因此需要在再次启用中断之前进行此操作。

Edit: 编辑:

You can find the contents of __set_MSP here . 您可以在此处找到__set_MSP的内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM