DAPLINK 移植 (二)

一、系统时钟

通过对官方源码时钟的配置,可用CUBEMX 得到如下图

MCU 最高工作时钟为 72M ,但是目前使用的是 8M,

之所以为什么要修改这,是因为 将 APP 文件拖到 电脑的 磁盘中,首先会执行擦除功能,擦除的地址范围 从 50K - 256K ,一共103 page ,老是出现擦除失败,

具体表现为 FAIL.TXT 中出现

    // ERROR_IAP_ERASE_ALL
    "In application programming mass erase failed.",

所以我在擦除的函数内,添加的失败预防措施。简单来说,就是当检测到擦除失败了,再擦一下,重复三次,通过打印的信息来看,103页,有那么2-3页会失败,基本上这几页 再擦一次就行了。

uint32_t EraseSector(uint32_t adr)
{
    FLASH_EraseInitTypeDef erase_init;
    uint32_t error;
    uint32_t ret = 0;  // O.K.
	HAL_StatusTypeDef ret_hal = HAL_OK;
	uint32_t trycnt = 3;

#if 0
    HAL_FLASH_Unlock();

	__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR );

    memset(&erase_init, 0, sizeof(erase_init));
    erase_init.TypeErase = FLASH_TYPEERASE_PAGES;
	erase_init.Banks = FLASH_BANK_1;
    erase_init.PageAddress = adr;
    erase_init.NbPages = 1;
    if (HAL_FLASHEx_Erase(&erase_init, &error) != HAL_OK) 
    {
        ret = 1;
	    DEBUG("Addr : 0x%X",adr);

    }

    HAL_FLASH_Lock();
#endif

	if (HAL_FLASH_Unlock() == HAL_OK)
	{
	  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR );
	  
	  memset(&erase_init, 0, sizeof(erase_init));
	  erase_init.TypeErase = FLASH_TYPEERASE_PAGES;
	  erase_init.Banks = FLASH_BANK_1;
	  erase_init.PageAddress = adr;
	  erase_init.NbPages = 1;

	  while ( trycnt-- )
	  {
	      ret_hal = HAL_FLASHEx_Erase(&erase_init, &error);

	      if ( ret_hal != HAL_OK ) 
          {
			  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR );

              DEBUG("Try : Erase Error, Page Num : 0x%X! Error Flag = %d Cnt [%d]", error, ret_hal,trycnt );
          }
          else
          { 
             trycnt = 3;
             break;
          }

	     if (trycnt == 0)
	     {
           trycnt = 3;
		   break;
	     }

	  }

	  if ( ret_hal != HAL_OK) 
	  {
		DEBUG("Erase Flash Page Error, Page Num : 0x%X! Error Flag = %d", error, ret_hal );
	  }
	  else
	  {
		//DEBUG("Erase Complete ! Page Num : 0x%X! ", adr );
	  }
	   
	  HAL_FLASH_Lock();
	}
	else
	{
	  DEBUG("FLASH unlock fail! ")
	}


    return ret;
}

解决了上述擦除失败,还是会有 FAIL.TXT ,表现为写入失败

    // ERROR_IAP_WRITE
    "In application programming write failed.",

所以添加了,写入失败的打印信息

uint32_t ProgramPage(uint32_t adr, uint32_t sz, uint32_t *buf)
{
    uint32_t i;
    uint32_t ret = 0;  // O.K.
	HAL_StatusTypeDef ret_hal = HAL_OK;
	uint32_t trycnt = 3;

    HAL_FLASH_Unlock();

    util_assert(sz % 4 == 0);
    for (i = 0; i < sz / 4; i++) {

        while ( trycnt-- )
        {
            ret_hal = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, adr + i * 4, buf[i]);

		    if ( ret_hal != HAL_OK ) 
		    {
				__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR );

			    DEBUG("Try : Program Error, Page Num : 0x%X! Error Flag = %d  Cnt [%d]", (adr + i * 4), ret_hal,trycnt );
		    }
		    else
		    {
                trycnt = 3;
		        break;
		    }

			if (trycnt == 0)
			{
                trycnt = 3;
		        break;
			}
        }

        if ( ret_hal != HAL_OK) 
        {
            DEBUG("Program Flash Page Error, Page Num : 0x%X! Error Flag = %d", adr, ret_hal );
            ret = 1;
            break;
        }
    }

    HAL_FLASH_Lock();
    return ret;
}

果然出现了,大量的写入失败信息出来,大部分 重新写一次就行了,还是存在写三次都失败的地方。

所以回到了,文章的开头,MCU的工作时钟问题,尝试把系统的时钟工作在72M,那么源代码需要做如下修改

sdk.c 文件中 void sdk_init() ,屏蔽下面的

    //SystemCoreClockUpdate();

使用外部8M的晶振,配置主频为 72M ,(可使用cubemx 配置 生成代码,复制过来即可 )

	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) {
        /* Initialization Error */
        util_assert(0);
    }


    /* USB 配置 */
	PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB;
	PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5;
	if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
	{
	  /* Initialization Error */
	  util_assert(0);

	}

 系统时间更改,保持 1000HZ ,系统的主频为 72M ,

72M / 2 / 36000 = 1000 

HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
    HAL_StatusTypeDef ret;
    RCC_ClkInitTypeDef clk_init;
    uint32_t unused;
    uint32_t prescaler;
    uint32_t source_clock;

    HAL_RCC_GetClockConfig(&clk_init, &unused);

    /* Compute the prescaler value to have TIMx counter clock equal to 4000 Hz */
    //source_clock = SystemCoreClock / tim2_clk_div(clk_init.APB1CLKDivider);
    //prescaler = (uint32_t)(source_clock / 4000) - 1;

    /* Set TIMx instance */
    timer.Instance = TIM2;

    timer.Init.Period            = 0xFFFF;
    timer.Init.Prescaler         = 36000 - 1;//prescaler;
    timer.Init.ClockDivision     = TIM_CLOCKDIVISION_DIV2;
    timer.Init.CounterMode       = TIM_COUNTERMODE_UP;
    timer.Init.RepetitionCounter = 0;

    __HAL_RCC_TIM2_CLK_ENABLE();

    ret = HAL_TIM_Base_DeInit(&timer);
    if (ret != HAL_OK) {
        return ret;
    }

    time_count = 0;
    ret = HAL_TIM_Base_Init(&timer);
    if (ret != HAL_OK) {
        return ret;
    }

    ret = HAL_TIM_Base_Start(&timer);
    if (ret != HAL_OK) {
        return ret;
    }

    return HAL_OK;
}



uint32_t HAL_GetTick(void)
{
    cortex_int_state_t state;
    state = cortex_int_get_and_disable();
    const uint32_t ticks = __HAL_TIM_GET_COUNTER(&timer) ;;/// 4; /* 去掉 */
    time_count += (ticks - time_count) & 0x3FFF; /* CNT 寄存器 15bit */
    cortex_int_restore(state);
    return time_count;
}

结果就是 不再出现 写入错误 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

写代码混口饭吃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值