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, I am programming on the Cypress FX2 (8051 compatible) and I have a problem that my variables declared in a c-function do not get initializes properly. My main program is written in assembly, since I need to have an ISR, which is very short and i want to have full control over what the proc. does during that ISR. I have to include a c-file in my project, which initializes a bunch of registers for a special interface on my USB chip. The problem is that the linker does not include that data segment. my data is defined this way: const char xdata WaveData[128] = {128 bytes} do i need to write an initialization function in C, which moves all that data or is there a way for force the inclusion of that data segment? thanks, Greg ps.: sorry if i am not clear.
What would the need for a very tightly optimized ISR have to do with writing the main function in assembler? Your core problem almost certainly is that because your main function is not written in C, the C runtime startup code isn't being linked in and run. See the manual to learn about startup.a51 and the all the machinery it contains. As to your initialized block: given it's "const" already, what would be the point having it in xdata? The right choice of memory space would be "code" here, I think. For one thing, it would no longer need the startup.a51 routines to copy data to xram for you, that way.
"do i need to write an initialization function in C, which moves all that data or is there a way for force the inclusion of that data segment?" No, STARTUP.A51 and INIT.A51 contain the C runtime startup code that would normally run first. If you turn your project "inside out", you won't need to do anything special for initialization. By "inside out", I mean configure your project to be a C project with assembly modules, not an assembly project with C modules. This way all the C startup stuff should happen automatically. Have main() simply call your main assembly code when the USB initialization is done. Your main assembly code does not necessarily have to return if everything is done in that code.
In general, C run-time code is responsible for initializing initialized data before main() starts. There is no way for a linker to link a segment of pre-defined values "into RAM". The RAM will power up in an undefined state. The initial values will have to exist somewhere in your ROM, and be copied to RAM to initialize the data segment upon startup. (Similarly, uninitialized variables must be zeroed to conform to the ANSI spec.) In your case, however, you don't have a main(), and you probably aren't initializing the C run-time environment. Take a look at the lib\init.a51 code, which you would normally add to your C projects that use initialized data. You'll need to execute this or similar code in your own startup procedure before you call the C functions.
ok, I was thinking that i would have had to turn my code inside out. I was wondering if there was any other option. Thanks guys :) Greg
"given it's "const" already, what would be the point having it in xdata?" This is perfectly valid and useful: If your code space is full, but you have spare XDATA space, being able to have your constants in ROM but mapped into XDATA space is very useful indeed! The Keil tools support this with the XCONST feature: http://www.keil.com/forum/docs/thread2074.asp http://www.keil.com/forum/docs/thread2636.asp
"since I need to have an ISR, which is very short and i want to have full control over what the proc. does during that ISR." I know there are situations where one has to resort to assembler, but why don't you try writing the ISR in C and take a look at the code generated? You might be pleasantly surprised. If you aren't already familiar with it check out the 'using' keyword for specifying register banks. Stefan
Hi Greg, I'm using cypress controller too. Try this:
code char WaveData[128] = {128 bytes}