搜索
bottom↓
回复: 24

Keil SWD 调试疑问 绝对难 高手进 :)

[复制链接]

出0入0汤圆

发表于 2013-12-19 09:12:27 | 显示全部楼层 |阅读模式
本帖最后由 yanjiesh 于 2013-12-19 09:44 编辑

如下述是代码的一部分,在开启最后一个函数前的调试和运行都正常,一旦打开这个函数,就无反应了。
尝试使用Jlink-v7的SW调试,在代码的最初几句设了断点,但是运行起来,界面上一点反应都没有。 请大家提问题。


#include "LPC17xx.h"
#include "type.h"
#include "target.h"
#include "nvic.h"
#include "systick.h"
#include "cortexm3_macro.h"
#include "systick.h"
#include "timer.h"
#include "uart.h"

#include "LPC1766i2C.h"
#include "Si2178I2C.h"
#include "atbm887x.h"



int main (void)
{
//  uint32_t data, true_data, i;
        uint8_t times = 10 ;
        uint8_t tmp = 0 ;
        uint8_t i;

  TargetResetInit();

  NVIC_DeInit();
  NVIC_SCBDeInit();

#if __IRAM
  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif

  /* Configure the NVIC Preemption Priority Bits */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  
  SysTick_Config(100000000UL/1000 - 1);

  UARTInit(0, 115200);
  // UART0 TESTing
  while (times>=1)
          {
                  UART0SendByte(64);
                times--;
                printf("hello\r\n");
          };
   
   if (InitialTimer( 0 , 50000 )) // interval is 1ms.
   { EnableTimer (0)  ; printf(" Timer 0 is enabled.\r\n");}
   else printf (" Timer 0 not initialized.\r\n");

  // Four Leds are connected to P2.2 ~ P2.5
  // Set P2.2 ~ 2.5 to GPIO functions.
           
         //PINSEL4 &= (~(0x3c));
           //PINMODE4 &= (0x00000550);
         //PINMODE4 |= (0x00000550);
     FIO2DIR0 |= 0x3c ;
        // FIO2MASK0 &= (~(0x3c));


  
  // 初始化I2C接口/* initialize I2c
        I2CInit((unsigned int)I2CMASTER );       
        printf("I2C2 is initialized .\r\n");
    putch(64);
        putch(13);
        putch(10);
        puts("hello!");
       

    // GPIO and Timer testing:
   
               
                for ( i=2;i<=5;i++)
                        {
                                FIO2SET0 |= 0x1<<i ;
                                //FIO2PIN |= 0x3c;

                                  System_wait(50);

                                puts("I set");

                                FIO2CLR0 |= 0x1<<i ;
                                //FIO2PIN  &= (~(0x3c));

                                System_wait(50);

                                puts (" and then I reset.\r \n");

                                if (i == 5) i = 1;
                        };

         
   

         


        //The next function is to initialize demodulator after STB power up.
        //It MUST BE the first function to call before any other operation on the demodulator.
        ATBMPowerOnInit();  ————最后一个函数一旦开启,前面的代码均不能正常作用了。

出0入0汤圆

 楼主| 发表于 2013-12-19 09:19:58 | 显示全部楼层
查了一下  在Disassambly窗口里 停在如下注释的位置 :
                 _sys_open:
0x00000F78 B50E      PUSH     {r1-r3,lr}
0x00000F7A E9CD0100  STRD     r0,r1,[sp,#0]
0x00000F7E F000FCAF  BL.W     strlen (0x000018E0)
0x00000F82 9002      STR      r0,[sp,#0x08]
0x00000F84 4669      MOV      r1,sp
0x00000F86 2001      MOVS     r0,#0x01
0x00000F88 BEAB      BKPT     0xAB
0x00000F8A BD0E      POP      {r1-r3,pc}
                 _sys_close:

请高手支招 :)  谢谢

出0入0汤圆

发表于 2013-12-19 11:45:58 | 显示全部楼层
楼主, 你能描述一下你的最后一个函数功能是什么吗? 另外,在调试的时候要注意关闭看门狗, 否则会导致出错.

出0入0汤圆

 楼主| 发表于 2013-12-20 09:16:15 | 显示全部楼层
wkong501 发表于 2013-12-19 11:45
楼主, 你能描述一下你的最后一个函数功能是什么吗? 另外,在调试的时候要注意关闭看门狗, 否则会导致出错. ...

谢谢支持!最后一个函数是用I2C 来访问一个芯片索取信息。另外,我没有开启看门狗。

主要疑问是,为何开启该函数后,前面原先正常表现的UART、GPIO突然都没有了输出,而且这些输出是安排在最后一个函数之前的。

我在思考,是否和芯片的冯诺依曼或哈佛架构有关呢?

出0入22汤圆

发表于 2013-12-20 09:30:45 | 显示全部楼层
那个函数是你写的吗,可能是封掉swd调试口了

出0入0汤圆

 楼主| 发表于 2013-12-20 10:47:40 | 显示全部楼层
jiaowoxiaolu 发表于 2013-12-20 09:30
那个函数是你写的吗,可能是封掉swd调试口了

谢谢 Jiaowoxiaolu , 的确如你预计,这个函数不是我写的 ,是我移植过来的,主要涉及I2C2口与另个芯片的读写通信。

但是我设计使用了I2C2 的中断服务, 我参考其他朋友提供LPC1114的I2C中断服务样板,修改了移植了下。

我的困惑是,在函数之前的代码运行为何受到后面的代码的约束?

出0入0汤圆

发表于 2013-12-20 10:51:07 | 显示全部楼层
不仿真的时候能正常运行么?

出0入0汤圆

 楼主| 发表于 2013-12-20 11:03:29 | 显示全部楼层
linyu0395 发表于 2013-12-20 10:51
不仿真的时候能正常运行么?

谢谢 linyu0395 , 不仿真时,输出就不正常,所以,所以 ,才用仿真哦

出0入0汤圆

发表于 2013-12-20 11:04:03 | 显示全部楼层
楼主include一下<stdio.h>试试,有可能是你那个函数里用到了标准库里面的东西,又没有包含头文件,编译器就包含了标准的C库,然后在初始化库需要的东西的时候,就卡住了。

出0入25汤圆

发表于 2013-12-20 11:16:12 | 显示全部楼层
项目配置中选中Use MicroLib试试

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2013-12-20 11:53:40 | 显示全部楼层
XIVN1987 发表于 2013-12-20 11:16
项目配置中选中Use MicroLib试试

谢谢 XIVN1987 ,这个选项我试过,选了的话,Printf会出错,所以我关了。谢谢。

出0入0汤圆

 楼主| 发表于 2013-12-20 14:57:28 | 显示全部楼层
primula 发表于 2013-12-20 11:04
楼主include一下试试,有可能是你那个函数里用到了标准库里面的东西,又没有包含头文件,编译器就包含了标 ...

谢谢 Primula 的支持,试过了,未能出现转机,出现多种编译错误。

出0入0汤圆

发表于 2013-12-20 15:17:59 | 显示全部楼层
yanjiesh 发表于 2013-12-20 14:57
谢谢 Primula 的支持,试过了,未能出现转机,出现多种编译错误。

楼主,我觉得可能就跟标准C库有关系了,因为正常的话,包含stdio.h后应该不会编译出错的,可能就是在那个函数里定义了什么东西,导致编译的时候加载了不一样的C库,如果包含stdio.h又会引起冲突。
从那个汇编停留的位置来看,代码段是很靠前的,在main函数前执行的代码,除了那个reset向量,就是标准C库里的__main了,用户的main是被标准C库的__main调用的。
依次推测的话,我觉得应该是哪个代码定义的什么东西编译了另一个C库,在那个C库里__main又因为某种情况无法继续执行,才能导致编译后面的代码,影响了前面的代码无法执行,甚至main函数都进不到。

出0入0汤圆

发表于 2013-12-20 15:18:52 | 显示全部楼层
楼主方便把那里面的代码贴出来看看吗。

出0入0汤圆

发表于 2013-12-20 15:23:57 | 显示全部楼层
10楼给答案,我来赚莫元!

出0入0汤圆

 楼主| 发表于 2013-12-20 19:10:13 | 显示全部楼层
primula 发表于 2013-12-20 15:18
楼主方便把那里面的代码贴出来看看吗。

谢谢 primula 朋友,以下是代码,等待大家帮助,周末愉快!

        int ATBMPowerOnInit()
        {
                int power_on_status = 0;
                uint8_t ui8pll ;//reset_status;
       
                uint8_t ui8ChipID;
       
                stCustomConfig.stTunerConfig.ui8IQmode                        = SWAP_IQ ;
                stCustomConfig.stTunerConfig.ui8DTMBBandwithMHz         = 8; //unit: MHz
                stCustomConfig.stTunerConfig.ui32IFFrequency                = 5; //
       
                //demod config
                stCustomConfig.stTsMode.ui8TSTransferType                        = TS_PARALLEL_MODE;   
                stCustomConfig.stTsMode.ui8OutputEdge                        = TS_OUTPUT_FALLING_EDGE;         
                stCustomConfig.stTsMode.ui8SPIClockConstantOutput        = TS_CLOCK_VALID_OUTPUT;
                stCustomConfig.stTsMode.ui8TSSPIMSBSelection                = TS_SPI_MSB_ON_DATA_BIT7;
                stCustomConfig.stTsMode.ui8TSSSIOutputSelection         = TS_SSI_OUTPUT_ON_DATA_BIT0;
                stCustomConfig.ui8CrystalOrOscillator                                = OSCILLATOR;
                stCustomConfig.ui32SampleClkFrequency                                 = 24; //
       
                //dvbc config
                stCustomConfig.stDvbcParams.i32SymbolRate                        = 6875;//
                stCustomConfig.stDvbcParams.ui8InputMode                        = DVBC_IF_INPUT;
       
                ui8ChipID = ATBMChipID();                                                                        //       
                if(ui8ChipID == 0x40)
                {
                        ATBMWrite(0x01, 0x0c, 0x00);
                        ATBMWrite(0x06, 0x06, 0x00);
                        ATBMWrite(0x01, 0x03, 0x00);
                        ATBMRead(0x06, 0x0e, &ui8pll);
                        ATBMWrite(0x06, 0x04, 0x01);
                        ui8pll |= 0x01;
                        ATBMWrite(0x06, 0x0e,ui8pll);       
                        ui8pll &= 0xfe;
                        ATBMWrite(0x06, 0x0e,ui8pll);
                        ATBMWrite(0x06, 0x04, 0x00);
                }
                //else if(ui8ChipID == 0x30)
                //{
                //        reset_status = ATBMReset(stCustomConfig.ui8CrystalOrOscillator); //Check hardware state
                //        if(reset_status ==0)
                //        {
                //                printf("please check Crystal or oscillator setting\n");                
                //        }
                //        ATBMWrite(0x06, 0x06, 0x00);
                //        ATBMWrite(0x01, 0x03, 0x00);
                //}
                else
                {
                        printf("power on init failed, chip not correctly detected\n");
                }
                System_wait(1);/*1 ms*/
                return power_on_status;
        }

其中 ATBMRead和ATBMWrite是I2C读写函数。

出0入0汤圆

发表于 2013-12-20 19:37:48 | 显示全部楼层
I2C的功率控制位打开了吗?如果没打开相应的功率控制位,会出错。

出0入0汤圆

发表于 2013-12-20 22:24:48 | 显示全部楼层
本帖最后由 dr2001 于 2013-12-20 22:32 编辑
yanjiesh 发表于 2013-12-19 09:19
查了一下  在Disassambly窗口里 停在如下注释的位置 :
                 _sys_open:
0x00000F78 B50E      ...


考虑以下问题:
1、你的工程使用操作系统了没有?(完整的操作系统,一般来说指支持Posix的OS,有完整文件系统支持,etc)
2、如果工程没有使用操作系统,那么,你裁剪C运行库了没有?
如果以上两件事情的答案都是否,查看CallStack,看是哪些函数导致调用了_sys_open/_sys_close这样的函数。

这里,你就不觉得直接编译出来的代码里,带Break这样的指令不对头么?呵呵,正常的指令序列带陷阱指令,除非你自己有明确的目的,否则,想想都有问题么。

按照RVCT的典型配置,BKPT  0xAB应该是SemiHosting的主机访问向量。而且给R0 0x1似乎还就是sys_open。这对于裸奔的系统来说,不正常。
SemiHosting可以打开主机上的文件(包含stdin/stdout)加以访问;如果用了SemiHosting,不带仿真器会挂;必须带着仿真器才能正常跑。

裸奔的时候,C运行库不是所有的函数都能用。先考虑清楚,哪些东西需要底层操作系统/驱动程序来提供,如果你的运行环境没有这些支持,调用这些函数就是危险的。

printf在标准C库里必须ReTarget IO才能用,否则就是SemiHosting的。看到你用到了printf,这个是怎么输出数据的?输出到哪里了?按这个逻辑想想看?

另外,标题起的实在不好说啥。。。

出0入0汤圆

 楼主| 发表于 2013-12-23 09:15:02 | 显示全部楼层
WindDragon 发表于 2013-12-20 19:37
I2C的功率控制位打开了吗?如果没打开相应的功率控制位,会出错。

谢谢 WindDragon , 我在I2Cinit()中开始的地方加了一句—— PCONP |= 0x04000000; // set the I2C interface 2 power/clock control bit= 0x04000000.,我想是打开了吧。

不过,我是第一次玩LPC1766的i2c,你看这句话有问题吗?

出0入0汤圆

 楼主| 发表于 2013-12-23 09:25:18 | 显示全部楼层
dr2001 发表于 2013-12-20 22:24
考虑以下问题:
1、你的工程使用操作系统了没有?(完整的操作系统,一般来说指支持Posix的OS,有完整文 ...

谢谢dr2001朋友的意见,我的标题实在说明了菜鸟和高手的差别,贻笑大方了 哈哈

考虑以下问题:
1、你的工程使用操作系统了没有?(完整的操作系统,一般来说指支持Posix的OS,有完整文件系统支持,etc)
我的工程没有使用操作系统。
2、如果工程没有使用操作系统,那么,你裁剪C运行库了没有?
同上,没有剪裁C运行库。
如果以上两件事情的答案都是否,查看CallStack,看是哪些函数导致调用了_sys_open/_sys_close这样的函数。
开始学习分析Startup.s文件,以前就是copy到工程中使用来着,根据后面你提供的信息,好像和启动文件的内的CalStack有关,也和配置的调试方法有关。于是,我查了下网上的资料,正在学习ARM的启动过程,我想Cortex的启动过程应该是一样的吧?
这里,你就不觉得直接编译出来的代码里,带Break这样的指令不对头么?呵呵,正常的指令序列带陷阱指令,除非你自己有明确的目的,否则,想想都有问题么。

按照RVCT的典型配置,BKPT  0xAB应该是SemiHosting的主机访问向量。而且给R0 0x1似乎还就是sys_open。这对于裸奔的系统来说,不正常。
SemiHosting可以打开主机上的文件(包含stdin/stdout)加以访问;如果用了SemiHosting,不带仿真器会挂;必须带着仿真器才能正常跑。

裸奔的时候,C运行库不是所有的函数都能用。先考虑清楚,哪些东西需要底层操作系统/驱动程序来提供,如果你的运行环境没有这些支持,调用这些函数就是危险的。

printf在标准C库里必须ReTarget IO才能用,否则就是SemiHosting的。看到你用到了printf,这个是怎么输出数据的?输出到哪里了?按这个逻辑想想看?

另外,标题起的实在不好说啥。。。

出0入0汤圆

发表于 2013-12-23 11:58:22 | 显示全部楼层
本帖最后由 dr2001 于 2013-12-23 12:00 编辑
yanjiesh 发表于 2013-12-23 09:25
谢谢dr2001朋友的意见,我的标题实在说明了菜鸟和高手的差别,贻笑大方了 哈哈  

考虑以下问题 ...


很有可能是SemiHosting带来的问题,由于没有代码细节,无法严格确认。

简单说,没有重定向Printf的输出接口的话,printf的信息输出到哪里?有OS或者相关的支持,才会有stdout作为默认输出的,裸奔是没有的。无论是SWV的ITM输出,还是串口,都是需要代码去实现相关功能的。

这点,对MDK来说,默认情况下,输出操作会用调用异常,然后让仿真器来处理后续的信息,有主机参与的处理,就是SemiHosting。所以,用到IO之类的操作时,需要重定向IO并且进行必要的处理,否则C标准库是不好用的。

重定向IO大约需要实现以下:

  1. #include    "stdio.h"

  2. #pragma import(__use_no_semihosting_swi)

  3. struct  __FILE {
  4.     char    rev;
  5. };

  6. struct __FILE        __stdout;

  7. int
  8. fputc(int ch, FILE * fp)
  9. {
  10.     if(ch == '\n') {
  11.     }
  12.     return ch;
  13. }

  14. int
  15. ferror(FILE * fp)
  16. {
  17.     return  EOF;
  18. }

  19. struct __FILE        __stdin;

  20. int
  21. fgetc(FILE * fp)
  22. {
  23.     char    ch = 0;
  24.     return  ch;
  25. }

  26. void
  27. __backspace(FILE * fp)
  28. {
  29. }
复制代码


MDK的库帮助手册里有,可以看看。

如果不用scanf之类的,只要输出fputc就行了。要有scanf,需要实现getc和退格。
注意FILE *是谁,只有__stdin和__stdout是标准IO。可以自己扩展的。

希望能解决你的问题。

出0入0汤圆

发表于 2013-12-23 11:59:51 | 显示全部楼层
帮顶  哈哈哈哈和哈哈哈哈

出0入0汤圆

 楼主| 发表于 2013-12-23 13:18:17 | 显示全部楼层
dr2001 发表于 2013-12-23 11:58
很有可能是SemiHosting带来的问题,由于没有代码细节,无法严格确认。

简单说,没有重定向Printf的输出 ...

谢谢 dr2001 , 还在学习ARM启动的资料。这里 先贴一下 本工程里 Printf的实现手法。 以供大家一起分析学习。


/*****************************************************************************
** Function name:                printf
**
** Descriptions:                实现print功能函数
** parameters:                        *fmt, ...
** Returned value:                None
**
*****************************************************************************/
int vsprintf(char * /*s*/, const char * /*format*/, va_list /*arg*/);
       
void printf(char *fmt, ...)
{
        va_list ap;
        char string[256];         
       
        va_start(ap, fmt);
        vsprintf(string, fmt, ap);
       
        UART0Send(string);
        va_end(ap);
}

出0入0汤圆

 楼主| 发表于 2013-12-23 13:20:30 | 显示全部楼层
四轴飞行器 发表于 2013-12-23 11:59
帮顶  哈哈哈哈和哈哈哈哈

谢谢 四轴飞行器 朋友 ! 有机会 向你学习 四轴飞行器 技术哦,

出0入0汤圆

发表于 2013-12-23 13:26:37 | 显示全部楼层
yanjiesh 发表于 2013-12-23 13:18
谢谢 dr2001 , 还在学习ARM启动的资料。这里 先贴一下 本工程里 Printf的实现手法。 以供大家一起分析学 ...

只要
#pragma import(__use_no_semihosting_swi)
就能屏蔽SemiHosting。

然后再试试看吧。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-20 09:49

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表