always-2029922 发表于 2019-1-2 22:39:33

swd 4线模式下载异常求解(Error: Flash Download failed - Cortex-M3)

在项目中使用使用stm32f103vc6芯片,并用swd接口4线下载,分别是vcc、gnd、swdio、swclk,也就是没有reset引脚。现出现问题为:出场芯片可以使用mdk正常下载一次,复位或断电后再次下载即出现异常失败,只能通过按下复位按键才能下载,报告错误如下:
----------------------------——————————————————
JLink info:
------------
DLL: V6.30h, compiled Mar 16 2018 18:02:51
Firmware: J-Link V9 compiled Apr 20 2018 16:47:26
Hardware: V9.20
S/N : 89802975
Feature(s) : GDB, RDI, FlashBP, FlashDL, JFlash

* JLink Info: Found SW-DP with ID 0x1BA01477
* JLink Info: SWD speed too high. Reduced from 12000 kHz to 8100 kHz for stability
* JLink Info: Found SW-DP with ID 0x1BA01477
* JLink Info: Scanning AP map to find all available APs
* JLink Info: AP: Stopped AP scan as end of AP map has been reached
* JLink Info: AP: AHB-AP (IDR: 0x14770011)
* JLink Info: Iterating through AP map to find AHB-AP to use
* JLink Info: AP: Core found
* JLink Info: AP: AHB-AP ROM base: 0xE00FF000
* JLink Info: CPUID register: 0x411FC231. Implementer code: 0x41 (ARM)
* JLink Info: Found Cortex-M3 r1p1, Little endian.
* JLink Info: FPUnit: 6 code (BP) slots and 2 literal slots
* JLink Info: CoreSight components:
* JLink Info: ROMTbl @ E00FF000
* JLink Info: ROMTbl: E000E000, CID: B105E00D, PID: 001BB000 SCS
* JLink Info: ROMTbl: E0001000, CID: B105E00D, PID: 001BB002 DWT
* JLink Info: ROMTbl: E0002000, CID: B105E00D, PID: 000BB003 FPB
* JLink Info: ROMTbl: E0000000, CID: B105E00D, PID: 001BB001 ITM
* JLink Info: ROMTbl: E0040000, CID: B105900D, PID: 001BB923 TPIU-Lite
* JLink Info: ROMTbl: E0041000, CID: B105900D, PID: 101BB924 ETM-M3
ROMTableAddr = 0xE00FF000
* JLink Info: Reset: Halt core after reset via DEMCR.VC_CORERESET.
* JLink Info: Reset: Reset device via AIRCR.SYSRESETREQ.
* JLink Info: Reset: CPU may have not been reset (DHCSR.S_RESET_ST never gets set).
* JLink Info: Reset: Using fallback: Reset pin.
* JLink Info: Reset: Halt core after reset via DEMCR.VC_CORERESET.
* JLink Info: Reset: Reset device via reset pin

Target info:
------------
Device: STM32F103VC
VTarget = 3.300V
State of Pins:
TCK: 0, TDI: 0, TDO: 0, TMS: 1, TRES: 1, TRST: 0
Hardware-Breakpoints: 6
Software-Breakpoints: 8192
Watchpoints:          4
JTAG speed: 6000 kHz

Erase Done.
Programming Failed!
Error: Flash Download failed-"Cortex-M3"
Flash Load finished at 18:51:12

----------------------------——————————————————
根据信息可以判断出芯片已经复位,并且擦除了flash,但是下载失败,不知道在“ Programming”这一步因何原因失败。
已经查找到的解决方法有以下:
1.将mdk的debug的reset设置为软件触发模式
2.修改匹配的flash配置文件
3.检查swd引脚是否复用
将以上内容均有试验,但未能解决问题。

下面是我的配置:
boot1悬空,boot0拉下接地。,swd相关原理图如下:



在keil仿真设置了swd模式,并且配置了芯片对应的flash型号,如下图:

(图二未显示仿真器原因为本人在家使用远程访问工作pc,仿真器已经拔出)
代码里面设置了__HAL_AFIO_REMAP_SWJ_NOJTAG();启用swd两线模式,同时屏蔽了应用代码,仅执行初始化配置,如下:
HAL_StatusTypeDef HAL_Init(void)
{
/* Configure Flash prefetch */
#if (PREFETCH_ENABLE != 0)
#if defined(STM32F101x6) || defined(STM32F101xB) || defined(STM32F101xE) || defined(STM32F101xG) || \
    defined(STM32F102x6) || defined(STM32F102xB) || \
    defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || \
    defined(STM32F105xC) || defined(STM32F107xC)

/* Prefetch buffer is not available on value line devices */
__HAL_FLASH_PREFETCH_BUFFER_ENABLE();
#endif
#endif /* PREFETCH_ENABLE */

/* Set Interrupt Group Priority */
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);

/* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */
HAL_InitTick(TICK_INT_PRIORITY);

/* Init the low level hardware */
HAL_MspInit();

/* Return function status */
return HAL_OK;
}
在HAL_MspInit();中调用__HAL_AFIO_REMAP_SWJ_NONJTRST();配置了swd仅使用swdio和swclk,如下:void HAL_MspInit(void)
{
/* USER CODE BEGIN MspInit 0 */

/* USER CODE END MspInit 0 */

__HAL_RCC_AFIO_CLK_ENABLE();

HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);

/* System interrupt init*/
/* MemoryManagement_IRQn interrupt configuration */
HAL_NVIC_SetPriority(MemoryManagement_IRQn, 0, 0);
/* BusFault_IRQn interrupt configuration */
HAL_NVIC_SetPriority(BusFault_IRQn, 0, 0);
/* UsageFault_IRQn interrupt configuration */
HAL_NVIC_SetPriority(UsageFault_IRQn, 0, 0);
/* SVCall_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SVCall_IRQn, 0, 0);
/* DebugMonitor_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DebugMonitor_IRQn, 0, 0);
/* PendSV_IRQn interrupt configuration */
HAL_NVIC_SetPriority(PendSV_IRQn, 15, 0);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 15, 0);

    /**DISABLE: JTAG-DP Disabled and SW-DP Disabled
    */
//__HAL_AFIO_REMAP_SWJ_DISABLE();*/
//__HAL_AFIO_REMAP_SWJ_NOJTAG();
      __HAL_AFIO_REMAP_SWJ_NONJTRST();

/* USER CODE BEGIN MspInit 1 */

/* USER CODE END MspInit 1 */
}然后初始化系统时钟,如下
int SystemClock_Config(void)
{

RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;

    /**Initializes the CPU, AHB and APB busses clocks
    */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
      DEV_PRO_DGB_ERROR("rcc config error\n");
}

    /**Initializes the CPU, AHB and APB busses clocks
    */
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
    DEV_PRO_DGB_ERROR("rcc config error\n");
}

    /**Configure the Systick interrupt time
    */
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

    /**Configure the Systick
    */
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 15, 0);

return 0;
}代码仅运行了以上部分,个人认为可以排除swd的io复用,依然下载异常。

同时在排查过程中发现,若屏蔽代码HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) ,更新程序后,复位或掉电后,再次运行则可正常下载。但HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) 仅为时钟初始化,不知为何影响swd。代码如下:
HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef*RCC_ClkInitStruct, uint32_t FLatency)
{
uint32_t tickstart = 0U;

/* Check the parameters */
assert_param(RCC_ClkInitStruct != NULL);
assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
assert_param(IS_FLASH_LATENCY(FLatency));

/* To correctly read data from FLASH memory, the number of wait states (LATENCY)
must be correctly programmed according to the frequency of the CPU clock
    (HCLK) of the device. */

#if defined(FLASH_ACR_LATENCY)
/* Increasing the number of wait states because of higher CPU frequency */
if(FLatency > (FLASH->ACR & FLASH_ACR_LATENCY))
{   
    /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
    __HAL_FLASH_SET_LATENCY(FLatency);
   
    /* Check that the new number of wait states is taken into account to access the Flash
    memory by reading the FLASH_ACR register */
    if((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency)
    {
      return HAL_ERROR;
    }
}

#endif /* FLASH_ACR_LATENCY */
/*-------------------------- HCLK Configuration --------------------------*/
if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
{
    assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
    MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
}

/*------------------------- SYSCLK Configuration ---------------------------*/
if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
{   
    assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
   
    /* HSE is selected as System Clock Source */
    if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
    {
      /* Check the HSE ready flag */
      if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
      {
      return HAL_ERROR;
      }
    }
    /* PLL is selected as System Clock Source */
    else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
    {
      /* Check the PLL ready flag */
      if(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
      {
      return HAL_ERROR;
      }
    }
    /* HSI is selected as System Clock Source */
    else
    {
      /* Check the HSI ready flag */
      if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)
      {
      return HAL_ERROR;
      }
    }
    __HAL_RCC_SYSCLK_CONFIG(RCC_ClkInitStruct->SYSCLKSource);

    /* Get Start Tick */
    tickstart = HAL_GetTick();
   
    if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
    {
      while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSE)
      {
      if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE)
      {
          return HAL_TIMEOUT;
      }
      }
    }
    else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
    {
      while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
      {
      if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE)
      {
          return HAL_TIMEOUT;
      }
      }
    }
    else
    {
      while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSI)
      {
      if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE)
      {
          return HAL_TIMEOUT;
      }
      }
    }      
}   
#if defined(FLASH_ACR_LATENCY)
/* Decreasing the number of wait states because of lower CPU frequency */
if(FLatency < (FLASH->ACR & FLASH_ACR_LATENCY))
{   
    /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
    __HAL_FLASH_SET_LATENCY(FLatency);
   
    /* Check that the new number of wait states is taken into account to access the Flash
    memory by reading the FLASH_ACR register */
    if((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency)
    {
      return HAL_ERROR;
    }
}   
#endif /* FLASH_ACR_LATENCY */

/*-------------------------- PCLK1 Configuration ---------------------------*/
if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
{
    assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider));
    MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_ClkInitStruct->APB1CLKDivider);
}

/*-------------------------- PCLK2 Configuration ---------------------------*/
if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
{
    assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB2CLKDivider));
    MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, ((RCC_ClkInitStruct->APB2CLKDivider) << 3));
}

/* Update the SystemCoreClock global variable */
SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE)>> RCC_CFGR_HPRE_Pos];

/* Configure the source of time base considering new system clocks settings*/
HAL_InitTick (TICK_INT_PRIORITY);

return HAL_OK;
}
以上代码使用STM32CubeMX生成。

个人分析:
1)按下复位键后可以使用swd下载程序证明flash配置正常,且swd电路正常
2)代码内未涉及io配置,且数据手册说明如下,证明即便配置io也不会影响swd。

3)屏蔽RCC初始化后下载正常,是否因为未初始化RCC芯片处于未运行状态,相当于处于复位?
4)使用jlink版本为jlinkv9也适用jlinkv8试验,现象同样。是否因为jlink固件问题不支持软复位?但出场原始芯片可以直接烧写,为何?
可能有其他朋友也遇到类似的问题,特此发帖求教,希望共同讨论探究,万分感谢!

祝好!





sincomaster 发表于 2019-1-3 09:29:01

我碰到过这个问题,我是用NUCLEO F413的板上的STLINK,来下载我的F103,也是提示这个,最后我发现是我不记得把NUCLEO F413板载STLINK的跳线帽(NUCLEO/STLINK)这个没有取掉,我的KEIL环境是F103,但实际下载是F413,所以提示Error: Flash Download failed - Cortex-M3,因为是M4,你再看看是那里设置不对

wenyangzeng 发表于 2019-1-10 09:52:47

提示的信息第2条显示你下载速度太快了。

无薪税绵 发表于 2019-1-10 10:20:09

在仿真器设置中,试试取消 CACHE CODE ,CACHE MEMORY,DOWNLOAD TO FLASH ,这三个勾选,看看行不行。

932837498@qq.co 发表于 2019-1-10 12:52:09

程序里面是不是有进入低功耗,我遇到过在低功耗模式不能下载的情况

watershade 发表于 2019-1-10 16:58:39

给你的第一条建议是,将代码烧写到nucleo等对应系列开发板试一下。如果确定还出问题,起码可以确定就是软件的问题。否则会一直怀疑是不是j-link或者下载配置什么的出错了。(nucleo也可以用j-link下载,不要用nucleo自带的swd烧写。用你的)
第二个你说的按下复位按键,是插上电之后按一下还是按着然后上电?我感觉应该是前者,后者实际上是用官方的bootloader进行uart等来烧写程序的方法。我假定是前者,这就说明程序进入一个特殊的状态。按照你上面说flash部分屏蔽之后正常的情况。我觉得,最好的办法还是在线dubug一下这部分会不会跳到那里去。或者你通过某种方法把不该擦写的擦写了?

总结一下,就是线理清是软件还是硬件问题。如果是软件,在线dubug看看有没有可能进入特殊的异常里面。(楼上有哥们说的sleep是一种思路,但是F103好像没有)

butterflyspring 发表于 2019-1-10 17:13:34

我碰到的情况比较多的是:1 系统进入低功耗,这样影响后面下载 2 改变调试引脚(一般PA13,PA14).这个原因通过单步调试就能发现,走到某一位置就不能调了。3.你提到的系统时钟设置,理论上你设置了FLASH延迟只有帮助,没有影响的。在极少数情况下,我看到过老版本的J-LINK 下载有异常,更换ST-LINK就好了,但不清楚原因。 建议有条件尝试一下。另外也可以做个最简单初始化的代码(不用完整功能,但长度要有的)测试验证一下。如果这样的代码下载都有问题那就真的要考虑换工具了:)

zhjb1 发表于 2019-1-11 07:15:48

本帖最后由 zhjb1 于 2019-1-11 07:50 编辑

我是在采用GD32F103VET6芯片而用STM32CubeMX生成的STM32F103VET6时遇到此问题。
我的原因是在设置Keil的OptionDebug选项时,如果不按着复位键,在Settings中看不到芯片ID,只有按着Reset键,才能正确显示芯片ID,所以只能在下载代码时先按着复位键点击下载后松开复位键就能正常下载了,下载后一切正常。采用STM32F103VET6就不需要这样操作。
原因不详。
仅供参考

toofree 发表于 2019-1-11 09:30:12

不会在纸上写程序。
发个工程上来比什么都强

korry 发表于 2019-9-9 21:46:52

我是多次插拔jlink就好了,一脸懵逼
页: [1] 2
查看完整版本: swd 4线模式下载异常求解(Error: Flash Download failed - Cortex-M3)