stm32cubemx工程,freerots
stm32cubemx调用printf
stm32 iap,stm32在线下载
stm32cubemx在线烧录
stm32 调用printf函数
stm32重定向printf函数输出
stm32串口printf输出
stm32进入dfu
stm32cubemx IAP,stm32cubemx duf
stm32cubemx在线烧录。stm32cubemx在线更新程序
stm32远程更新
记得包含标准输入输入头文件: stdio.h
在usart.c里面添加:
/* USER CODE BEGIN 0 */
#include
/* USER CODE END 0 */
2
/* USER CODE BEGIN 1 */
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
/* USER CODE END 1 */
下面说明如何基于stm32f0x系统里面,使用在线升级(stm32f0 IAP)
Bootloader里面,main里调用函数跳转到APP地址0x8003000,下面的这个是main函数里面的主程序,分开烧录下载,一般来说,先下载这个程序用于做IAP的。
typedef void (*pFunction)(void);
#define ApplicationAddress 0x8003000
void UserAppStart(void)//这里是bootloader里面的函数
{
if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)
{
/* Jump to user application */
JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4);
Jump_To_Application = (pFunction) JumpAddress;//跳转到0x8003000
/* Initialize user application's Stack Pointer */
__set_MSP(*(__IO uint32_t*) ApplicationAddress);////初始化用户程序的堆栈指针
Jump_To_Application();//执行跳转,程序从0x8003000开始跑。
}
}
void main(void)
{
/*加入一些判断,或者*/
UserAppStart;
}
#define APPLICATION_ADDRESS (uint32_t)0x08003000
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
#if (defined ( __CC_ARM ))
__IO uint32_t VectorTable[48] __attribute__((at(0x20000000)));
#elif (defined (__ICCARM__))
#pragma location = 0x20000000
__no_init __IO uint32_t VectorTable[48];
#elif defined ( __GNUC__ )
__IO uint32_t VectorTable[48] __attribute__((section(".RAMVectorTable")));
#endif
// 上面是要自己添加的
int main(void)
{
//自己添加的,最好在user code里面添加,不会被覆盖
/* USER CODE BEGIN 1 */
uint32_t i = 0;
/* USER CODE END 1 */
HAL_Init();
/* Configure the system clock to 48 MHz */
SystemClock_Config();
/* Relocate by software the vector table to the internal SRAM at 0x20000000 ***/
/* Copy the vector table from the Flash (mapped at the base of the application
load address 0x08004000) to the base address of the SRAM at 0x20000000. */
for(i = 0; i < 48; i++)
{
VectorTable[i] = *(__IO uint32_t*)(APPLICATION_ADDRESS + (i<<2));
}
/* Enable the SYSCFG peripheral clock*/
__HAL_RCC_SYSCFG_CLK_ENABLE();
/* Remap SRAM at 0x00000000 */
//拷贝中断向量到 VectorTable,stm32f0 没有中断偏移寄存器,所以将中断向量表读取到RAM中,然后重映射到RAM地址.
__HAL_SYSCFG_REMAPMEMORY_SRAM();
/* Add your own code here...
*/
// 接下来做自己的事情,这里忽略不写...........
}
#define ApplicationAddress 0x08005000
typedef void (*pFunction)(void);
int main(void)
{
DFU_Button_Config();
/* DFU Button Check */
if (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_8) == 0)
{
// Test if user code is programmed starting from address 0x8005000 //
if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)
{
// Jump to user application //
JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4);
Jump_To_Application = (pFunction) JumpAddress;
// Initialize user application's Stack Pointer //
__set_MSP(*(__IO uint32_t*) ApplicationAddress);
Jump_To_Application();
}
}
这里不用重映射向量表,只需要跳转就好了。这个使用于stm32F1,stm32F2等单片机的dfu升级和在线升级。同样,需要在Keil中的"Target"设定IROM1的气势地址和结束地址, 一般来说,设置起始地址: 0x8003000,或者0x8005000都可以,主要是看你的IAP程序有多大。
注意! 上面并非在线固件升级,而只是,修改bootloader,如果需要在线usb DFU升级,那么要用到Stm32fCubeMx的 dfu功能, 幸运的是,我们不需要在去折腾stm32寄存器,而用stm32cubemx直接生成dfu功能的代码了,详细见下面:
参考:
http://bbs.21ic.com/icview-571430-1-1.html
http://bbs.21ic.com/icview-822770-1
https://blog.csdn.net/xy6zzz/article/details/49992367
https://blog.csdn.net/flydream0/article/details/52808191