Hello,
I'm creating an application which runs on Dallas 89C450 microcontroller. My application uses RTX-51 Full RTOS. The versions of the tools which are integrated into my IDE are like below:
C51 Ver: 7.50 A51 Ver: 7.10
My application used to work fine but I was having problems with my available code space. So, I decided to port my application to LX51 Advanced Linker V4.24 in order to use its code packing feature. But my application started malfunctioning after enabling code packing.
What might be going wrong? How can I solve this problem? Using code packing feature is quite important for me because it seems that it would solve my problems with available code space if it worked fine.
Please send me your opinions and advises. This is an emergency case.
Best regards...
But my application started malfunctioning after enabling code packing.
What might be going wrong?
Everything. That's the best answer possible, given the complete absence of usable detail in your post.
If you don't even bother to tell us what kind of malfunction you observed, how do you expect anyone to be able to help you fix it?
You need to adopt a methodical, structured, scientific approach to debugging: www.8052.com/.../read.phtml
This is an application which runs on a commercial device. I'm using RTX-51 as the real-time kernel to accomplish multitasking purposes. My application is comprised of tasks dedicated to special duties within the system. There are tasks like: serial handlers, display drivers, built-in test, etc.
I put each of my tasks in a seperate C-module. Normally, I used to link my application using BL51 linker. But as the size of my application grows, I needed to change my linker to LX51 in favor of its better code size optimization capabilities. When I activated "code packing" option of this optimizer, my target hardware starts not accomplishing some functionalities like built-in-test.
I use a serial line for debugging purposes. I put some string into the line at a specific location that I want to observe. It seems, after enabling this code packing option, system starts not passing some of the lines in my code which it used to pass in the past.
Does anybody know what might be going wrong? I can't understand it because I don't know exactly what this "code packing" option does. I checked out my assembler code and memory-map output listings but I couldn't observe any abnormalities.
Hopefully, I could make myself clear now. I would be glad, if you answered me as quick as possible.
Thank you. Best regards...
Frequently, this kind of a problem is caused by some kind of time-dependency the previous compilation maintained. Linker code packing, creates micro-subroutines out of identical code sections in your program. As such, some parts of your program will run slightly slower.
If your program depends on some code to execute in a certain time window, this could explain the problems with code packing.
To solve the problem, disable code packing for those sections of code. (See http://www.keil.com/support/docs/2436.htm)
Jon
Yeah, I had seen this article which you send me earlier. And I tried it in my time critical modules. But it didn't work fine. Thank you for your interest.
Any other ideas?
system starts not passing some of the lines in my code which it used to pass in the past.
Sorry, but that's still a lot too vague.
So you're doing "printf() debugging". That may not be sufficient for this kind of problem. You need considerably finer-grained control --- possibly even a full-blown emulator. Actually, with a problem like that, I'd probably try to boil it down far enough to fit in the simulator (i.e. remove all dependence on external peripherals), and try it in there.
Is it possible that I'm facing with a stack overflow problem. I couldn't find any option in IDE to detect a stack overflow failure.
I also installed latest release of uVision 3 (C51 ver 8.05 etc.) but unfortunately nothing has changed. What else would you offer?
I want to give you a more detailed information about my application. My target processor is a Dallas DS89C450 which has an on-chip 64KB program memory. It doesn't support using an external stack. Unfortunately, 256-byte data section of the microctontroller has to be used as a stack region. I'm using RTX51-Full V7.01 real-time executive for my multitasking purposes. My application is comprised of different operating system tasks devoted to special duties. Some portion of this RAM region is also used by this real-time operating system. Thus, I'm placing my local and global variables on an external RAM chip.
The available on-chip code memory is about to get full. So, I decided to change my linker to LX51 in favor of its better optimization levels and code packing option. But I started having problems with the operations of the system which has to be accomplished by the microcontroller that I mentioned.
The microcontroller is working on a device and cooperating with other two 8051-based microcontrollers located inside this device.Therefore, it doesn't seem to be able to use a full-blown ICE to trace the operation of the code in the run-time. But instead, I'm using a "printf" debugging strategy on a serial line. After enabling 9th optimization level and code packing, it seems that a line is not being executed in one of my tasks. But this line was executed before enabling LX51 and code packing. Moreover, all other lines and functions continue executing properly. After enabling 11th optimization level and code packing, abnormalities get even higher. Can this phenomenon happen due to a stack overflow? But I would expect the code to crash entirely because of a stack overflow. I would be appreciated if I could solve and learn the reason of this event that I had observed.
Thank you for your interest.
Best regards,
There is only so much code that you can cram into a 64K address space!
The higher Linker optimisations are clever, but they aren't magic - if your code is too big, then it just won't fit, I'm afraid.
I have seen the kind of symptoms you describe on a very full system - the answer was just to get rid of some excess code.
The trouble with printf debugging is that it just adds to the bloat by adding all those strings into the code space! :-(
Dont't you have JTAG access for debugging?
Can't you move some stuff onto the other processors?
After enabling 9th optimization level and code packing, it seems that a line is not being executed in one of my tasks.
That's probably a misinterpretation. The way opt 9 and higher work means that it becomes impossible to find out whether a given line of code is executed just from stepping through the C source code in a debugger. You have to look at the assembly code.
But I would expect the code to crash entirely because of a stack overflow.
That expectation means you have some serious misconceptions about how the 8051 architecture works. The 8051 stack mechanism doesn't have a solid wall it'll run into and crash.
My application used to work fine but I was having problems with my available code space
the solution is easy:
get rid of the RTOS
Erik
For Jon Ward,
You are right. I was deactivating code optimization for only one task which has a time dependency. But when I deactivated code optimization for the entire module which contains that task function, everything started working fine again. Thank you very much. It seems that linker code packing doesn't work pretty well for modules which have a time-dependency just like you claimed.
But, how can I be sure that it will not be there to catch me out next time when I made a new modification to my code?
"Thank you very much. It seems that linker code packing doesn't work pretty well for modules which have a time-dependency just like you claimed."
No - you are missing the point!
The point is that high-level programming languages (eg, 'C') give you absolutely no guarantees at all about timing. Often, they don't even guarantee that things will be done in exactly the order that you might infer from the source code.
"how can I be sure that it will not be there to catch me out next time when I made a new modification to my code?"
Never, ever do anything timing critical in 'C'!!
I'd say: For timing critical operations in C, use a timer. That's what they're for.
Andy's point is that you should never rely on the execution time of the C code itself. You can do precise timing and write your code in C, but you need a hardware timer to provide a consistent time reference.
There are many, many possible ways to generate machine code that correctly implements any given C source. It's unwise to expect the compiler and linker always to produce exactly the same output, especially when you start changing optimization options.
"Andy's point is that you should never rely on the execution time of the C code itself."
Yes, that's precisely what I meant, even though it wasn't exactly what I said!
"It's unwise to expect the compiler and linker always to produce exactly the same output..."
It's sheer folly to expect to get the same output when you switch to a completely different Linker and then change the optimisation levels, too!