This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSPM0G3507: Keil: *Specific* code can be compiled but cannot be downloaded

Part Number: MSPM0G3507
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

  • 7875.Data.zipHere are the related Keil project and the two compile output.

  • Hi Xiaoyi,

    Actually, this should be the keil issue that it do not set the hex file into 8-bytes alignment.

    The MSPM0 Flash loader can only download the firmware to device with 8-bytes alignment firmware, so if the firmware compiled by keil not fit this, then it will show the error "CORTEX_M0P: Flash Programmer: Error in image size.".

    Actually, in the sdk project, we always set the command in sct file: ALIGNALL 8

    LR_IROM1 0x00000000 0x00080000  {    ; load region size_region
      ER_IROM1 0x00000000 ALIGNALL 8 0x00080000 {  ; load address = execution address
       *.o (RESET, +First)
       *(InRoot$$Sections)
       .ANY (+RO)
       .ANY (+XO)
      }

    And I see the proejct is used with this.

    Then I suspect that maybe using library functions which is not generated by 8-bytes alignment, will violate the 8-byte alignment rule.I think this should be keil issue, would you try with CCS and see any error?

    B.R.
    Sal

  • Hi Sal,

    Thank you for your reply! I tried on CCS Theia and it worked without any errors.

    The output file from Keil is 7916 Bytes, which cannot be divided by 8.

    But Keil is much easier for us individual developer and students to use. It supports general DAPLink, for example, which is way smaller and cheaper than XDS110. And our team can easily migrate to this chip with our familiar IDE.

    Since the program can be compiled and linked without errors by Keil's ARM toolchain, maybe we can add some NOP at the end of binary file when it not fit the 8-bytes alignment rule. Technically it could be done automatically during downloading process, I think, for the fact that there are often some junk bytes like 0xFF or 0x00 at the end of the flash. Place some padding bytes here won't affect the program.

    I hope that TI Offical could provide some kind of workaround to automatically expand the elf (and hex) when it not fits the rule.

    Looking forward to your reply.

    Xiaoyi

  • Hi Xiaoyi,

    I think, for the fact that there are often some junk bytes like 0xFF or 0x00 at the end of the flash. Place some padding bytes here won't affect the program.

    Yes, this could process. Sometimes, user often fill the hex file with 0xff to avoid alignment issue.

    We give the method in CCS tools to auto fits the rule, integrated with compiler and hex tools, I am not sure how Keils do, which using different compiler tool.

    Maybe you can check the keil compiler and assembly tools user guide to see if there has any methods.

    B.R.

    Sal