Part Number:TMS320F28388DOther Parts Discussed in Thread:C2000WARE
大家好,
我最近想要通过基于UDP的TFTP协议来实现28388D的在线固件功能,有几个问题想请教一下:
1、CPU1能实现Ethernet通信吗?
2、在CPU1不同的flash扇区烧写了两个工程的代码,如果想要从这个工程的main函数跳转到另一个工程main需要哪些汇编指令?
3、flash能使用地址指针来存储一些数据吗?
4、在28377D的flash API函数中有读取flash这个功能,28388D发现已经去掉了,想请问用户如何手动编写读取flash函数?
Ben Qin:
你好,
1.只能在CM中实现
2. 参考下下面这篇帖子:
https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/903277/tms320f280049-asking-for-best-practice-to-jump-between-secondary-boot-loader-and-app
3. 可以的
4. 可以参考C2000ware中flashAPI例程:
C:\ti\c2000\C2000Ware_5_01_00_00\libraries\flash_api\f2838x
,
MTFT:
Ben Qin 说:
可以参考C2000ware中flashAPI例程:
C:\ti\c2000\C2000Ware_5_01_00_00\libraries\flash_api\f2838x
你好,2838x的api中已经删除了读取Flash的函数,我想问是否能像读取RAM一样通过地址读取Flash的数据。
,
Ben Qin:
应该是可以的。
,
MTFT:
你好,我像RAM一样使用flash的时候好像是不能直接写入数据,我首先是将一个数组指定在flash的某个扇区上,然后直接对这个数组进行读写操作,这样好像是不可行的,如果flash能像RAM一样读写数据,那flash的烧写操作又是如何执行的呢?
,
Ben Qin:
可以使用CODE_SECTION指令将数组存储在特定的flash地址,然后可以读取这个变量,但是不能改变它的值。要改变它的值的话只能是重新烧写程序。
,
MTFT:
好的,我尝试一下
,
Ben Qin:
好的
,
MTFT:
你好,关于第2点两个工程程序跳转问题,我简单的写了一些代码,通过led灯来观察跳转情况。
第一个工程cpu1_main代码:
#include "cpu1_board.h"uint32_t testCnt = 0; uint32_t jumpCnt = 0;/*** main.c*/ uint32_t main(void) {//// Initialize device clock and peripherals//Device_init();//// init interrupt and vectorTable, drivelib.//Interrupt_initModule();Interrupt_initVectorTable();//// SYSCFG//Board_init();//// Enable Global Interrupt (INTM) and realtime interrupt (DBGM)//EINT;ERTM;// return 0;while(1){testCnt++;if(testCnt >= 5000000){GPIO_togglePin(mGPIO_PIN_LED4);testCnt = 0;jumpCnt++;}if(jumpCnt >= 10){jumpCnt = 0;asm("LB 0x088000");}} }第二个工程代码和上面类似:
跳转地址改为asm(" LB 0x080000");
第一个工程的cmd文件:
/* BEGIN is used for the "boot to Flash" bootloader mode */
BEGIN : origin = 0x080000, length = 0x000002
/* Flash sectors */
FLASH0 : origin = 0x080002, length = 0x001FFE /* on-chip Flash */
第二个工程cmd文件:
BEGIN : origin = 0x088000, length = 0x000002
FLASH4 : origin = 0x088002, length = 0x007FFE /* on-chip Flash */
第一个工程设置擦除烧写扇区范围是Flash0-Flash3
第二个工程设置擦除烧写扇区范围是Flash4-Flash8
通过led观察运行情况是第一个工程能正常跳转到第二个工程,但第二个工程跳回第一个工程时发现不会再进入while循环的if语句里了。
Debug调试观察变量testCnt的值和变量jumpCnt都是很大的一个值,且不再变化。
,
Ben Qin:
是多大的值呢?如果满足if语句的条件应该是可以进入if语句的。
,
MTFT:
比if语句判断的值要大,而且在if语句里打断点,一直都没有执行进去,也就没法执行地址跳转指令asm(" LB 0x088000");
,
Ben Qin:
如果在while循环中将其初始化能否成功进入if语句?
,
MTFT:
问题已经解决了,是我在第二个工程配置了RAM做为CLA Program跳到第一个工程时就用不了了,所以我有疑问在第二个工程进行了RAM配置再跳到第一个工程时,是会保留第二个工程的配置吗?
,
Ben Qin:
RAM配置指的是什么?
不管怎样,从一个工程跳到另一个工程,都要跳到程序开始的位置,也就是说,程序会重新开始运行的。
,
MTFT:
Ben Qin 说:RAM配置指的是什么?
在第二个工程执行初进行了RAM的一些配置,代码如下:
//// Configure LSRAMs//MemCfg_setLSRAMControllerSel(MEMCFG_SECT_LS0, MEMCFG_LSRAMCONTROLLER_CPU_ONLY);MemCfg_setLSRAMControllerSel(MEMCFG_SECT_LS1, MEMCFG_LSRAMCONTROLLER_CPU_ONLY);MemCfg_setLSRAMControllerSel(MEMCFG_SECT_LS2, MEMCFG_LSRAMCONTROLLER_CPU_ONLY);MemCfg_setLSRAMControllerSel(MEMCFG_SECT_LS3, MEMCFG_LSRAMCONTROLLER_CPU_CLA1);MemCfg_setCLAMemType(MEMCFG_SECT_LS3, MEMCFG_CLA_MEM_DATA);MemCfg_setLSRAMControllerSel(MEMCFG_SECT_LS4, MEMCFG_LSRAMCONTROLLER_CPU_CLA1);MemCfg_setCLAMemType(MEMCFG_SECT_LS4, MEMCFG_CLA_MEM_PROGRAM);MemCfg_setLSRAMControllerSel(MEMCFG_SECT_LS5, MEMCFG_LSRAMCONTROLLER_CPU_CLA1);MemCfg_setCLAMemType(MEMCFG_SECT_LS5, MEMCFG_CLA_MEM_PROGRAM);MemCfg_setLSRAMControllerSel(MEMCFG_SECT_LS6, MEMCFG_LSRAMCONTROLLER_CPU_CLA1);MemCfg_setCLAMemType(MEMCFG_SECT_LS6, MEMCFG_CLA_MEM_PROGRAM);MemCfg_setLSRAMControllerSel(MEMCFG_SECT_LS7, MEMCFG_LSRAMCONTROLLER_CPU_CLA1);MemCfg_setCLAMemType(MEMCFG_SECT_LS7, MEMCFG_CLA_MEM_PROGRAM);在第一个工程中的.data段指定在RAMLS5上了,然后将RAMLS5改为RAMLS2就没有问题了,两个工程间能来回跳转了。
而且我有一个疑问,从一个工程跳转至另一个工程时,原工程存储在RAM的变量会在另一个工程上保留吗?也就是两个工程在RAM区的变量地址是否会被相互覆盖。
,
MTFT:
另外我还有一个问题:
我想在上电时首先执行第二个工程的代码然后再跳转至第二个工程的代码,而上电初始化时会先从第一个工程的BEGIN执行,请问我应该在f2838x_codestartbranch.asm文件中如何进行修改,才能在执行完第一个工程的_c_init0时跳转至第二个工程的BEGIN位置去执行。
我参考例程flash_kernel_c28x_cm_ex1_c28x1工程里的f2838x_codestartbranch.asm文件进行下面修改:
*********************************************************************** * Function: wd_disable * * Description: Disables the watchdog timer ***********************************************************************.if WD_DISABLE == 1.text wd_disable:SETC OBJMODE;Set OBJMODE for 28x object codeEALLOW;Enable EALLOW protected register accessMOVZ DP, #7029h>>6;Set data page for WDCR registerMOV @7029h, #0068h;Set WDDIS bit in WDCR to disable WDEDIS;Disable EALLOW protected register access;LB _c_int00;Branch to start of boot._asm in RTS libraryLB 0x080000; Cleanup and exit.At this point the EntryAddr ; is located in the ACC registerBF_ExitBoot,UNC.endif;end wd_disable只是更改了第16行的代码,将main替换成第二个工程BEGIN的位置,编译时会出现以下错误:
error #10471-D: Ignoring empty output section ".cinit" in memory range FLASH3; objects in CRC range must be non-empty.
第一个工程部分cmd文件如下:
SECTIONS {codestart: > BEGIN, ALIGN(8).text: >> FLASH1 | FLASH2 | FLASH3, ALIGN(8).cinit: > FLASH3, ALIGN(8).switch: > FLASH1, ALIGN(8).reset: > RESET, TYPE = DSECT /* not used, */.stack: > RAMM1#if defined(__TI_EABI__).init_array: > FLASH1, ALIGN(8).bss: > RAMLS2.bss:output: > RAMLS3.bss:cio: > RAMLS2.data: > RAMLS2.sysmem: > RAMLS2/* Initalized sections go in Flash */.const: > FLASH3, ALIGN(8) #else.pinit: > FLASH1, ALIGN(8).ebss: > RAMLS2.esysmem: > RAMLS2.cio: > RAMLS2/* Initalized sections go in Flash */.econst: >> FLASH2 | FLASH3, ALIGN(8) #endif
,
MTFT:
Ben Qin 说:可以使用CODE_SECTION指令将数组存储在特定的flash地址,然后可以读取这个变量,但是不能改变它的值。要改变它的值的话只能是重新烧写程序。
CODE_SECTION只能用在函数上吧?DATA_SECTION才是用于变量?
,
Ben Qin:
MTFT 说:原工程存储在RAM的变量会在另一个工程上保留吗?也就是两个工程在RAM区的变量地址是否会被相互覆盖。
这里并没有掉电,所以RAM中的数据应该是会保留的。
MTFT 说:CODE_SECTION只能用在函数上吧?DATA_SECTION才是用于变量?
是的。我的描述出错了。
MTFT 说:我想在上电时首先执行第二个工程的代码然后再跳转至第二个工程的代码,而上电初始化时会先从第一个工程的BEGIN执行,请问我应该在f2838x_codestartbranch.asm文件中如何进行修改,才能在执行完第一个工程的_c_init0时跳转至第二个工程的BEGIN位置去执行。
这里你可以参考下这篇帖子:
TMS320F280025C: Properly switch between different application code – C2000 microcontrollers forum – C2000︎ microcontrollers – TI E2E support forums
,
MTFT:
你好,我这还有两个问题请教一下:
1、请问CM核实现两个应用程序的跳转应该使用哪个指令,我试了上面的asm(" LB 0x080000");CM核编译会出错,而 使用((void (*)(void))EntryAddr)();这条指令会使CM进入FaultISR中断。
2、在CPU1中,设定的Flash烧写扇区是Flash4之后,工程cmd文件部分内容:
BEGIN : origin = 0x088000, length = 0x000002
FLASH4 : origin = 0x088002, length = 0x007FFE /* on-chip Flash */
我如果想要通过FlashAPI函数烧写代码,将CCS debug生成的.hex文件直接烧写到FLASH4的起始地址中,请问我这样做是正确的吗?因为我发现.hex文件的开头内容和地址0x088000的内容并不一样,所以感到很疑惑。
,
MTFT:
关于CM应用程序跳转,我使用了_asm( "bx r0");指令,我如果想要跳转至指定的地址,但是r0寄存器的值我应该如何确定?
我在flash_kernel例程flash_kernel_c28x_cm_ex1_cm的flash_kernel_c28x_cm_ex1_sci_flash_kernel_cm.c文件看到有这个跳转函数:
void exit(uint32_t address){//// Jump to entry address//__asm("bx r0"); }r0是如何与参数address联系起来的?
当我使用这个跳转函数跳转至0x0210000时还是会进入FaultISR中断死循环。
,
Ben Qin:
MTFT 说:1、请问CM核实现两个应用程序的跳转应该使用哪个指令
参考下这篇帖子:
(+) TMS320F28386D: TMS320F28386D: How to jump from bootloader to Application in CM – C2000 microcontrollers forum – C2000︎ microcontrollers – TI E2E support forums
MTFT 说:我如果想要通过FlashAPI函数烧写代码,将CCS debug生成的.hex文件直接烧写到FLASH4的起始地址中,请问我这样做是正确的吗?因为我发现.hex文件的开头内容和地址0x088000的内容并不一样,所以感到很疑惑。
开头不一样应该是正常的,因为对于hex文件通常每一行的前几位并不是数据,数据一般在中间的位置。
,
MTFT:
Ben Qin 说:参考下这篇帖子:
我在CM使用了这个函数:
void exit(uint32_t address){ // // Jump to entry address // __asm(" bx r0");}
运行时没有起作用,直接往下运行了,而且传入参数address也没有放在r0寄存器上