# FreeRTOS_CodeTest **Repository Path**: pan-liangrong/free-rtos_-code-test ## Basic Information - **Project Name**: FreeRTOS_CodeTest - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-12-06 - **Last Updated**: 2025-05-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # FreeRTOS_CodeTest ## 内容介绍 这个项目,主要测试FreeRTOS的特性,如: [书的目录](https://github.com/FreeRTOS/FreeRTOS-Kernel-Book/blob/main/toc.md) [任务管理](https://github.com/FreeRTOS/FreeRTOS-Kernel-Book/blob/main/ch04.md#4-task-management) [队列管理](https://github.com/FreeRTOS/FreeRTOS-Kernel-Book/blob/main/ch05.md#5-queue-management) [软件定时器管理](https://github.com/FreeRTOS/FreeRTOS-Kernel-Book/blob/main/ch06.md#6-software-timer-management) [中断管理](https://github.com/FreeRTOS/FreeRTOS-Kernel-Book/blob/main/ch07.md#7-interrupt-management) [资源管理](https://github.com/FreeRTOS/FreeRTOS-Kernel-Book/blob/main/ch08.md#8-resource-management) [事件组](https://github.com/FreeRTOS/FreeRTOS-Kernel-Book/blob/main/ch09.md#9-event-groups) [任务通知](https://github.com/FreeRTOS/FreeRTOS-Kernel-Book/blob/main/ch10.md#10-task-notifications) [低功耗支持](https://github.com/FreeRTOS/FreeRTOS-Kernel-Book/blob/main/ch11.md#11-low-power-support) [开发者支持](https://github.com/FreeRTOS/FreeRTOS-Kernel-Book/blob/main/ch12.md#12-developer-support) [troubleshooting](https://github.com/FreeRTOS/FreeRTOS-Kernel-Book/blob/main/ch13.md#13-troubleshooting) ## 参考内容 [FreeRTOS-Kernel](https://github.com/FreeRTOS/FreeRTOS-Kernel):FreeRTOS核心源码以及头文件 [FreeRTOS-Kernel-Book](https://github.com/FreeRTOS/FreeRTOS-Kernel-Book):示例代码以及书籍 [FreeRTOS](https://github.com/FreeRTOS/FreeRTOS):FreeRTOS移植下载的代码 ## 时间戳 第一次更新时间:2024年12月7日00:32:32 ### 资源管理的措施: #### 进入和退出临界段 ~~~c //Enter the critical section taskENTER_CRITICAL(); { printf( "%s", pcString ); } // exit the critical section taskEXIT_CRITICAL(); ~~~ #### 挂起调度器 ~~~c /* Write the string to stdout, suspending the scheduler as a method of mutual exclusion. */ vTaskSuspendScheduler(); { printf( "%s", pcString ); } xTaskResumeScheduler(); ~~~ #### 使用信号量(二值/互斥) ~~~c xSemaphoreTake( xMutex, portMAX_DELAY ); { /* The following line will only execute once the mutex has been successfully obtained. Standard out can be accessed freely now as only one task can have the mutex at any one time. */ printf( "%s", pcString ); /* The mutex MUST be given back! */ } xSemaphoreGive( xMutex ); ~~~ #### Gatekeeper Tasks ~~~c FreeRTOS中的Gatekeeper Task(门卫任务)是一种设计模式,用于管理对共享资源的访问,以避免优先级反转和死锁问题。在这种模式中,Gatekeeper Task是唯一有权直接访问共享资源的任务,其他任务必须通过Gatekeeper Task来间接访问资源。以下是Gatekeeper Task的工作原理: 资源共享:Gatekeeper Task作为资源共享的唯一拥有者,其他任务想要访问资源时,必须通过Gatekeeper Task提供的服务来进行。这样,任何时候只有一个任务(即Gatekeeper Task)直接与共享资源交互,避免了多个任务直接竞争资源的问题 任务通信:其他任务通过发送消息(例如字符串、命令等)到一个队列中,请求Gatekeeper Task执行特定的操作。Gatekeeper Task在接收到消息后,会执行相应的操作,比如在串口打印消息 避免优先级反转:由于Gatekeeper Task是唯一直接访问共享资源的任务,其他任务不会直接与共享资源交互,因此不存在优先级反转的问题。优先级反转是指一个高优先级任务因为等待低优先级任务持有的资源而被阻塞的情况 避免死锁:由于Gatekeeper Task控制着对共享资源的访问,它可以避免多个任务同时尝试访问资源导致的死锁情况。死锁是指两个或多个任务在等待对方释放资源而永远无法继续执行的状态 队列管理:Gatekeeper Task通常包含一个队列,用于接收来自其他任务的请求。Gatekeeper Task在队列中等待请求,一旦收到请求,就会执行相应的操作,并将结果反馈给请求任务或直接操作共享资源 任务优先级:Gatekeeper Task通常被赋予较低的优先级,以确保它不会抢占其他高优先级任务的执行。这样可以保证Gatekeeper Task只在没有更高优先级任务需要执行时才运行,从而有效地管理共享资源的访问 通过使用Gatekeeper Task,FreeRTOS可以有效地管理对共享资源的访问,提高系统的稳定性和响应性。这种模式特别适用于需要严格管理资源访问的场景,如串口通信、LCD显示更新等 ~~~ ### 二值信号量与互斥信号量 二值信号量/互斥信号量的值为:0或1,为什么有了二值信号量又有了互斥信号量? 原因: 1. 信号量会引入:任务优先级反转的问题; 2. 互斥信号量引入了:任务优先级继承的机制,来解决优先级反转的问题; 第二次更新时间:2024年12月7日18:23:26 # STM32F1xx_ProTemplate ## 目录结构 ~~~c STM32F1xx_ProTemplate/ |-- App | |-- inc | `-- src |-- Doc |-- Func | |-- include | `-- source |-- HwDrv | |-- Bsp_Driver | | |-- inc | | `-- src | |-- CM3 | `-- STM32F10x_StdPeriph_Driver | |-- inc | `-- src |-- Listings |-- MiddleSoftWare | |-- FreeRTOS | | |-- include | | `-- portable | | |-- Keil | | |-- MemMang | | `-- RVDS | | |-- ARM7_LPC21xx | | |-- ARM_CA9 | | |-- ARM_CM0 | | |-- ARM_CM3 | | |-- ARM_CM4F | | |-- ARM_CM4_MPU | | `-- ARM_CM7 | | `-- r0p1 | `-- LVGL |-- Objects `-- User ~~~ ## Cortex-M3 堆栈的实现 >Cortex‐M3 使用的是“向下生长的满栈”模型。 > >堆栈指针 SP 指向最后一个被压入堆栈的 32位数值。 > >**在下一次压栈时,SP 先自减 4,再存入新的数值。** > >**POP 操作刚好相反:先从 SP 指针处读出上一次被压入的值,再把 SP 指针自增 4。** > >虽然 POP 后被压入的数值还保存在栈中,但它已经无效了,因为为下次的 PUSH 将覆盖它的值! > >![image-20241223164947887](../tool_use/Typora_pic/image-20241223164947887.png) > >![image-20241223165936019](../tool_use/Typora_pic/image-20241223165936019.png) ## 程序编译报错 ### 程序体积太大Flash不够使用 >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_port_disp_template.o(.bss). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching startup_stm32f10x_hd.o(STACK). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching startup_stm32f10x_hd.o(HEAP). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching hwdrv_spi.o(.bss). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching hwdrv_usart.o(.bss). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching hwdrv_oled.o(.bss). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching tasks.o(.bss). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching hwdrv_sdio_sdcard.o(.bss). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_gc.o(.bss). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_draw_sw_letter.o(.bss). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching func_faultcode.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching libspace.o(.bss). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_theme_default.o(.bss). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_keyboard.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching func_faultcode.o(.bss). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching tasks.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching hwdrv_tp.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_calendar_header_arrow.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching fontupd.o(.bss). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_port_indev_template.o(.bss). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_theme_default.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_txt.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching exfuns.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching mymalloc.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_calendar.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_btnmatrix.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_gc.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching hwdrv_usart.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_grid.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching system_stm32f10x.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching stm32f10x_rcc.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_timer.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching gui_test_ui_login3.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching hwdrv_sdio_sdcard.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_mem.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching hwdrv_lcd.o(.bss). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching gui_test_ui_display_temphumi.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_hal_disp.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching port.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching hwdrv_adc.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_flex.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_tileview.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_anim.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_area.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching gui_test_ui_display_temphumiwarn.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching ff.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_colorwheel.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_indev.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_draw_sw_gradient.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_port_indev_template.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_event.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_obj.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_refr.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_draw_sw_letter.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_calendar_header_dropdown.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_spinner.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_font_montserrat_14.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching gui_test_ui_display_fault.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching hwdrv_i2c.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching hwdrv_tp_ft5206.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_style.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_obj_pos.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_hal_tick.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching hwdrv_delay.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching hwdrv_lcd.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching hwdrv_spi.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_group.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_tabview.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_textarea.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching hwdrv_key.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching diskio.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_win.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching hwdrv_tp_gt9147.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching hwdrv_tp_ott2001a.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6406E: No space in execution regions with .ANY selector matching lv_obj_style.o(.data). >.\Objects\STM32F1xx_ProTemplate.axf: Error: L6407E: Sections of aggregate size 0x64b0 bytes could not fit into .ANY selector(s). 判断应该是.data以及.bss空间不足,尝试修改.s文件,减小栈堆空间,来满足.bss以及.data空间; ----不行 ## STM32的链接脚本 Keil5中的链接器脚本(也称为scatter文件/分散加载文件.sct)是一种用于指导编译器和链接器如何将源代码文件链接成可执行映像的文本文件。它定义了内存布局、外设地址和中断向量表等关键信息。 ### Keil5链接器脚本的一些主要配置项 >1. **MEMORY指令**:定义内存区域,并指定它们的属性(例如,大小、地址范围) > > ~~~c > MEMORY{ > FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 128K > RAM (rw) : ORIGIN = 0x20000000, LENGTH = 64K > } > ~~~ > > 这里定义了FLASH和RAM两个内存区域,包括它们的起始地址和长度 > >2. **SECTIONS指令**:定义代码和数据段,并指定它们的属性(例如,可执行、可读、可写) > > ~~~c > SECTIONS{ > .text : {} > FLASH > .data : {} > RAM > .bss : {} > RAM > } > ~~~ > > 这里指定了.text、.data和.bss段应该放置在FLASH或RAM中 > >3. **ENTRY指令**:指定程序的入口点 > > ~~~c > ENTRY(Reset_Handler) > ~~~ > >4. **INCLUDE指令**:包含其他链接器脚本文件 > > ~~~c > INCLUDE other_script.sct > ~~~ > > 这允许链接器脚本包含其他文件中定义的区域和段 > >5. **其他指令**:用于配置中断向量表、堆栈和符号表等。例如,可以定义堆栈的起始地址和大小。 > >6. **Make RO Sections Position Independent**:创建可重定位的只读(R/O)节区。 > >7. **Make RW Sections Position Independent**:创建可重定位的读写(R/W)节区。 > >8. **Don't Search Standard Libraries**:不搜索标准库。 > >9. **Report 'might fail' Conditions as Errors**:报告可能出现失败的情况作为错误。 > >10. **Scatter File**:分散加载文件,用于描述内存布局。 > >11. **Misc controls**:可能包含额外的链接器选项。 > >12. **Linker control string**:链接器控制字符串,这里是一系列链接器参数 ## 启动模式 >在STM32F10xxx里,可以通过BOOT[1:0]引脚选择三种不同启动模式 > >| BOOT1 | BOOT0 | 启动模式 | 说明 | >| ----- | ----- | ------------ | -------------------------- | >| x | 0 | 主闪存存储器 | 主闪存存储器被选为启动区域 | >| 0 | 1 | 系统存储器 | 系统存储器被选为启动区域 | >| 1 | 1 | 内置SRAM | 内置SRAM被选为启动区域 | > >根据选定的启动模式,主闪存存储器、系统存储器或SRAM可以按照以下方式访问: > >* 从主闪存存储器启动:主闪存存储器被映射到启动空间(0x0000 0000),但仍然能够在它原有的地址(0x0800 0000)访问它,即闪存存储器的内容可以在两个地址区域访问,0x00000000或0x0800 0000。 >* 从系统存储器启动:系统存储器被映射到启动空间(0x0000 0000),但仍然能够在它原有的地址(互联型产品原有地址为0x1FFF B000,其它产品原有地址为0x1FFF F000)访问它。 >* 从内置SRAM启动:STM32F10xxx内置64K字节的静态SRAM,只能在0x2000 0000开始的地址区访问SRAM。 ## STM32 三种存储器的理解 >* 主闪存存储器 > STM32内置的Flash,一般我们使用JTAG或者SWD模式下载程序时,就是下载到这个里面,重启后也直接从这启动程序,可以理解为电脑中的软件安装在这里。 >* 内置 SRAM > 芯片内置的RAM区,没有程序存储的能力了,可以理解为这个是电脑的内存条。 >* 系统存储器 > 一块特定的区域,只读ROM存储器,STM32厂家在这个区域内部预置了一段BootLoader,也就是我们常说的ISP程序,出厂后无法修改。选用这种模式启动,可以从串口下载程序到Flash中,可以理解为电脑中的Window系统安装在这里。 ## STM32 bootloader开发 >STM32的Bootloader开发主要涉及以下几个方面的任务: > >* 硬件初始化:Bootloader首先需要进行硬件初始化,包括配置时钟、内存、外设等硬件资源。这些初始化和配置是在应用程序运行之前完成的,确保应用程序在运行时能够正确访问和使用这些硬件资源。 >* 固件版本检测:Bootloader可以通过检测固件版本来判断是否需要更新固件程序。这是固件升级过程中的一个重要步骤,以确保系统运行的是最新版本的固件。 >* 加载固件程序:如果需要更新固件程序,Bootloader将从外部存储器(如SD卡、NAND Flash等)或内部Flash存储器中加载固件程序。这一步骤是Bootloader的核心功能之一,涉及到数据的读取和写入操作。 >* 校验固件程序:Bootloader会对加载的固件程序进行校验,确保固件程序的完整性和正确性。这一步骤有助于防止因固件损坏导致的系统故障。 >* 跳转到用户程序:如果固件程序校验通过,Bootloader将跳转到用户程序的入口地址,开始执行用户程序。这是Bootloader的另一个关键功能,确保系统能够顺利过渡到应用程序的执行。 >* 支持固件升级:Bootloader还可以提供一些额外的功能,如通过串口、USB或其他接口进行程序烧录,支持固件热更新。这使得设备能够远程更新固件,提高了设备的可维护性和灵活性。 >* 安全特性:Bootloader需要能防止非法固件的加载,保护设备不受恶意软件攻击。这是在设计Bootloader时需要考虑的一个重要方面,特别是在安全性要求较高的应用中。 >* 性能优化:Bootloader的设计还需要考虑性能优化,以确保系统能够快速启动和响应。 >* 总的来说,STM32的Bootloader开发涉及到硬件初始化、固件管理、系统跳转等多个方面,是确保STM32系统正常运行和更新的关键部分。 > >bootloader开发的例程: > >* 参见正点原子:IAP实验 > >* 由.axf生成.bin文件的指令:D:\keil5\ARM\ARMCC\bin\fromelf.exe --bin -o ..\OBJ\RTC.bin ..\OBJ\RTC.axf > >* 参见例程: > > [stm32_bootloader](https://gitee.com/pan-liangrong/stm32_bootloader) ## STM32 有无bootloader程序有什么差别吗? >STM32的Boot程序和没有Boot程序的主要区别在于启动模式和功能。 > >Bootloader,主要解决了以下几个问题: > >* 启动模式选择:STM32通过BOOT0和BOOT1引脚的状态来选择不同的启动模式。如果没有Boot程序,STM32通常默认从内置Flash启动,这是最常见的启动模式。而有了Boot程序,用户可以选择从系统存储器启动,这通常用于固件升级和恢复。 >* 固件升级和恢复:Boot程序允许STM32通过串口、USB或其他接口进行固件更新。在系统存储器模式下,STM32会从预置的Bootloader启动,这个Bootloader由ST在出厂时烧录进去,主要用于将用户应用程序下载到芯片内部Flash。如果没有Boot程序,固件升级和恢复操作将无法通过串口等接口进行。 >* 调试和开发:Boot程序还可以用于调试和开发。例如,STM32提供了SRAM启动模式,这通常用于程序调试。在这种模式下,程序可以从内置SRAM启动,这有助于快速更新和调试代码,而不需要频繁擦除和重写Flash。 >* 解决芯片死锁问题:在开发调试过程中,如果内部Flash锁死,无法连接SWD或JTAG调试,可以通过修改BOOT模式重新刷写代码。将BOOT0设置为1,BOOT1设置为0,可以从系统存储器启动,利用ST出厂时自带的Bootloader程序进行操作。 >* 程序跳转:Bootloader的一个重要能力是能实现程序跳转,即从一个完整的程序跳转到另一个完整的程序进行运行。在嵌入式系统中,Bootloader的一个很重要的功能是更新程序,要求Bootloader不仅能接收数据,还能把数据写入flash中。 >* 综上所述,Boot程序为STM32提供了更多的灵活性和功能,特别是在固件升级、恢复和调试方面。如果没有Boot程序,STM32将缺少这些高级功能,只能从内置Flash启动执行程序。