Adapt9s12XD512 non-functioning caused by function call

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Adapt9s12XD512 non-functioning caused by function call

3,643 Views
ODUIEEECarTeam
Contributor I
I wrote a function for use in my program that does nothing more than loop through an int array[683] a few times making comparisons in order to analyze sensor data. It does nothing more than test for different cases and save some integers in a global array.  It runs fine on the computer using a C compiler. It is, however, perhaps a little lengthy to post here(but i will do so in the following post).  It compiles fine in code warrior with no errors, but I get a warning: L1912: Object _vectab overlaps with another (last addr: 0xEB5F, object addr: 0xCF00)
Anyway, here is the problem:
 
When I load the function but don't call it, everything works fine, but when I call the function, the microcontroller does NOTHINGIt doesn't run any of the code before the function call, or after it, or at least not correctly, as the code does several things that can be observed (like flash an onboard LED).  I can't find any indication that the program is too big, or does anything that the microcontroller can't handle. 
 
I will try to clean up the code (lots of things commented out left in it) for the following post.
 
Why does the following function cause the microcontroller not to function at all?


Message Edited by ODU IEEE Car Team on 2008-03-26 12:46 PM
Labels (1)
0 Kudos
31 Replies

1,411 Views
J2MEJediMaster
Specialist I
The warning message indicates that something is trying to occupy the same space as your interrupt vector table. Possibly when the function runs, it smashes the vector table in short order, and then everything stops working. Things to check:

1) Look closely at the map files geneated by the linker and see where the overlap is. Move the offending function if possible.
2) Non-banked memory is limited. Does your function really have to be there? Can it go into another memory bank?

---Tom
0 Kudos

1,411 Views
ODUIEEECarTeam
Contributor I
I thought I didn't much have to worry about memory since i have :Memory
– 512K byte Flash EEPROM
– 4K byte EEPROM
– 32K byte RAM

Anyway, I know I can make the program more efficient, but my whole program is still going to get bigger. 
I changed #pragma CODE_SEG __NEAR_SEG NON_BANKED
to #pragma CODE_SEG __NEAR_SEG BANKED
on several of my large functions. and this gets rid of the warning. However, the problem is the same. the program does nothing.  No warnings (other than the usual possible loss of data). 
I also have a #include <math.h>

Do I have to do anything special to use banked memory? What could cause this total program failure?


0 Kudos

1,411 Views
allawtterb
Contributor IV


ODU IEEE Car Team wrote:
I thought I didn't much have to worry about memory since i have :Memory
– 512K byte Flash EEPROM
– 4K byte EEPROM
– 32K byte RAM

While you do have a fair amount of ROM, the amount of non-banked ROM you have is still restricted(~32K).
 
Did you fix the problems noted by Jim and change the size allocated for your stack? 
0 Kudos

1,411 Views
ODUIEEECarTeam
Contributor I
I got rid of the initialization of the arrays. it was not necesary.  as for one problem about assigning 683 values to an array of size 10, that is not a problem because this has been tested and that case only ever happens about 6 times. I increased the size anyway though.
 I changed several functions to banked memory and that eliminated the warnings, but not the problem, what is the practical difference between using banked vs. non-banked?
is there any other code necessary to use banked?

How do you change the size of your stack?


Message Edited by ODU IEEE Car Team on 2008-03-26 09:43 PM
0 Kudos

1,411 Views
allawtterb
Contributor IV
You need to change the value of STACKSIZE in your prm file to change the value of your stack. You will have to set the size of the stack depending on the size of local variables used in other functions and which functions call which other functions. 
 
There were 2 pieces of code that could have been problems, I think you are referring to the second one.  Jim pointed out above the one that needs fixed for sure.
 
 
 - Brett
0 Kudos

1,411 Views
ODUIEEECarTeam
Contributor I
both of those problems are fixed and the stack size is set to 4K, and the problem remains. It won't even flash an LED still.  It doesn't run even when i comment out the function call now that i changed 3 large functions to banked. I get no errors. no warnings.

I now have 3 functions like this:
#pragma CODE_SEG __NEAR_SEG BANKED
void SetParameters(){...very large function...}

Is this right? i can still just call the function with "SetParameters();" right?
this eliminates the errors, but nothing works still. 




Message Edited by ODU IEEE Car Team on 2008-03-26 10:22 PM
0 Kudos

1,411 Views
CompilerGuru
NXP Employee
NXP Employee
>#pragma CODE_SEG __NEAR_SEG BANKED
That does look suspicios.
The __NEAR_SEG basically says the function is reachable in a non banked area. Using this together with a section named BANKED looks suspect, if you use the banked memory model (I guess so) do not explicitely use the __NEAR_SEG qualifier unless that code is really ending up non banked.
(or very advanced: is really only called from the same page, but I would not start with such optimizations).
Daniel
0 Kudos

1,411 Views
J2MEJediMaster
Specialist I

In the CodeWarrior directory, go to the (CodeWarrior Examples) directory and study and the example code in the BankedData, GlobalAddressing, and StringTable directories. In particular, StringTable shows how to allocate string literals in Flash.

Also, you may want to study the memory map for your MCU in the attached PDF.

---Tom

 

 

9S12XDFAMPP.pdf

Message Edited by t.dowe on 2009-08-31 05:12 PM
0 Kudos

1,411 Views
ODUIEEECarTeam
Contributor I
After commenting out lines of code one at a time, I found that the overlap begins exactly when my code goes over 12K.  What is special about 12K?  I don't see anything that specifies a 12K limit on anything.  The only relation I can make is that this is also when my main.c+isrvectors.c+startup code equals very close to 4K (3757+255+52=4064), which is the size of my EEPROM, but I didn't think this mattered because I have 512K flash, and can use up to 32k without having to deal with memory locations right?
0 Kudos

1,411 Views
JimDon
Senior Contributor III
I believe there is 12K of non paged ram on this device.
Post your PRM file, perhaps you are placing the code in ram???

I know if you were using DBG-12 this would be the case.
0 Kudos

1,411 Views
ODUIEEECarTeam
Contributor I
Here is my prm.  The only thing I changed from the generated one in this file is the STACKSIZE.
0 Kudos

1,411 Views
JimDon
Senior Contributor III
Since you are using special edition I would NOT use banked, as you have 32k of flash available without using banked memory. Banked memory only adds complications to debugging and other issues, and since it will do you no good, I  don't see any point to it. You will have enough problems with the banked issue.

I would create a new project using small model and add the code files to it.

I would use 0x8000 and 0xC000 un-banked as my 32K. Although 0x8000 is the paging window it can be used as regular un-banked flash if the paging register is left alone. This gives you 32k of contiguous memory.

My next question is why are you using the simulator and not the actual part?

0 Kudos

1,411 Views
ODUIEEECarTeam
Contributor I
Well, I only decided what to use based on what was in some other source code.  Also, banked was in between small and large so it seemed like a reasonable choice.  As for:

     "My next question is why are you using the simulator and not the actual part?"

I'm not sure what you mean. I am using the actual part.  I have been feeding data into the terminal in order to test it.  Would using small give me 32K for my code? or my code and data combined? (I'm guessing the former)
Do I still use the line "#pragma CODE_SEG __NEAR_SEG NON_BANKED"?
Or do I have to use a different one.  Where can I find the different things I can put here?
0 Kudos

1,411 Views
JimDon
Senior Contributor III
I don't have a "X" series board, so I am not familar with how ram is accessed when it is far.
I suppose you can use pragmas to put your ram data in far and your code in near or unbanked.
If you don't need more that 12K of ram than this is not an issue.
(this "X" series is begining to smell like and intel 286)...

My understanding is that the limit only applies to code and not ram data.
I think the reason you get that error is the line

 INTO  ROM_C000/*, ROM_4000*/;

It is tring to put all your code and the vectors into one page.
Try this:
 INTO  ROM_4000,  ROM_C000;

and see if that fixes the error.
You could also try to add this to the segments section:
   ROM_8000      = READ_ONLY     0x8000 TO   0xBFFF;

and then try this:
INTO  ROM_8000,  ROM_C000;
So that your 32k is continous, as functions can not break across non contigious boundries.

The reason I asked about the simulator, is that all your files have Full_Chip_Simulation in the name, which suggests you generated the project for full chip simulation not the BDM you are using. Usually this is not an issue, but sometimes it is.
Others who are familar with far ram usage can help you there, but this sould get your code to build for now.



Message Edited by JimDon on 2008-03-30 04:34 PM
0 Kudos

1,411 Views
CompilerGuru
NXP Employee
NXP Employee
I would not recommend to use the ROM_8000 section as using this as non banked means to that the remaining flash cannot be used for code anymore.
Especially if you are not familiar with the architecture, use
ROM_4000 and ROM_C000 first.
The first thing to decide is if this project is going to use more than 32/48k of the flash ever.
If this wont ever happen, using the small memory model (create a new project to see the setup), add -OnB=b (read the comment in the prm file) uncomment the reference to
ROM_4000 in the prm.
I would instead of this small memory model approach use the banked memory model, and only place all interrupt functions into
the
NON_BANKED section. Keep all other code banked.
E.g.:

#pragma CODE_SEG __NEAR_SEG NON_BANKED

... interrupt handler definition....

#pragma CODE_SEG DEFAULT

.. all other code here.

Do not use __NEAR_SEG if you do not place that section non banked, or said it the other way round, do not use __NEAR_SEG except for NON_BANKED.

Daniel

BTW: The file sizes of the map files and of the elf files are of little value only. The file sizes of the srecords are a bit more then double of the size of the flash used, but they do not reflect the RAM at all, and they do not tell anything about which part of the flash is used for what, and that appears to be the problem. Please have a look at the map file (it is text...) and copy parts of that file to give us an insight of your setup.

0 Kudos

1,411 Views
JimDon
Senior Contributor III
He will never go over 32K he is using special edition.
The PPAGE register should never be changed.
While it might work out that 4000/C000 is ok, if per chance a large function falls on the page boundary  could cause losing some amount of that 32K, which is why is suggested the 8000/C000 arrangement. If he can truly use not banked memory would this not be better?

Is the linker smart enough to try and fit other code into the possible hole?

Please explain why he should used banked instead of small, keeping in mind he can not use more that 32K on code space. Can you not still access banked ram from small model?

If none of his code is in paged memory, then hes should use _NEAR_SEG for all his code. Yes?
I am trying to eliminate all banked issues for him, as more than 32K is not an option anyway.




0 Kudos

1,411 Views
CompilerGuru
NXP Employee
NXP Employee
> He will never go over 32K he is using special edition.

The special edition today has a limit of 32k C code, correct. Going over 32k flash is still possible, for example with another license in the future, with assembly code or even just with a lot of C constants/strings.
For now, it appears though that 32k are enough, so I would really use the 4000 and C000 area.
When using a device with 512k I do recommend to use the banked memory model (even for users of the special edition). The banked calling convention is not much more expensive, and the used edition can change over time, just as the supported code size limitation can change.
Also note that the default prm only uses 16k of the unpaged memory with a comment how to use the rest. There is no such limit for the banked code.

> The PPAGE register should never be changed.
It gets automatically changed when using certain features, far calls, far data access. So never changing it means to understand what all must not be done. Using the 0x8000 is just more dangerous than using the 0x4000 area, and it rules out to use the 80% of the chip for code.

>While it might work out that 4000/C000 is ok, if per chance a large
>function falls on the page boundary  could cause losing some amount
> of that 32K, which is why is suggested the 8000/C000 arrangement.
> If he can truly use not banked memory would this not be better?

If the prm file lists two 16k blocks, then the linker will not allocate anything across the boundary, regardless if the two areas are together or not.
Also there is an option to fill the gaps generated, but its not default and I doubt that those gaps are any real problem anyway.

Using the 0x4000 and 0xC000 for unpaged is the simple and safe general setup. Using the 0x8000 area for unpaged is an advanced optimization I would not recommend using unless the programmer really understand all the possible problems this introduces.
Just as note, I wonder if it should not actually be
>   ROM_FE8000  = READ_ONLY  0xFE8000 TO 0xFEBFFF;
Using
>   ROM_8000  = READ_ONLY  0x8000 TO 0xBFFF;

implies PPAGE == 0, which is legal in the architecture, but of course not what was intended.
So while normally placing code with the far calling convention into non paged code will work fine, I would guess it actually fails for the READ_ONLY  0x8000 TO 0xBFFF area (not sure, I did not try it out).
Using non banked code there should work, I guess.

>If none of his code is in paged memory, then hes should use >__NEAR_SEG for all his code. Yes?

Using explicitly __NEAR_SEG in the small memory model does not change much as it is default. Using it in banked changes the calling convention so non __near qualified function pointers wont work when pointing to a function allocated in that section.
Not mentioning the __NEAR_SEG causes that some code gets not as efficient as possible in the banked memory model when the code is really allocated non banked, but this is optimization. Is you are not aware of how this all works, do not use __NEAR_SEG.
Given the
> #pragma CODE_SEG __NEAR_SEG BANKED
in a previous post, this shows how incorrectly added __NEAR_SEG's do cause troubles, hence the recommendation not to use __NEAR_SEG unless it is consciously.


Daniel
0 Kudos

1,411 Views
JimDon
Senior Contributor III
If it is true that using 8000 does not prevent holes, then
INTO  ROM_4000,  ROM_C000;
is your best choice. with the PRM set like this, you will get error like you have been getting if you exceed 32K of code.
If you needed a large ROM table, which would not count against your 32K (I think, is this true) you could used banked ROM with the banked model. Tables in ROM can not break across a page, notr can arrays in RAM

So, stick with banked, but be aware of these issues.

0 Kudos

1,411 Views
ODUIEEECarTeam
Contributor I
I have several arrays defined globally with no #pragma statements and I need to access them from most of my functions.  They are int arrays of size either 1366 or 683.  If I use the banked model and I use DEFAULT, instead of NEAR_SEG NON_BANKED, will there be any issues with accessing them?  do I need to define where these go? can they be accessed from both my interrupts in NEAR_SEG NON_BANKED, and my other code in DEFAULT? can functions in each of these access each other?

 we are getting some weird behavior now like the program is only running correctly sometimes. we hit reset and maybe it will run maybe it won't, hit reset again, who knows... 
0 Kudos

1,411 Views
CompilerGuru
NXP Employee
NXP Employee
???

Any special reason you ask those questions?
Basically both the small and the banked memory model behave the same as far as accessing variables in RAM is concerned, just as code in NON_BANKED.

Note that the #pragma CODE_SEG wont affect the allocation of data at all, it only applies to code (and not to constants (#pragma CONST_SEG), variables (#pragma DATA_SEG) or string literals (#pragma STRING_SEG).
The only thing you have to especially place in the banked memory model are interroupt routines, those have to be placed in a section allocated non banked (e.g. into a #pragma CODE_SEG __NEAR_SEG NON_BANKED area).

Daniel

0 Kudos