STM32CubeMx生成的工程中使用Printf函数调试和IAP

发布者:EtherealHeart最新更新时间:2020-06-07 来源: eefocus关键字:STM32CubeMx  工程  Printf函数  调试  IAP 手机看文章 扫描二维码
随时随地手机看文章

一、STM调试信息打印方法。

1. 新建stm32cubemx工程,配置工程。

图片1,配置stm32cubemx

我用的是STM32cubeMx版本: Version 4.27.0, cube Version V1.0。

版本图片1

2. 在stm32cubemx工程,配置工程,勾选使用FreeRtOs系统。

勾选freerots

注意,勾选左边的,freertos,使用系统。stm32做的,非常方便。

3. 生成带系统FreeRtos的源码工程(我这里基于keil MDK v5)

勾选工程生成的类型

4. 生成工程,然后用keil打开,在源码里面添加代码,使得USART1重定向到标准Printf函数中输出。

在这里插入图片描述

在generated file里面,勾选:generate periheral initialization as apair of “.c/.h” files per periheral; 这样可以让每个外设,都生成一个文件。不用全面功能呢堆在一起。

输入代码重定向printf

包含标准输出输入头文件

注意选择工程的种类,我用的是keil mdk v5。

5. 总结添加的代码如下:

记得包含标准输入输入头文件: stdio.h


在usart.c里面添加:


/* USER CODE BEGIN 0 */

#include

/* USER CODE END 0 */


/* 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 */


在“user code” 里面添加,这样你再次编译生成stm32cubmx工程的时候,你的代码才会被保留,不如会被知覆盖掉。


二、STM IAP方法(基于STM32F0xx系列)。

1. stm32f0x系列IAP,基于Stm32CubeMx的工程。

下面说明如何基于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;

}


stm23cubemx 工程源码里面(APP) main 函数添加:

#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...    

*/

// 接下来做自己的事情,这里忽略不写...........

}


在Keil下设置IROM1:start 0x8003000 IRAM1:Start 0x200000C0

记得对应自己设置的位置。

在这里插入图片描述

stm32f0 没有中断偏移寄存器,所以将中断向量表读取到RAM中,然后重映射到RAM地址, 应该说,stm32f0x系列的都要这样做,否则不能正常使用中断。

2. stm32f1+系列IAP,基于Stm32CubeMx的工程。

stm32F103 dfu IAP

#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功能的代码了,详细见下面:


三、 STM32CubeMx Device firmware Update(STM32 DFU功能实现)

1. demo:STM32F103VBT单片机的dfu IAP功能的实现详细步骤(基于Stm32cubeMx):

先打开Stm32CubeMx软件,然后选择型号,stm32f103vbt,在左侧配置功能的界面,打开usb device(STM32F103VBt只有 usb Device only功能)

版本版本有依旧之前一样。

在这里插入图片描述

2. 配置STM32F103VBT单片机的DFU(这里默认配置即可),启动地址一般位于0x08000000:

在这里插入图片描述

在这里插入图片描述

3. 生成工程,就万事大吉,启动开发板,你会发现需要你安装usb驱动

在这里插入图片描述

在这里插入图片描述

4. 下载编译好的stm32cubemx工程DFU hex文件到开发板验证:

然后上电启动,连开发板的usb到电脑,发现,电脑发现新硬件!需要安装smt32 的dfu驱动, 这个驱动在你的DFU下载软件DfuSeDemo的安装文件夹里面可以找到。

在这里插入图片描述

安装好驱动之后,就可以用那个来下载主程序了!

在这里插入图片描述

记得修改dfu里面的跳转(这样你才能有跑到你的应用程序的main函数去),参考上一个步骤,开始你的产品程序编写吧!

参考:


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

关键字:STM32CubeMx  工程  Printf函数  调试  IAP 引用地址:STM32CubeMx生成的工程中使用Printf函数调试和IAP

上一篇:MDK-ARM(Keil uVision V4.72)上STM32开发环境配置
下一篇:STM32CubeMx启动串口调试功能Printf调试

推荐阅读最新更新时间:2024-10-24 15:58

STM32CubeMx生成的工程中使用Printf函数调试IAP
一、STM调试信息打印方法。 1. 新建stm32cubemx工程,配置工程。 我用的是STM32cubeMx版本: Version 4.27.0, cube Version V1.0。 2. 在stm32cubemx工程,配置工程,勾选使用FreeRtOs系统。 注意,勾选左边的,freertos,使用系统。stm32做的,非常方便。 3. 生成带系统FreeRtos的源码工程(我这里基于keil MDK v5) 4. 生成工程,然后用keil打开,在源码里面添加代码,使得USART1重定向到标准Printf函数中输出。 在generated file里面,勾选:generate periheral init
[单片机]
<font color='red'>STM32CubeMx</font>生成的<font color='red'>工程</font>中使用<font color='red'>Printf</font><font color='red'>函数</font><font color='red'>调试</font>和<font color='red'>IAP</font>
STM32CubeMx生成的工程中使用Printf函数调试IAP
一、STM调试信息打印方法。 1. 新建stm32cubemx工程,配置工程。 我用的是STM32cubeMx版本: Version 4.27.0, cube Version V1.0。 2. 在stm32cubemx工程,配置工程,勾选使用FreeRtOs系统。 注意,勾选左边的,freertos,使用系统。stm32做的,非常方便。 3. 生成带系统FreeRtos的源码工程(我这里基于keil MDK v5) 4. 生成工程,然后用keil打开,在源码里面添加代码,使得USART1重定向到标准Printf函数中输出。 在generated file里面,勾选:generate periheral init
[单片机]
<font color='red'>STM32CubeMx</font>生成的<font color='red'>工程</font>中使用<font color='red'>Printf</font><font color='red'>函数</font><font color='red'>调试</font>和<font color='red'>IAP</font>
stm32CubeMx上移植自己的printf()和scanf()函数
要想printf()和scanf() 函数工作,我们需要把printf()和scanf() 重新定向到串口中。重定向是指用户可以自己重写C 的库函数,当连接器检查到用户编写了与C 库函数相同名字的函数时,优先采用用户编写的函数,这样用户就可以实现对库的修改了。为了实现重定向printf()和scanf() 函数,我们需要分别重写fputc()和fgetc() 这两个C 标准库函数。 一、移植printf()函数,重定向C库函数printf到USART1 int fputc(int ch, FILE *f) { HAL_UART_Transmit(&huart1, (uint8_t *)&ch,1, 0xFFFF);
[单片机]
STM32CubeMx启动串口调试功能Printf调试
## 概述 项目中往往需要调试信息,调试stm32的时候,需要标准库里面的printf函数。在keil MDK环境下重定向printf与keil C51不同,由于本人使用了STM32CubeMX生成工程模板,HAL_USART_Transmit函数即是模板里串口输出的函数。由于printf最终是调用fputc输出数据,fputc是一个弱引用(weak)函数,覆写即可重定向printf。 代码清单 /* USER CODE BEGIN Includes */ #include FreeRTOS.h #include task.h #include queue.h #include stdio.h /* USER CODE
[单片机]
STM32CubeMx启动串口调试功能Printf调试
## 概述 项目中往往需要调试信息,调试stm32的时候,需要标准库里面的printf函数。在keil MDK环境下重定向printf与keil C51不同,由于本人使用了STM32CubeMX生成工程模板,HAL_USART_Transmit函数即是模板里串口输出的函数。由于printf最终是调用fputc输出数据,fputc是一个弱引用(weak)函数,覆写即可重定向printf。 代码清单 /* USER CODE BEGIN Includes */ #include FreeRTOS.h #include task.h #include queue.h #include stdio.h /* USER CODE
[单片机]
<font color='red'>STM32CubeMx</font>启动串口<font color='red'>调试</font>功能<font color='red'>Printf</font><font color='red'>调试</font>
51单片机 printf函数 调试程序
主要分三个部分(1)51单片机程序部分;(2)keil工具部分;(3)为何printf输出为串口。 (1)51单片机程序部分 #include stdio.h #include reg51.h void InitUART(void)//使用定时器1作为串口波特率发生器 { TH1 = 0xF3; //晶振12mhz 波特率串口上设为2400才不显示乱码代码是4800 TL1 = TH1; TMOD |= 0x20; //定时器1方式2 SCON = 0x50; //串口接收使能 ES = 1; //串口中断使能 TR1 = 1; //定时器1使能 TI = 1; //发送中断
[单片机]
Keil MDK 中利用串口及c标准库函数printf为cortex-m3做调试输出
摘要: c标准库的printf是输出给显示器的,将printf函数进行修改,使其输出重定向至串口,就能实现目的。printf函数调用fputc函数完成实质输出单一字符的工作,因此将fputc函数修改使之完成串口单字符发送工作即可。 注: 本文方法性内容主要来自《Keil MDK环境下使用printf函数的解决方法》与《STM32串口使用Printf()函数问题》。除使用c标准库外,还可以使用keil mdk提供的microLib,在STM32串口使用Printf()函数问题》一文有介绍,另外,该文同时也提到如果使用c标准库函数,则要避免链接使用半主机模式的函数,retarge.c文件中的#pragma import(__use
[单片机]
IAR瑞萨单片机开发加入printf调试函数
IAR开发环境,没有printf函数,自己百度加入了一个(http://www.cnblogs.com/codecamel/p/4686437.html),但是还是有一些问题,特别是打印多个变量时,只能够打印字符串时比较稳定,原因是因为va_arg()给了错误的返回值,故只能找寻其他的方法,今天测试了一下,新的办法步骤如下 1.关键之处,否则会出现PUTCHAR函数未定义现象。 右键点击工程选择option- General Option- ibrary configuration中library改为full,且 General Option- library option- Printf formatter选项中选择full2
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved