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.

MSP430F5XXX 代码分区存放的问题

Other Parts Discussed in Thread: MSP430F5438A

以MSP430F5438A为例,它的Flash大小为512KB,分为Bank A ~ D,共四个区块。
   现在有V1~V4共4个版本的代码,想要分别存放到Bank A ~ D。
   MSP430是统一编址的,Flash的地址空间为0x00005c00 ~ 0x00045bff。
   所以Bank A ~ D对应的地址空间分别为:
   0x00005c00 ~  0x00015bff
    0x00015c00 ~  0x00025bff
    0x00025c00 ~  0x00035bff
    0x00035c00 ~  0x00045bff
    我们知道,CCS在编译代码时,默认将程序空间从Bank A即0x00005c00 地址开始存放。
   对于V1~V4的四个版本的代码,V1可以通过编译直接放到默认的Bank A区间。
   但是V2~V4三个版本,有什么好的方案,将程序空间分别置于Bank B ~ D区间呢?

  • 我的印象是, CCS不在乎閃存Bank, 只在乎地址是16位或20位.

    您可以指定 small code 或 large code model. 你也可以指定 small data 或 large data model.

    small 意味 Bank-A 的一部分, 0x5C00 ~ 0xFFFF.

    large 意味 Bank-A,B,C,D 全部.

  • 请楼上仔细看顶楼内容,我的意思是分别放不同版本的程序

  • 你好:

    大致思路是这样的,这里面的关键问题是中断向量里面的函数入口地址在使用不同的程序时是需要重新装载,因为中断向量的位置是固定的。

    所以分别编译四个程序,手动合成为一个.hex,自己做一个小的boot loader,比如通过按键来选择现在执行的程序是A或者C,然后将中断向量的中断服务函数入口重新装载(也可以反着映射),再将程序跳转到现在需要执行的代码的Main函数的入口。

    Regards,

    Hardy

  • 你好,

    你需要的是自行引导的bootloader.

    请参考附件文档。

  • Hi,Hardy:

         感谢你的回复。你的理解与我的意图非常吻合。

         不过在我的应用中并不需要单独的bootloader。应用规定的通信协议里就规定了如何升级程序的整个流程。

         对于Bank A~D中存放的V1~4共4个程序来说, 可以任意地升级并跳转至另一个Bank的程序中去。

         比如假设当前的程序运行在Bank B,那么可以将新的程序下载到Bank C,然后程序从Bank B跳转到Bank C中去运行

         并且程序重启后,仍然从Bank C运行。其它以此类推。

         我现在想到的大致思路是:

         1. 针对A~D四个不同Bank的程序,在编译时,分别修改CMD文件的设置,将存放code的地址分别映射为对应Bank A~D的地址

         比如对于Bank A的CMD文件中的设置为  

         FLASH                   : origin = 0x5c00, length = 0x10000

         那么对于Bank B的CMD文件中就设置为

         FLASH                   : origin = 0x15c00, length = 0x10000

         Bank C和Bank D以此类推

        2. 就如你所说的,关键问题是中断向量重载的问题。我在网上找到一份通过RAM重新分配中断向量的例程。

        思路是,在程序启动时,先将所有的中断复位程序的地址赋给从RAM最后一个地址开始的连续地址空间。

        然后设置SYSCTL寄存器,将中断向量设置为“Interrupt vectors generated with end address TOP of RAM”

        综上,只 需要编写一个程序,通过#1和#2,就可以将代码分别应用到任意Bank A ~D的区间

        我这样理解对吗?

  • 沉得太快!自己顶一下!

  • 你好!

    我觉得基本是可以实现的,但是还是需要实战试一下。

    期待你的好消息!

  • 好的 我试试先 :)

  • 我認為你的目的很容易達到. 其實這與有四個 Bank的 Flash沒有什麼直接的關係. 只要有足夠的 Flash 來容納所有的『板本』, 原則上作法都是一樣的.

    你可能忽略了兩個硬件的約束. 其一是, 0x0FFFE-0x0FFFF (Reset Vector) 只有 16-bit 而且必定指向 CPU 在 Reset 後第一個執行的指令. 其二是, 電源復原後, RAM 的內容不可預料.

  • 谢谢你的分析和回复。我大概理解了一下你的意思:

    1. 由于复位向量是16位的,所以复位后跳转的地址不能超过0x10000。
    因此,如果我将程序放到超过0x10000的地址,则复位后无法正常跳转并执行。

    如果是这样,那我是否可以再定义一个函数,比如叫ResetJump,存放在不超过0x10000的地址。
    复位后使复位向量跳转到ResetJump,在这个函数里,再根据需要,利用长跳转指令,跳转到超过
    0x10000的地址去执行。这样貌似挺复杂的,而且不知道如何具体操作。

    2. 将中断向量定义到RAM区,是在复位完成之后进行的,并且会将实际使用到的中断向量
    赋给RAM,所以应该不用担心。

    我把将中断向量重新分配到RAM的参考代码放到附件里了。

  • Luo Peng 说:
    如果是这样,那我是否可以再定义一个函数,比如叫ResetJump,存放在不超过0x10000的地址。
    复位后使复位向量跳转到ResetJump,在这个函数里,再根据需要,利用长跳转指令,跳转到超过
    0x10000的地址去执行。这样貌似挺复杂的,而且不知道如何具体操作。

    完全正確.

    /* 例如 in Assembly code:

    At address 0x0FFFE */

    Reset_Vector: Any_Flash_Below_0x0FFFE

    /* At address of Flash below 0x0FFFE */

    Any_Flash_Below_0xFFFE: BRA #Any_Other_Flash

     

    /* Starting at any other Flash */

    Any_Other_Flash: /*真正有用的程式的起始…*/

    Luo Peng 说:
    我把将中断向量重新分配到RAM的参考代码放到附件里了。

    可行. 如此你每一個『板本』都可以擁有它自己一套的中斷向量.

  •     有你的回复,我就有信心多了。等编程器到手后,就赶紧实验一下。

        感谢大家的热心帮助啊!