VBR Not getting set properly on MCF2110

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

VBR Not getting set properly on MCF2110

ソリューションへジャンプ
1,875件の閲覧回数
henrymcdonald
Contributor I

This is a project I've inherited.  I'm seeing an issue where the VBR doesn't appear to be getting set correctly.

My linker script contains:

MEMORY {
 vectorrom (RX) : ORIGIN = 0x00000000, LENGTH = 0x00000500
 code (RX) : ORIGIN = 0x00000500, LENGTH = 0x0001DB00
 vectorram (RWX) : ORIGIN = 0x20000000, LENGTH = 0x00000400
 userram (RWX) : ORIGIN = 0x20000400, LENGTH = 0x00003B00
}
...
___VECTOR_RAM = ADDR(.vectorram);
...

And I have verified that mcf5xxx_startup() is getting called at startup:

asm void mcf5xxx_wr_vbr(unsigned long) { /* Set VBR */
 move.l 4(SP),D0
 movec d0,VBR 
 nop
 rts 
}

void mcf5xxx_startup(void)
{
 extern __declspec(system) uint8 __DATA_ROM[];
 extern __declspec(system) uint8 __DATA_RAM[];
 extern __declspec(system) uint8 __DATA_END[];
 extern __declspec(system) uint8 __BSS_START[];
 extern __declspec(system) uint8 __BSS_END[];
 extern __declspec(system) uint32 VECTOR_TABLE[];
 extern __declspec(system) uint32 __VECTOR_RAM[];

 register uint32 n;
 register uint8 *dp, *sp;

 if (__VECTOR_RAM != VECTOR_TABLE)
 {
   for (n = 0; n < 256; n++)
     __VECTOR_RAM[n] = VECTOR_TABLE[n];
 }
 mcf5xxx_wr_vbr((uint32)__VECTOR_RAM);

// There's more stuff here, but the issue I'm trying to resolve is with the mcf5xxx_wr_vbr function
}

The problem that I'm seeing is that after mcf5xxx_wr_vbr is called, I think the VBR register is not 0x20000000 (I think the lowest 20 bits are don't-cares though).  Before mcf5xxx_wr_vbr((uint32)__VECTOR_RAM) is called, the debugger is showing register D0 as 0x00000684 and VBR as 0x20000134.  The disassembly of the function call shows that A0 is being loaded with 0x20000000, A0 is then written to D0, then the jump to the mcf5xxx_wr_vbr function is executed.  Once in mcf5xxx_wr_vbr, D0 is then overwritten when it already has what I want in it.

I'm tempted to just comment out the first line of  mcf5xxx_wr_vbr, but I'd like to understand what the issue is and why this project used to work before I started working on it.

0 件の賞賛
返信
1 解決策
1,752件の閲覧回数
TomE
Specialist II

It looks like your C code is trying to pass the parameter to the function in Register D0, but the Assembly Function expects it to be passed on the stack.

This looks like a nasty old problem which has trapped lots of people, especially those trying to run old projects with newer versions of CodeWarrior. CW changed from 7.12 in June 2009 to 7.2 in Jan 2010. They changed the ABI between those from "Stack Based" (STD_ABI) to "Register Based" (REG_ABI). Actually 7.12 and prior supported both versions (but  example assembly code used STD_ABI), but 7.2 and after only support REG_ABI, so all previous projects and all previous App Note examples don't work. And all previous libraries.

Read this one and see if it matches your problem:

https://community.nxp.com/message/401840

> I'm tempted to just comment out the first line

But you have to fix EVERY assembly function you're using, everywhere. That's just the first one that failed.

If you're using a CW prior to 7.2 then there's apparently a "declspec" you can put on the definition of the assembly function call to make callers use the stack-based ABI.

Tom

元の投稿で解決策を見る

3 返答(返信)
1,753件の閲覧回数
TomE
Specialist II

It looks like your C code is trying to pass the parameter to the function in Register D0, but the Assembly Function expects it to be passed on the stack.

This looks like a nasty old problem which has trapped lots of people, especially those trying to run old projects with newer versions of CodeWarrior. CW changed from 7.12 in June 2009 to 7.2 in Jan 2010. They changed the ABI between those from "Stack Based" (STD_ABI) to "Register Based" (REG_ABI). Actually 7.12 and prior supported both versions (but  example assembly code used STD_ABI), but 7.2 and after only support REG_ABI, so all previous projects and all previous App Note examples don't work. And all previous libraries.

Read this one and see if it matches your problem:

https://community.nxp.com/message/401840

> I'm tempted to just comment out the first line

But you have to fix EVERY assembly function you're using, everywhere. That's just the first one that failed.

If you're using a CW prior to 7.2 then there's apparently a "declspec" you can put on the definition of the assembly function call to make callers use the stack-based ABI.

Tom

1,752件の閲覧回数
henrymcdonald
Contributor I

Thank you a ton Tom.  

This is a problem with the customer not knowing which version of CodeWarrior was used to compile the code.  I don't think that there are many assembly functions in the code except for this startup code.  I'll review the source to determine if there are any others.  If so, or if I cannot feel that I have reviewed everything, I'll roll back to 7.1.  I should probably just roll back to 7.1, but I've already delivered code to the customer.  If they come back with additional changes, or quirky operation, I'll go back to using 7.1.

On that note, is there a list of compiler provided definitions somewhere that will will let me determine the version of compiler used?  For example, in all of my Microchip based projects, I add:

#if (__XC16_VERSION != 1026)
   #error This firmware has been built and tested with XC16 version 1.26, please test everything thoroughly if using another version.
#endif 

This guarantees that whoever has to maintain the project in the future can determine what compiler was used to develop the project.  If they want to change it, they can, but they do so at their own peril. 

Side note:  I opened a ticket with NXP on Wednesday of last week asking for assistance on this before I started looking at the generated assembly code.  I provided a very stripped down project that consisted of the startup code, UART initialization, UART handler, a very detailed description of the problem, the symptoms, compiler version, etc.  The response I got minutes ago was essentially, "You have to program the part before you can debug it."  It's like they don't even try.  I get it that it is probably a common mistake that people make, so it's OK that they put that in the response... but that was the entire response.  So again, I thank you heartily Tom for your response. 

0 件の賞賛
返信
1,752件の閲覧回数
TomE
Specialist II

MCF52110.

> On that note, is there a list of compiler provided definitions...

That question may be better suited to the Code Warrior Forums. I searched for keywords related to that, but couldn't find anything.

> I don't think that there are many assembly functions in the code

The only ones that have to use assembly with the Coldfire are the ones that access the CPU Special Registers. Everything else (all the I/O) is memory-mapped, so doesn't require assembly.

But you need assembly to set the Stack Pointer (if the automatic setting from the Reset Vector isn't good enough), the Vector Base Register (as you've found), RAMBAR and FLASHBAR. On other CPUs in this family (but not the MCF52110) there's also the Cache Control Registers (CACR and ACR0 and ACR1). You also need assembly to change the CPU Priority Level in the SR in order to disable and enable interrupts around critical regions. You may also need assembly if calling the "byterev" instruction if you need it to byte-swap quickly. In our case we're using the security controller in the MCF5235, and it is a little-endian module paired with a big-endian CPU, so all data in and out has to be 32-bit swapped.

> I opened a ticket with NXP on Wednesday

Tickets? That might be an NXP innovation, as I seem to remember Freescale closed their ticketing years ago. I'm not surprised with the response you got though. Look at the strange replies I got to my "Bear PIT" requests, referenced in this post. Follow the "redaction doesn't seems to implies" link. You might be amused by the last link in there ("writting, wrotten, wrutten" and "accruate"):

https://community.nxp.com/message/71442?commentID=71442#comment-71442

Tom

0 件の賞賛
返信