Other Parts Discussed in Thread: UNIFLASH
Tool/software:
This is Machine-Translated because i am NOT ABLE to create this thread on e2echina.ti.com. I can't figure out the reason but it constantly returns HTTP Code 500.
When using the MSPM0 evaluation kit and Keil uV5 tool for development, I found that after removing specific function calls from the code, although the program can compile successfully, it cannot be burned (downloaded) into the microcontroller. Even if the deleted code cannot be executed (such as the method shown in the second code), as long as the code is compiled into a binary file, it can be burned successfully. After continuous experimentation, it was found that using the following two pieces of code can stably reproduce this problem:
Firstly, it should be noted that the following two pieces of code were extracted from my project and have no practical significance, but are sufficient to reproduce the bug mentioned in the question.
Using the latest Keil uV5 ARM (version at the end), open the empty project in the mspm0 SDK example and install it in my SDK at C:\ti\mspm0_sdk_2_01_00_03\examples\nortos\LP_MSPM0G3507\driverlib\empty. Replace the main.c code with:
#include "ti_msp_dl_config.h" #include "stdio.h" int main(void) { SYSCFG_DL_init(); char str[50]; sprintf(str, "%.3f", 12.345f); while (1) { } }
(Due to space limitations, copyright has been omitted)
Here is the detailed error information:
Rebuild started: Project: empty_LP_MSPM0G3507_nortos_keil *** Using Compiler 'V6.19', folder: 'C:\Keil_v5\ARM\ARMCLANG\Bin' Rebuild target 'empty_LP_MSPM0G3507_nortos_keil' Before Build - User command #1: cmd.exe /C "C:\ti\mspm0_sdk_2_01_00_03\examples\nortos\LP_MSPM0G3507\driverlib\empty\keil\../../../../../../tools/keil/syscfg.bat 'C:\ti\mspm0_sdk_2_01_00_03\examples\nortos\LP_MSPM0G3507\driverlib\empty\keil\' empty.syscfg" Using Sysconfig Tool from "C:\ti\sysconfig_1.21.0\sysconfig_cli.bat" "Update the file located at <sdk path>/tools/keil/syscfg.bat to use a different version" Warning: SysConfig has been updated to use standard TI part numbers. The device MSPM0G3505 has been automatically selected. If this is not the desired please open SysConfig to change it. Running script... Validating... info: /ti/project_config/ProjectConfig deviceSpin: Note: User must select a device after migration. Generating Code (empty.syscfg)... Unchanged C:\ti\mspm0_sdk_2_01_00_03\examples\nortos\LP_MSPM0G3507\driverlib\empty\ti_msp_dl_config.c... Unchanged C:\ti\mspm0_sdk_2_01_00_03\examples\nortos\LP_MSPM0G3507\driverlib\empty\ti_msp_dl_config.h... assembling startup_mspm0g350x_uvision.s... compiling empty.c... compiling ti_msp_dl_config.c... linking... Program Size: Code=7128 RO-data=772 RW-data=0 ZI-data=352 FromELF: creating hex file... ".\Objects\empty_LP_MSPM0G3507_nortos_keil.axf" - 0 Error(s), 0 Warning(s). Build Time Elapsed: 00:00:01 Load "C:\\ti\\mspm0_sdk_2_01_00_03\\examples\\nortos\\LP_MSPM0G3507\\driverlib\\empty\\keil\\Objects\\empty_LP_MSPM0G3507_nortos_keil.axf" Info: Debug/System power-up request sent Info: executing SWD power up Info: Current state of access point is: 80427 Info: Current state of access point is: 680027 Erase Done. Programming Failed! Error: Flash Download failed - "Cortex-M0+" Flash Load finished at 00:45:36
However, without changing the compiler settings, if the code is replaced with the following, which is to add a function and compile it into a binary file, the program can be compiled and burned (downloaded) normally, although this new function only plays a placeholder role. The code is as follows:
#include "ti_msp_dl_config.h" #include "stdio.h" #define TIMER_CLOCK_KHz 60000 void setFrequencyKHz(int freqKHz) { int calculatedValue; if (freqKHz > 10000) return; calculatedValue = TIMER_CLOCK_KHz / freqKHz; static DL_TimerG_PWMConfig gPWM_0Config = { .pwmMode = DL_TIMER_PWM_MODE_EDGE_ALIGN, .startTimer = DL_TIMER_START, }; gPWM_0Config.period = calculatedValue; DL_TimerG_initPWMMode( TIMG12, (DL_TimerG_PWMConfig *)&gPWM_0Config); DL_TimerG_setCaptureCompareValue(TIMG12, calculatedValue / 2, DL_TIMER_CC_0_INDEX); } int main(void) { SYSCFG_DL_init(); char str[50]; sprintf(str, "%.3f", 12.345f); int i = 0; switch (i) { case -1: setFrequencyKHz(123); } while (1) { } }
This is the output of compilation burning:
Rebuild started: Project: empty_LP_MSPM0G3507_nortos_keil *** Using Compiler 'V6.19', folder: 'C:\Keil_v5\ARM\ARMCLANG\Bin' Rebuild target 'empty_LP_MSPM0G3507_nortos_keil' Before Build - User command #1: cmd.exe /C "C:\ti\mspm0_sdk_2_01_00_03\examples\nortos\LP_MSPM0G3507\driverlib\empty\keil\../../../../../../tools/keil/syscfg.bat 'C:\ti\mspm0_sdk_2_01_00_03\examples\nortos\LP_MSPM0G3507\driverlib\empty\keil\' empty.syscfg" Using Sysconfig Tool from "C:\ti\sysconfig_1.21.0\sysconfig_cli.bat" "Update the file located at <sdk path>/tools/keil/syscfg.bat to use a different version" Warning: SysConfig has been updated to use standard TI part numbers. The device MSPM0G3505 has been automatically selected. If this is not the desired please open SysConfig to change it. Running script... Validating... info: /ti/project_config/ProjectConfig deviceSpin: Note: User must select a device after migration. Generating Code (empty.syscfg)... Unchanged C:\ti\mspm0_sdk_2_01_00_03\examples\nortos\LP_MSPM0G3507\driverlib\empty\ti_msp_dl_config.c... Unchanged C:\ti\mspm0_sdk_2_01_00_03\examples\nortos\LP_MSPM0G3507\driverlib\empty\ti_msp_dl_config.h... assembling startup_mspm0g350x_uvision.s... compiling empty.c... compiling ti_msp_dl_config.c... linking... Program Size: Code=7920 RO-data=788 RW-data=8 ZI-data=352 FromELF: creating hex file... ".\Objects\empty_LP_MSPM0G3507_nortos_keil.axf" - 0 Error(s), 0 Warning(s). Build Time Elapsed: 00:00:01 Load "C:\\ti\\mspm0_sdk_2_01_00_03\\examples\\nortos\\LP_MSPM0G3507\\driverlib\\empty\\keil\\Objects\\empty_LP_MSPM0G3507_nortos_keil.axf" Info: Debug/System power-up request sent Info: executing SWD power up Info: Current state of access point is: 80027 Info: Current state of access point is: 680027 Erase Done. Programming Done. Verify OK. Flash Load finished at 01:02:34
I know that in this code, MicroLib in Keil can be enabled to solve this problem, but
① I need to use the floating-point (IEEE 754) function of sprintf, but if I use MicroLib, I cannot convert floating-point numbers to strings.
② If the error is due to memory issues, why can it compile successfully after adding a function and a shaping variable located on the stack? This can also be seen from the compiler output: the modified code occupies more space in each project than the memory in the first file.
In addition, not only the official MSPM0 evaluation board cannot be burned, but also the third-party development board based on the MSPM0G3507 main control chip that I purchased cannot be burned. Using a third-party CMSIS DAPLink debugger also fails to burn.
Additionally, I also attempted to burn the hex file generated by Keil using Uniflash, but was unable to do so. The output is as follows:
[2024/9/2 上午1:09:30] [INFO] CORTEX_M0P: GEL Output: Memory Map Initialization Complete [2024/9/2 上午1:09:31] [ERROR] CORTEX_M0P: Flash Programmer: Error in image size. Length of block is 7916, but it should be divisible by 8 since Flash Programmer writes in 64-bits [2024/9/2 上午1:09:32] [SUCCESS] Program Load completed successfully.
The following is the detailed information of Keil version:
IDE-Version: μVision V5.38.0.0 Copyright (C) 2022 ARM Ltd and ARM Germany GmbH. All rights reserved. Tool Version Numbers: Toolchain: MDK-ARM Plus Version: 5.38.0.0 Toolchain Path: C:\Keil_v5\ARM\ARMCLANG\Bin C Compiler: ArmClang.exe V6.19 Assembler: Armasm.exe V6.19 Linker/Locator: ArmLink.exe V6.19 Library Manager: ArmAr.exe V6.19 Hex Converter: FromElf.exe V6.19 CPU DLL: SARMCM3.DLL V5.38.0.0 Dialog DLL: TARMCM1.DLL V1.14.6.0 Target DLL: CMSIS_AGDI.dll V1.33.15.0 Dialog DLL: TARMCM1.DLL V1.14.6.0
Origin:
我使用题中的MSPM0评估板和Keil uV5工具进行开发时发现:当从代码中删除特定函数调用后,虽然程序可以编译通过,但无法烧录(下载)进微控制器。即使这段被删除的代码不可能被执行(比如第二段代码中所示的方法),但只要这段代码被编译进二进制文件,就能烧录成功。在不断尝试后发现使用下面这两段代码可以稳定复现这一问题:
首先说明:下面这两段代码是从我的项目中提取出来的,没有实际意义,但足以复现题中提到的这一Bug。
使用最新的Keil uV5 ARM(版本在最后),打开mspm0 SDK例子中的empty工程,在我的SDK安装中位于C:\ti\mspm0_sdk_2_01_00_03\examples\nortos\LP_MSPM0G3507\driverlib\empty. 将其中main.c的代码替换为:
#include "ti_msp_dl_config.h" #include "stdio.h" int main(void) { SYSCFG_DL_init(); char str[50]; sprintf(str, "%.3f", 12.345f); while (1) { } }
(受篇幅限制,版权信息已省略)
下面是报错详细信息:
Rebuild started: Project: empty_LP_MSPM0G3507_nortos_keil *** Using Compiler 'V6.19', folder: 'C:\Keil_v5\ARM\ARMCLANG\Bin' Rebuild target 'empty_LP_MSPM0G3507_nortos_keil' Before Build - User command #1: cmd.exe /C "C:\ti\mspm0_sdk_2_01_00_03\examples\nortos\LP_MSPM0G3507\driverlib\empty\keil\../../../../../../tools/keil/syscfg.bat 'C:\ti\mspm0_sdk_2_01_00_03\examples\nortos\LP_MSPM0G3507\driverlib\empty\keil\' empty.syscfg" Using Sysconfig Tool from "C:\ti\sysconfig_1.21.0\sysconfig_cli.bat" "Update the file located at <sdk path>/tools/keil/syscfg.bat to use a different version" Warning: SysConfig has been updated to use standard TI part numbers. The device MSPM0G3505 has been automatically selected. If this is not the desired please open SysConfig to change it. Running script... Validating... info: /ti/project_config/ProjectConfig deviceSpin: Note: User must select a device after migration. Generating Code (empty.syscfg)... Unchanged C:\ti\mspm0_sdk_2_01_00_03\examples\nortos\LP_MSPM0G3507\driverlib\empty\ti_msp_dl_config.c... Unchanged C:\ti\mspm0_sdk_2_01_00_03\examples\nortos\LP_MSPM0G3507\driverlib\empty\ti_msp_dl_config.h... assembling startup_mspm0g350x_uvision.s... compiling empty.c... compiling ti_msp_dl_config.c... linking... Program Size: Code=7128 RO-data=772 RW-data=0 ZI-data=352 FromELF: creating hex file... ".\Objects\empty_LP_MSPM0G3507_nortos_keil.axf" - 0 Error(s), 0 Warning(s). Build Time Elapsed: 00:00:01 Load "C:\\ti\\mspm0_sdk_2_01_00_03\\examples\\nortos\\LP_MSPM0G3507\\driverlib\\empty\\keil\\Objects\\empty_LP_MSPM0G3507_nortos_keil.axf" Info: Debug/System power-up request sent Info: executing SWD power up Info: Current state of access point is: 80427 Info: Current state of access point is: 680027 Erase Done. Programming Failed! Error: Flash Download failed - "Cortex-M0+" Flash Load finished at 00:45:36
但是,在不改动编译器设置的情况下,如果将代码替换为下面这样, 也就是添加一个函数并使其被编译进二进制文件,程序就可以正常编译与烧录(下载),虽然这个新函数只起到占位作用。代码如下所示:
#include "ti_msp_dl_config.h" #include "stdio.h" #define TIMER_CLOCK_KHz 60000 void setFrequencyKHz(int freqKHz) { int calculatedValue; if (freqKHz > 10000) return; calculatedValue = TIMER_CLOCK_KHz / freqKHz; static DL_TimerG_PWMConfig gPWM_0Config = { .pwmMode = DL_TIMER_PWM_MODE_EDGE_ALIGN, .startTimer = DL_TIMER_START, }; gPWM_0Config.period = calculatedValue; DL_TimerG_initPWMMode( TIMG12, (DL_TimerG_PWMConfig *)&gPWM_0Config); DL_TimerG_setCaptureCompareValue(TIMG12, calculatedValue / 2, DL_TIMER_CC_0_INDEX); } int main(void) { SYSCFG_DL_init(); char str[50]; sprintf(str, "%.3f", 12.345f); int i = 0; switch (i) { case -1: setFrequencyKHz(123); } while (1) { } }
这是编译烧录的输出:
Rebuild started: Project: empty_LP_MSPM0G3507_nortos_keil *** Using Compiler 'V6.19', folder: 'C:\Keil_v5\ARM\ARMCLANG\Bin' Rebuild target 'empty_LP_MSPM0G3507_nortos_keil' Before Build - User command #1: cmd.exe /C "C:\ti\mspm0_sdk_2_01_00_03\examples\nortos\LP_MSPM0G3507\driverlib\empty\keil\../../../../../../tools/keil/syscfg.bat 'C:\ti\mspm0_sdk_2_01_00_03\examples\nortos\LP_MSPM0G3507\driverlib\empty\keil\' empty.syscfg" Using Sysconfig Tool from "C:\ti\sysconfig_1.21.0\sysconfig_cli.bat" "Update the file located at <sdk path>/tools/keil/syscfg.bat to use a different version" Warning: SysConfig has been updated to use standard TI part numbers. The device MSPM0G3505 has been automatically selected. If this is not the desired please open SysConfig to change it. Running script... Validating... info: /ti/project_config/ProjectConfig deviceSpin: Note: User must select a device after migration. Generating Code (empty.syscfg)... Unchanged C:\ti\mspm0_sdk_2_01_00_03\examples\nortos\LP_MSPM0G3507\driverlib\empty\ti_msp_dl_config.c... Unchanged C:\ti\mspm0_sdk_2_01_00_03\examples\nortos\LP_MSPM0G3507\driverlib\empty\ti_msp_dl_config.h... assembling startup_mspm0g350x_uvision.s... compiling empty.c... compiling ti_msp_dl_config.c... linking... Program Size: Code=7920 RO-data=788 RW-data=8 ZI-data=352 FromELF: creating hex file... ".\Objects\empty_LP_MSPM0G3507_nortos_keil.axf" - 0 Error(s), 0 Warning(s). Build Time Elapsed: 00:00:01 Load "C:\\ti\\mspm0_sdk_2_01_00_03\\examples\\nortos\\LP_MSPM0G3507\\driverlib\\empty\\keil\\Objects\\empty_LP_MSPM0G3507_nortos_keil.axf" Info: Debug/System power-up request sent Info: executing SWD power up Info: Current state of access point is: 80027 Info: Current state of access point is: 680027 Erase Done. Programming Done. Verify OK. Flash Load finished at 01:02:34
我知道在这一段代码中,可以使能Keil中的MicroLib解决这一问题,但
①我需要使用sprintf的浮点数功能,如果用MicroLib则无法实现浮点数转字符串。
②如果报错是因为内存问题,那么为什么在添加一个函数和一个位于栈区的整形变量后又能编译通过?从编译器输出也能看到这一点:修改后的代码在各个项目中占用的空间都大于第一个文件中的内存。
另外,不只是MSPM0官方的这一评估板会无法烧录,我购买的第三方基于MSPM0G3507主控芯片的开发板同样无法烧录。使用第三方CMSIS DAPLink调试器同样无法烧录。
另外,我也尝试通过Uniflash烧录Keil生成的hex文件,同样无法烧录,输出如下:
[2024/9/2 上午1:09:30] [INFO] CORTEX_M0P: GEL Output: Memory Map Initialization Complete [2024/9/2 上午1:09:31] [ERROR] CORTEX_M0P: Flash Programmer: Error in image size. Length of block is 7916, but it should be divisible by 8 since Flash Programmer writes in 64-bits [2024/9/2 上午1:09:32] [SUCCESS] Program Load completed successfully.
以下是Keil版本详细信息:
IDE-Version: μVision V5.38.0.0 Copyright (C) 2022 ARM Ltd and ARM Germany GmbH. All rights reserved. Tool Version Numbers: Toolchain: MDK-ARM Plus Version: 5.38.0.0 Toolchain Path: C:\Keil_v5\ARM\ARMCLANG\Bin C Compiler: ArmClang.exe V6.19 Assembler: Armasm.exe V6.19 Linker/Locator: ArmLink.exe V6.19 Library Manager: ArmAr.exe V6.19 Hex Converter: FromElf.exe V6.19 CPU DLL: SARMCM3.DLL V5.38.0.0 Dialog DLL: TARMCM1.DLL V1.14.6.0 Target DLL: CMSIS_AGDI.dll V1.33.15.0 Dialog DLL: TARMCM1.DLL V1.14.6.0