STM32
直播中

李华

7年用户 1379经验值
私信 关注
[问答]

关于STM8L151G6串口升级的问题求解

目前需要做STM8L151G6的串口升级,flash工32K,boot分2K,应用程序(run_APP)占15K,升级程序(isp_APP)15K。正常情况下运行run_APP,与升级命令时通过串口接收数据并存放于isp_APP区域,接收成功后复位到boot,它将isp_APP的数据搬到run_APP中并运行。之前做过STM32和430的程序,总以为差不多,不过调试了两周多了,总是找不到问题。使用了IAR 1.41.1.boot的icf文件:
    define memory with size = 16M;
    define region tinyData = [from 0x00 to 0xFF];
    define region NearData = [from 0x0000 to 0x07FF];
    define region Eeprom = [from 0x1000 to 0x13FF];
    define region BootROM = [from 0x6000 to 0x67FF];
    define region NearFuncCode = [from 0x8000 to 0x87FF];
    define region FarFuncCode = [from 0x8000 to 0x87FF];
    define region HugeFuncCode = [from 0x8000 to 0x87FF];
run_APP的icf文件:
    define memory with size = 16M;
    define region TinyData = [from 0x00 to 0xFF];
    define region NearData = [from 0x0000 to 0x07FF];
    define region Eeprom = [from 0x1000 to 0x13FF];
    define region BootROM = [from 0x6000 to 0x67FF];
    define region NearFuncCode = [from 0x8800 to 0xC3FF];
    define region FarFuncCode = [from 0x8800 to 0xC3FF];
    define region HugeFuncCode = [from 0x8800 to 0xC3FF];


boot的main文件:
__root const long reintvec[]@".intvec"=
{      
    0x82008080,0x82008804,0x82008808,0x8200880C, //当应用程序地址不是0xB000时则要相应改掉除第一个
    0x82008810,0x82008814,0x82008818,0x8200881C, //0x82008080以外的数值
    0x82008820,0x82008824,0x82008828,0x8200882C,
    0x82008830,0x82008834,0x82008838,0x8200883C,
    0x82008840,0x82008844,0x82008848,0x8200884C,
    0x82008850,0x82008854,0x82008858,0x8200885C,
    0x82008860,0x82008864,0x82008868,0x8200886C,
    0x82008870,0x82008874,0x82008878,0x8200887C,
};

void main(void)
{
    u8 i;
    Main_Init();
    EEPROM_Read(IAPFlagAddr, StartIAPFlag,1);
    if(StartIAPFlag==0x01)       //如果存在升级标志                                    
    {
       //清空APP区的数据
        FLASH_Unlock(FLASH_MemType_Program);
        for(i=0;i

回帖(1)

gvxiaot

2024-5-9 16:40:19
关于STM8L151G6串口升级的问题,我将为您提供一个详细的解决方案。首先,我们需要了解STM8L151G6的内存布局和串口升级的基本原理。

STM8L151G6的内存布局如下:
1. Flash:32K
2. Boot:2K
3. Run_APP:15K
4. ISP_APP:15K

串口升级的基本原理是:
1. 正常情况下运行Run_APP。
2. 当接收到升级命令时,通过串口接收数据并存放到ISP_APP区域。
3. 接收成功后,复位到Boot区域。
4. Boot区域将ISP_APP的数据搬到Run_APP区域,并运行。

为了实现这个功能,您需要完成以下几个步骤:

步骤1:配置IAR编译器
确保您的IAR编译器配置正确。您提供的icf文件看起来有些问题,可能是由于缺少了一些必要的配置。以下是一个示例icf文件:

```
define memory with size = 32K;
define region TinyData = [from 0x00 to 0xFF];
define region NearData = [from 0x0000 to 0x7FFF];
define region FarData = [from 0x8000 to 0xFFFF];

define block data with alignment = 8, size = 256;
define block bss with alignment = 8, size = 256;
define block code with alignment = 16, size = 1024;

place at start of TinyData data;
place at start of TinyData bss;
place at start of code code;
```

请根据您的实际需求调整此文件。

步骤2:编写Boot区域代码
Boot区域的代码负责将ISP_APP的数据复制到Run_APP区域,并跳转到Run_APP区域执行。以下是一个示例Boot代码:

```c
#include

void main(void)
{
    // 复制ISP_APP到Run_APP
    memcpy((void *)0x8000, (void *)0x8800, 15 * 1024);

    // 跳转到Run_APP执行
    asm volatile ("mov.w #0x8000, sp");
    asm volatile ("ret");
}
```

步骤3:编写ISP_APP区域代码
ISP_APP区域的代码负责通过串口接收数据并将其存储在ISP_APP区域。以下是一个示例ISP_APP代码:

```c
#include
#include

void main(void)
{
    // 初始化串口
    // ...

    // 接收数据并存储到ISP_APP区域
    while (1)
    {
        // 接收数据
        // ...

        // 存储数据到ISP_APP区域
        memcpy((void *)0x8800, received_data, sizeof(received_data));

        // 复位到Boot区域
        asm volatile ("jmp 0x0000");
    }
}
```

步骤4:编写Run_APP区域代码
Run_APP区域的代码负责执行应用程序的主要功能。您需要确保Run_APP区域的代码可以在Flash的0x8000地址处正确执行。

请注意,这些示例代码仅供参考,您需要根据您的具体需求进行调整。希望这些信息能帮助您解决STM8L151G6串口升级的问题。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分