分享

SWD调试在STM32中REMAP调试的深入探究

 rookie 2019-08-14
首先说一下问题的现象,如果有这种现象的同学可以看看博主的这篇博文
程序download一次后,第二次download就提示no target connect,除非长按reset键才能继续下载程序

首先上一组stm32TIM2的端口使用组合有下面四种:

1.当不重映射时,默认TIM2四个的IO口是PA0、PA1、PA2、PA3

开启重映射__HAL_AFIO_REMAP_TIM2_ENABLE()

2.要使用PA15、PB3、PA2、PA3的端口组合,要调用下面的语句进行部分重映射:

__HAL_AFIO_REMAP_TIM2_PARTIAL_1()

3.要使用PA0、PA1、PB10、PB11的端口组合,要调用下面的语句进行部分重映射:

__HAL_AFIO_REMAP_TIM2_PARTIAL_2()

4.要使用PA15、PB3、PB10、PB11的端口组合,要调用下面的语句进行完全重映射:

__HAL_AFIO_REMAP_TIM2_ENABLE()

同时还要禁用JTAG功能,PA15、PB3、PB10、PB11才会正常输出。

那么使用了重映射之后会导致一个问题,程序download一次后,第二次download就提示no target connect,除非长按reset键才能继续下载程序。

该问题讨论可在此问答中找到答案

从该帖子找到的精辟回答如下

The problem is that the STM32F1 series has one register AFIO_MAPR which contains thesettings for remapping various peripherals and for enabling/disabling the JTAG/SWD connectionto your debugger. And to makethis more complicated, the bits in that register which enable/disable theJTAG/SWD settings (bits 24-26) arewrite-only so their existing state cannot be read.

See this extract from the STM32F1Reference Manual:

This means that any attempt to change the settings of thevarious "peripheral remap" bits, by doing a read-modify-writesequence to this register, could read differentvalues instead of the real current valuesin the JTAG/SWD bits. Then, when the write to the register is done, your debugger access stopsbecause whatever was read from those JTAG/SWD bits, is written back to them.(Other effects have also been reported, but I won't go into that now).

From what I could find without installing the HAL, the macrosused are:

#define __HAL_AFIO_REMAP_TIM1_ENABLE()
MODIFY_REG(AFIO->MAPR, AFIO_MAPR_TIM1_REMAP, AFIO_MAPR_TIM1_REMAP_FULLREMAP)

and MODIFY_REG is:

#define MODIFY_REG(REG, CLEARMASK, SETMASK)
WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))

So as you see, MODIFY_REG isdoing a read-modify-write and you don't know what values it will read fromJTAG/SWD bits 24-26 andhence what values it will write back to there! The values read from those bitsare "undefined" (to quote ST) and I know I have read different valuesfrom the same STM32F1 at different times.

The "fix" I have used with the SPL, is to change anyremapping code to specifically set the JTAG/SWD bits which you want, wheneveryou write to the AFIO_MAPRregister. You will need to figure out how you want to do the same with the HALcode. One way is to use a temporary variable so, from memory, the sequencebecomes:

·        Read AFIO_MAPR register intotemp variable

·        Change desired peripheralremap bits in the temp variable

·        Mask out bits 24-26 in thetemp variable

·        Set bits 24-26 in the tempvariable to whatever I wanted (therefore ignoring whatever their, likelyincorrect, "read" value was)

·        Write temp variable toAFIO_MAPR


基本上导致这个问题的原因在于SWJ_CFG[2]位是Write Only的
__HAL_AFIO_REMAP_I2C1_ENABLE()中会执行类似reg |= xxx_enable的操作
该操作会读寄存器,然后或上某个使能位
然而由于SWJ_CFG[2]位的Write Only特性,导致寄存器读出来后不是实际的值

解决方法:在使用了引脚复用的宏之后需要调用一次__HAL_AFIO_REMAP_SWJ_NOJTAG(),该宏的解释如下:

/**

 * @brief Enable the Serial wire JTAG configuration

 * @note  NOJTAG: JTAG-DP Disabledand SW-DP Enabled

 * @retval None

 */

#define__HAL_AFIO_REMAP_SWJ_NOJTAG()   do{CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_SWJ_CFG);           \

                                           SET_BIT(AFIO->MAPR, AFIO_MAPR_SWJ_CFG_JTAGDISABLE); \

                                         }while(0U)

我们追一下CLEAR_BIT(AFIO->MAPR,AFIO_MAPR_SWJ_CFG); 

可以发现#defineCLEAR_BIT(REG, BIT)   ((REG) &=~(BIT))

继续追该宏使用的参数AFIO->MAPR,AFIO_MAPR_SWJ_CFG,其中MAPR为复用寄存器,而AFIO_MAPR_SWJ_CFG追到最后为0x07000000(过程比较多,就不赘述了),再通过&= ~(BIT)操作,得出&=~(0111000000000000000000000000)

最后结果为&=11111000111111111111111111111111

这个时候可以看出来在CLEAR_BIT(AFIO->MAPR,AFIO_MAPR_SWJ_CFG);宏的作用是使得MAPR寄存器的Bits 26:24重置为0

这个时候博主把MAPR寄存器放出来

可以发现是重新复位了SWJ,也就是重置了JTAG位的功能。

 

 

接下来我们再看SET_BIT(AFIO->MAPR,AFIO_MAPR_SWJ_CFG_JTAGDISABLE);

功能函数#defineSET_BIT(REG, BIT)     ((REG) |= (BIT))

直接追AFIO_MAPR_SWJ_CFG_JTAGDISABLE,最后得出该值是0x02000000

所以该值操作为|=02000000,即|=00000 010 000000000000000000000000

重新看该值010在寄存器的作用,可以发现现在使能了SWD的调试功能了。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约