We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi everyone. So far I've only done some rather small 8051 projects, mostly with variants that had less than or equal to 64k memory. Now I have a project which includes fairly large amounts of code-data running on SiLabs' C8051F12x, which has 128k. Since inherently only 64k are accessible, I need to use code banking. However, once - as noted in the application notes - I include STARTUP.A51 and the L51_BANK.A51, my application throws an Module Name Not Unique Warning for C_STARTUP. In the KEIL Knowledge Base, I found the suggestion to rename C_STARTUP to C_STARTUP_MAIN to resolve the issue. I did so, but then I got a code overlap warning at 0000H to 0002H. I never had to deal with an overlap I didn't actually cause myself (manually) before, so I'm not sure how to resolve it. In the M51, I found ... C:0000H PUBLIC ?C_STARTUP_MAIN (and, further down) C:0000H LINE# 85.
I assume those are the overlapping segments, no? I'm not sure how to progress in resolving the warning, could anybody shed some light on this for me? Thanks alot! Steven
Since inherently only 64k are accessible, I need to use code banking.
I don't. I just stay within 64k. The fact that a chip has more does not force you to use code banking.
In one design I use the upper 64k as 'semi-permanent data storage' and have no banking whatsoever.
Erik
"I have a project which includes fairly large amounts of code-data running on SiLabs' C8051F12x, which has 128k. Since inherently only 64k are accessible..."
Actually, that's 64K of CODE plus 64K of XDATA.
So, the clever thing would be to take your large amounts of data out of CODE space and put them into XDATA...
Search the forum and documentation for "XDATA Banking" (a bit of a misnomer), "XCROM", and "XCONST"...
Like I wrote, I have to include a fair amount of code data, which in turn forces me to use the upper 64k. I'd prefer not to, believe me. ;)
I didn't go into whether or not it'd be feasible to merely copy stuff from the upper into lower 64k in runtime, but I have a feeling I want to avoid the overhead. Also, I have no idea how it needed to be done. So, I'd prefer sticking with the way KEIL/SiLabs suggests, which is using code banking. Surely solving this overlap must be possible?
Appreciate the input nonetheless, Erik. :)
I ran across a mention of this someplace, but the need to migrate to the extended linker caused me a little headache, I haven't used it before. I also wasn't sure this applied to the F8051F12x in the first place. Is there a FAQ about how to migrate between the ordinary and extended linker hereabouts?
Otherwise, it'd be a brilliant solution for me, thanks for the input Andy. :)
the easy way:
use the chip as if it is a 64k chip, have the semi-permanent data in the upper 64 k access them as follows:
I give you the read, figure out the erase and write
//////////////////////////////////////////////////////////// // // // FUNCTION U8 ReadFlashChar (U8 code * RFSaddr) // // read high flash // U8 ReadFlashChar (U8 code * RFSaddr) { U8 RFCintsav; U8 RFCdata; RFCintsav = SG_IE; SG_IE = 0; SG_SFRPAGE = 0; if (RFSaddr > 0x7fff) { SG_PSBANK = 0x30; } else { SG_PSBANK = 0x20; RFSaddr += 0x8000 ; } RFCdata = *RFSaddr; SG_PSBANK = 0x10 ; SG_IE = RFCintsav; return (RFCdata) ; }
"I also wasn't sure this applied to the F8051F12x in the first place."
Not having done it with that chip, I couldn't be sure either! I think I did have a quick look once, and thought it looked possible...
"Is there a FAQ about how to migrate between the ordinary and extended linker hereabouts?"
No idea. If you're using uVision, and not doing any clever tricks, I think it should be just a matter of checking the 'Use Extended Linker' box...
"use the chip as if it is a 64K chip, have the semi-permanent data in the upper 64K"
But I was talking about constants - not semi-permanents.
Constants are loaded together with the code; semi-permanents would, presumably, require runtime initialisation?
yes, it is; HOWEVER, since banking traditionally is done with external memory, you need to hunt up the 'special' SILabs banking (I have seen in a previous post - do not ask, I do not recall which - that there is such a thing in the Keil toolset.
Since I would never dream, not even in a nightmare, of killing my throughput by using banking, I do not know what it is or where it is.
"...would never dream, not even in a nightmare, of killing my throughput by using banking"
As I hinted earlier, "banking" is a bit of a misnomer in this particular case; it's simply a matter of locating the constants into XDATA rather than CODE - so they're just accessed with MOVX instead of MOVC.
There isn't any run-time switching of banks to kill your throughput (unless you do want >64K, of course...)
Erik's thread reference is 4346 and the original op was Erik Malund. That was in April 2004. The thread carried many good responses. Suggest that you follow Jon Wards suggestions.
You do not have to use LX51 unless you want to use the far extensions. However, using LX51 will probably further reduce your code size as much as the code added for bank switching. If you are diligent in code module placement, you can reduce bank switching to a minimum and make your programming life much easier by using the tools instead of fighting them. Bradford
Jon Wards suggestions about how to properly do it with code banking or the stuff below that seemed to sum up in Erik saying 'If only KEIL supported this...'?
Also, I was under the impression that the idea of putting stuff as XDATA involved making them far constants, yet you sound as if this wasn't necessary at all.
If I do it in any way that involves using the banking assemblys, the warning that my application threw (see original post) will likely still appear, I reckon. Isn't there some compiler statement I should already know which will relocate the particular code, removing the warning and making my program run happily ever after?
If I am to do it without banking, do I use the method suggested by Erik? I cannot really comment about the code quoted by him, I'd need to delve into my program to see whether it's actually doable like that in my program as it is now, but if that's the way to progress, I'm sure I'll manage.
I really only looking for the most straight forward approach to the matter, I can even live with minor performance hits in this particular case...
In any case, I wish to thank everybody for their contributions. :)
"Also, I was under the impression that the idea of putting stuff as XDATA involved making them far constants, yet you sound as if this wasn't necessary at all."
You don't need to use any 'far' modifiers just to get your constants from CODE to XDATA as I described. You also don't need XBANKING.
As I said, "banking" is a misnomer here!
Hold on a second, is that to mean I'm thinking way too complicated here and just need to change any variable declaration from code to xdata and it'll be located in the upper 64k without further ado?
"just need to change any variable declaration from code to xdata and it'll be located in the upper 64k without further ado?"
No.
If you do that, it will take runtime code to load the values into XDATA - the initialisation values will still be stored in CODE space, thus defeating the object of the exercise!
The purpose of this XCONST stuff is to stop the tools from putting constants into CODE space in the first place. It means that you end up with a HEX file that loads code into CODE-space ROM, and constants into XDATA-space ROM.
The LX51 linker has support for this built-in; I guess you could mimic it manually yourself with BL51 and, probably, some assembler and/or a tool like SRECORD...?
I see ... I think. ;p
I'll first try to look into switching to the extended linker. As I have this particular project set up in the SiLabs IDE so far (I took a past project for another F8041x variant as starting point and expanded from there), it's not so simple as ticking a button, but I'll try to migrate the project to uVision and go on there. Not sure whether I'll manage to get there today, since I have some other issues I need to spend time on - otherwise it'll have to wait til monday. Would there be anything else to be considered in order to enable the built in support you mentioned?
Anyway, thank you for your input. If anyone else can shed some light on how to relocate the startup function so it doesn't cause overlaps, this would still be appreciated, since I have a feeling I might run into this again at some time. :/