4

我正在尝试调试我为 NXP LPC1850 评估板编写的一些软件。目前,当我停止我的代码时,我看不到它在我的 C 代码中的位置,但我可以在反汇编程序窗口中看到。

它挂在的行位于地址 0x40。指令是 BN 。我在 ARM Information Center 上查找过它,但我对汇编程序一无所知,恐怕即使在阅读之后,它对我来说也毫无意义。

      0x0: 0x9ff0         LDR       R7, [SP, #0x3c0]
      0x2: 0x1008         ASRS      R0, R1, #32
      0x4: 0x2bad         CMP       R3, #173                ; 0xad
      0x6: 0x1040         ASRS      R0, R0, #1
      0x8: 0x0041         LSLS      R1, R0, #1
      0xa: 0x1040         ASRS      R0, R0, #1
      0xc: 0x0043         LSLS      R3, R0, #1
      0xe: 0x1040         ASRS      R0, R0, #1
     0x10: 0x0045         LSLS      R5, R0, #1
     0x12: 0x1040         ASRS      R0, R0, #1
     0x14: 0x0047         LSLS      R7, R0, #1
     0x16: 0x1040         ASRS      R0, R0, #1
     0x18: 0x0049         LSLS      R1, R1, #1
     0x1a: 0x1040         ASRS      R0, R0, #1
     0x1c: 0x0000         MOVS      R0, R0
     0x1e: 0x0000         MOVS      R0, R0
     0x20: 0x0000         MOVS      R0, R0
     0x22: 0x0000         MOVS      R0, R0
     0x24: 0x0000         MOVS      R0, R0
     0x26: 0x0000         MOVS      R0, R0
     0x28: 0x0000         MOVS      R0, R0
     0x2a: 0x0000         MOVS      R0, R0
     0x2c: 0x004b         LSLS      R3, R1, #1
     0x2e: 0x1040         ASRS      R0, R0, #1
     0x30: 0x004d         LSLS      R5, R1, #1
     0x32: 0x1040         ASRS      R0, R0, #1
     0x34: 0x0000         MOVS      R0, R0
     0x36: 0x0000         MOVS      R0, R0
     0x38: 0x004f         LSLS      R7, R1, #1
     0x3a: 0x1040         ASRS      R0, R0, #1
     0x3c: 0x1645         ASRS      R5, R0, #25
     0x3e: 0x1040         ASRS      R0, R0, #1
     0x40: 0xe7fe         B.N       0x40
     0x42: 0xe7fe         B.N       0x42
     0x44: 0xe7fe         B.N       0x44
     0x46: 0xe7fe         B.N       0x46
     0x48: 0xe7fe         B.N       0x48
     0x4a: 0xe7fe         B.N       0x4a
     0x4c: 0xe7fe         B.N       0x4c
     0x4e: 0xe7fe         B.N       0x4e
     0x50: 0x0000         MOVS      R0, R0
     0x52: 0x0000         MOVS      R0, R0
     0x54: 0x0000         MOVS      R0, R0
     0x56: 0x0000         MOVS      R0, R0
     0x58: 0x0000         MOVS      R0, R0
     0x5a: 0x0000         MOVS      R0, R0
     0x5c: 0x0000         MOVS      R0, R0
     0x5e: 0x0000         MOVS      R0, R0

如果有人能解释发生了什么以及为什么程序在那时挂起,我将非常感激。

编辑:在下面添加了 C 代码

#include "NXP\iolpc4350.h"
#include "stdint.h"
#include "modules\i2c_drv.h"
#include "modules\drv_nvic.h"

#define IRC_FREQ       12000000
#define XTAL_FREQ      12000000

//nt32_t ClockFrequency;

uint32_t I2C0_PCLK;

unsigned char Data[2];

#define MULTF 15

#define PCA9502_ADDR  0x4D

volatile uint8_t flag0=0;

#define flTick               ( flag0 )
#define flTickSet()          ( flag0 = 0xFF )
#define flTickClear()        ( flag0 = 0x00 )

/*************************************************************************
 * Function Name: InitClock
 * Parameters: none
 *
 * Return: none
 *
 * Description: Initialize PLL and clock dividers. FCCO = 320MHz,
 *              PLL1_OUT = 160MHz
 *
 *************************************************************************/
void InitClock(void)
{
  /* 1. Init XTAL OSC */
  CGU_XTAL_OSC_CTRL_bit.HF = 0;       /* Xtal.freq is between 1MHz and 15MHZ */
  CGU_XTAL_OSC_CTRL_bit.BYPASS = 0;   /* Xtal.osc is connected */
  CGU_XTAL_OSC_CTRL_bit.ENABLE = 0;   /* Xtal.osc is enabled */

  /* 2.  Wait for OSC ready > 2ms */
  for(volatile uint32_t j = 20000; j; j--);

  /* 3. Switch to OSC clk */
  /* BASE_M4_CLK */
  CGU_BASE_M4_CLK = (1ul  << 11)      /* Autoblock during freq.change enabled */
                  | (6ul  << 24)      /* Source is XTAL osc. */
                    ;
  /* BASE_APB1_CLK */
  CGU_BASE_APB1_CLK = (1ul  << 11)    /* Autoblock during freq.change enabled */
                    | (6ul  << 24)    /* Source is XTAL osc. */
                    ;
  /* BASE_APB3_CLK */
  CGU_BASE_APB3_CLK = (1ul  << 11)    /* Autoblock during freq.change enabled */
                    | (6ul  << 24)    /* Source is XTAL osc. */
                    ;
  /* BASE_SPIFI_CLK */
  CGU_BASE_SPIFI_CLK = (1ul  << 11)   /* Autoblock during freq.change enabled */
                     | (6ul  << 24)   /* Source is XTAL osc. */
                    ;

  /* 4. Init PLL1 - In clk - OSC (12MHz)
     N = 3, M = 80, P = 1 VCO - 320MHz, PLL1 OUT - 160MHz */
  CGU_PLL1_CTRL_bit.PD = 1;           /* Power down PLL1 */
  CGU_PLL1_CTRL_bit.BYPASS = 0;       /* CCO clock sent to post-dividers */
  CGU_PLL1_CTRL_bit.DIRECT = 0;       /* Direct CCO output disabled */
  CGU_PLL1_CTRL_bit.FBSEL = 0;        /* CCO output as feedback divider */
  CGU_PLL1_CTRL_bit.PSEL = 1-1;       /* Post divider P = 1 */
  CGU_PLL1_CTRL_bit.NSEL = 3-1;       /* N = 3 */
  CGU_PLL1_CTRL_bit.MSEL = 80-1;      /* M = 80 */
  CGU_PLL1_CTRL_bit.CLK_SEL = 6;      /* Source is XTAL osc. */
  CGU_PLL1_CTRL_bit.AUTOBLOCK = 1;    /* Autoblock during freq.change enabled */

  /* 5. Enable PLL1 */
  CGU_PLL1_CTRL_bit.PD = 0;           /* Power up (enable) PLL1 */

  /* 5. Wait for the PLL1 to achieve lock */
  while(!CGU_PLL1_STAT_bit.LOCK);

  /* 6. Dividers */
  /* IDIVA - /4 input 160MHz, output 40MHz */
  CGU_IDIVA_CTRL_bit.AUTOBLOCK = 1;   /* Autoblock during freq.change enabled */
  CGU_IDIVA_CTRL_bit.IDIV = 4-1;      /* IDIV = 4 */
  CGU_IDIVA_CTRL_bit.CLK_SEL = 9;     /* Source is PLL1 */
  CGU_IDIVA_CTRL_bit.PD = 0;          /* Enable IDIVA */

  /* 7. Init Clock output stages */
  /* BASE_M4_CLK, APB0, APB2 - 160MHz */
  CGU_BASE_M4_CLK = (1ul  << 11)      /* Autoblock during freq.change enabled */
                  | (9ul  << 24)      /* Source is PLL1 */
                    ;
  /* BASE_APB1_CLK - 160MHz*/
  CGU_BASE_APB1_CLK = (1ul  << 11)    /* Autoblock during freq.change enabled */
                    | (9ul << 24)     /* Source is PLL1 */
                    ;
  /* BASE_SPIFI_CLK - 40MHz */
  CGU_BASE_SPIFI_CLK = (1ul  << 11)   /* Autoblock during freq.change enabled */
                     | (12ul << 24)   /* Source is IDIVA */
                    ;
  /* Enable M4 Bus clock */
  CCU1_CLK_M4_BUS_CFG_bit.RUN = 1;

  /* Enable APB 1 Bus clock */
  CCU1_CLK_APB1_BUS_CFG_bit.RUN = 1;

  /* Enable SCU clock */
  CCU1_CLK_M4_SCU_CFG_bit.RUN = 1;

  /* Set I2C0 module frequency = APB1 freq */
  I2C0_PCLK = 160000000;
}

/*************************************************************************
 * Function Name: RIT_IRQHandler
 * Parameters: none
 *
 * Return: none
 *
 * Description: Repetitive interrupt timer handler
 *
 *************************************************************************/
void RITIMER_IRQHandler(void)
{
    flTickSet();
    /* Clear interrupt */
    RIT_CTRL_bit.RITINT = 1;
    NVIC_ClearPendingIRQ(NVIC_RITIMER);
}

/*************************************************************************
 * Function Name: RIT_Init
 * Parameters: none
 *
 * Return: none
 *
 * Description: Initialization of repetitive interrupt timer
 *
 *************************************************************************/
void RITIMER_Init(void)
{
  /* Value for 0.25s timer interrupt @ 180MHz timer clock */
  RIT_COUNTER = 0;
  RIT_COMPVAL = 0x2AEA540;
  RIT_CTRL_bit.RITEN = 1;
  RIT_CTRL_bit.RITENCLR = 1;
  /* Enable interrupt */
  NVIC_EnableIRQ(NVIC_RITIMER);
  NVIC_SetPriority(NVIC_RITIMER, 16);
}

/*************************************************************************
 * Function Name: main
 * Parameters: none
 *
 * Return: none
 *
 * Description: main
 *
 *************************************************************************/
int main()
{
  // Configures Clock Generation Unit
  InitClock();
  // Force a RESET to Cortex-M0
  RGU_RESET_CTRL1 = ~RGU_RESET_ACTIVE_STATUS1 | RGU_RESET_CTRL1_M0APP_RST;
  // Configures Repetitve Interrupt Timer
  RITIMER_Init();
  // Configure the onboard LED - GPIO4.1
  GPIO_CLR4 = 1 << 1;
  GPIO_DIR4 |= 1 << 1;
  // Init I2C
  I2C_InitMaster(400000);

  // Everything below this line I have added in myself - Mitchell

  /* Configure PC_11 and PC_12 to serve as
     GPIO6[10] and GPIO6[11] to act as data select
     for SPP0_SSEL multiplexer

     1. Set as outputs
     2. Choose INTLCD_SSEL (option 0) as output by clearing both outputs
     3. Configure both pins as GPIO
  */

  // 1
  GPIO_DIR6 |= 0x0C;

  // 2
  GPIO_PIN6 &= ~0x0C;;

  // 3
  SCU_SFSPC_11_bit.MODE = 4;
  SCU_SFSPC_12_bit.MODE = 4;

  // Set LCD_RST to reset the LCD
  RGU_RESET_CTRL0 |= RGU_RESET_CTRL0_LCD_RST;
  // LCD_RST autoclears when complete
  // wait until this done before moving on
  while(RGU_RESET_STATUS1_bit.LCD_RST == 1);

  /* SPI slave select is an active low signal.
     This means that to communicate with the onboard LCD,
     SSP0_SSEL must be cleared
  */


  while(1)
  {

  }
}
4

3 回答 3

6

在 Cortex-M3 中,最低地址不是代码,而是向量表。例如,0 处的入口是 的重置值SP,4 处的入口是重置PC,以下入口是各种例外。如果我们将转储重新解释为数据,我们会得到以下信息:

00 DCD 0x10089FF0
04 DCD 0x10402BAD
08 DCD 0x10400041
0C DCD 0x10400043
10 DCD 0x10400045
14 DCD 0x10400047
18 DCD 0x10400049
1C DCD 0
20 DCD 0
24 DCD 0
28 DCD 0
2C DCD 0x1040004B
30 DCD 0x1040004D
34 DCD 0
38 DCD 0x1040004F
3C DCD 0x10401645

很明显,代码已链接到从 10400000 开始运行。如果我们考虑到这一点,并将整数转换为偏移量,我们会得到:

00  DCD 0x10089FF0          ; Initial SP
04  DCD 0x10402BAD          ; reset PC
08  DCD loc_10400040+1      ; NMI handler
0C  DCD loc_10400042+1      ; Hard Fault handler
10  DCD loc_10400044+1      ; MPU Fault Handler
14  DCD loc_10400046+1      ; Bus Fault Handler
18  DCD loc_10400048+1      ; Usage Fault Handler
1C  DCD 0
20  DCD 0
24  DCD 0
28  DCD 0
2C  DCD loc_1040004A+1      ; SVCall Handler
30  DCD loc_1040004C+1      ; Debug Monitor Handler
34  DCD 0
38  DCD loc_1040004E+1      ; PendSV Handler
3C  DCD 0x10401645          ; SysTick Handler

40 loc_10400040
40   B loc_10400040

(偏移量为 +1,因为 Cortex-M3 上的代码指针必须设置位 0,以指示目标是 Thumb 代码。)

loc_10400040对应于你的B.N 0x40反汇编。因此,显然,您最终进入了 NMI 处理程序。

查看 LPC18xx 用户手册,似乎 NMI 只能由引脚P4_0PE_4. 我建议仔细检查您的电路板原理图和/或 GPIO 配置代码。

于 2013-07-29T10:51:38.393 回答
0
  • 首先,您应该检查以确保所有优化都已关闭(查看项目选项)。如果您对优化的作用感到好奇,请在关闭它们后一次引入它们,并观察程序集如何变化。

  • 那些 MOVS 指令似乎充当了基本上提供执行延迟的 NOP。由于编译器优化,这些可能会替换一个或多个 while 循环。
    • 内联延迟指令更优化,如果编译器确定延迟可以预先确定,有时会替换循环条件分支(while 循环)。

  • 正如评论中提到的,BN 指令提供了无限循环。实际上,您的代码中至少有一个无限循环,在 main.js 的末尾。
于 2013-08-14T14:03:13.020 回答
0

我在使用汇编和 c 编写 uart 库时遇到了相同类型的问题。我的代码中的问题是我启用了一些必须在经过几次配置后才启用的位。就像在配置 pll 寄存器之前启用 PLLON 给了我这个问题

于 2021-07-01T12:12:27.237 回答