iap.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "usart.h"
  4. #include "stmflash.h"
  5. #include "iap.h"
  6. #include "led.h"
  7. //////////////////////////////////////////////////////////////////////////////////
  8. //本程序只供学习使用,未经作者许可,不得用于其它任何用途
  9. //ALIENTEK MiniSTM32开发板
  10. //IAP 代码
  11. //正点原子@ALIENTEK
  12. //技术论坛:www.openedv.com
  13. //修改日期:2014/1/8
  14. //版本:V1.0
  15. //版权所有,盗版必究。
  16. //Copyright(C) 广州市星翼电子科技有限公司 2009-2019
  17. //All rights reserved
  18. //////////////////////////////////////////////////////////////////////////////////
  19. iapfun jump2app;
  20. u16 iapbuf[1024];
  21. //appxaddr:应用程序的起始地址
  22. //appbuf:应用程序CODE.
  23. //appsize:应用程序大小(字节).
  24. void iap_write_appbin(u32 appxaddr,u8 *appbuf,u32 appsize)
  25. {
  26. u16 t;
  27. u16 i=0;
  28. u16 temp;
  29. u32 fwaddr=appxaddr;//当前写入的地址
  30. u8 *dfu=appbuf;
  31. for(t=0;t<appsize;t+=2)
  32. {
  33. temp=(u16)dfu[1]<<8;
  34. temp+=(u16)dfu[0];
  35. dfu+=2;//偏移2个字节
  36. iapbuf[i++]=temp;
  37. if(i==1024)
  38. {
  39. i=0;
  40. STMFLASH_Write(fwaddr,iapbuf,1024);
  41. fwaddr+=2048;//偏移2048 16=2*8.所以要乘以2.
  42. }
  43. }
  44. if(i)STMFLASH_Write(fwaddr,iapbuf,i);//将最后的一些内容字节写进去.
  45. }
  46. //跳转到应用程序段
  47. //appxaddr:用户代码起始地址.
  48. void iap_load_app(u32 appxaddr)
  49. {
  50. if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000) //检查栈顶地址是否合法.
  51. {
  52. TIM_ARRPreloadConfig(TIM4, DISABLE); //使能重载值TIM4_PRESCALER_VALUE
  53. USART_ITConfig(USART1, USART_IT_RXNE, DISABLE); //使能USART1接收中断
  54. USART_Cmd(USART1, DISABLE); //使能USART1
  55. USART_ITConfig(USART2, USART_IT_RXNE, DISABLE); //使能USART2接收中断
  56. USART_Cmd(USART2, DISABLE); //使能USART2
  57. USART_ITConfig(UART4, USART_IT_RXNE, DISABLE); //使能USART4接收中断
  58. USART_Cmd(UART4, DISABLE); //使能USART4
  59. USART_ITConfig(UART5, USART_IT_RXNE, DISABLE); //使能USART5接收中断
  60. USART_Cmd(UART5, DISABLE); //使能USART5
  61. INTX_DISABLE();
  62. jump2app=(iapfun)*(vu32*)(appxaddr+4); //用户代码区第二个字为程序开始地址(复位地址)
  63. MSR_MSP(*(vu32*)appxaddr); //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
  64. jump2app(); //跳转到APP.
  65. while(1);
  66. }
  67. else
  68. {
  69. printf("栈顶地址不合法\r\n");
  70. }
  71. return;
  72. }
  73. //运行app1
  74. uint32_t run_app1(void)
  75. {
  76. // IRQn_Type irq;
  77. uint32_t appxaddr=FLASH_APP1_ADDR;
  78. printf("jump to 0x%08X.\r\n",appxaddr);
  79. if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000) //检查栈顶地址是否合法.
  80. {
  81. // USART_ITConfig(USART1, USART_IT_RXNE, DISABLE); //使能USART1接收中断
  82. // USART_Cmd(USART1, DISABLE); //使能USART1
  83. //
  84. // USART_ITConfig(USART2, USART_IT_RXNE, DISABLE); //使能USART2接收中断
  85. // USART_Cmd(USART2, DISABLE); //使能USART2
  86. //
  87. // USART_ITConfig(UART4, USART_IT_RXNE, DISABLE); //使能USART4接收中断
  88. // USART_Cmd(UART4, DISABLE); //使能USART4
  89. //
  90. // USART_ITConfig(UART5, USART_IT_RXNE, DISABLE); //使能USART5接收中断
  91. // USART_Cmd(UART5, DISABLE); //使能USART5
  92. // for (irq = SysTick_IRQn; irq <= DMA2_Channel4_5_IRQn; irq++)
  93. // {
  94. // NVIC_DisableIRQ(irq);
  95. // NVIC_ClearPendingIRQ(irq);
  96. // }
  97. // __disable_irq();
  98. INTX_DISABLE();
  99. //TIM3_Int_Deinit();
  100. jump2app=(iapfun)*(vu32*)(appxaddr+4); //用户代码区第二个字为程序开始地址(复位地址)
  101. MSR_MSP(*(vu32*)appxaddr); //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
  102. jump2app(); //跳转到APP.
  103. while(1);
  104. }
  105. else
  106. {
  107. printf("栈顶地址不合法\r\n");
  108. }
  109. return 0;
  110. }
  111. //获取信息
  112. uint32_t get_info(void)
  113. {
  114. return 0;
  115. }
  116. //复位
  117. uint32_t reboot(void)
  118. {
  119. NVIC_SystemReset();// 复位
  120. return 0;
  121. }