I am checking some terrible C source code; I haven't got any idea about how to maintain it or cooperate with it. But I found a very fundamental problem. It does NOT have a startup.asm; it has a startup.c using the powerful C extension "#pragma". So, the C runtime environment is setup by "#pragma section", "#pragma intvect", "#pragma asm". I quite worry about such a startup.c; so I contacted the FAE of our local distributor. The FAE is an experienced good engineer, but he told me that, this is not their standard way to setup C runtime environment; they definitely provided the startup.s from Day 1.
What will be the side-effect, when the C runtime environment is setup by the C extension "#pragma"?
I don't think this can be a generic question? You must specify the particular toolset!
In C51, #pragma asm means that the compiler just creates an assembler source file, and this is passed to the Assembler for translation to object.
There is nothing magic or special about this generated assembler file - it just uses the normal A51 assembler syntax.
Therefore, in principle, it's possible to write your startup code this way.
"this is not their standard way to setup C runtime environment"
Absolutely!
"What will be the side-effect"
Key side effec is that, because the 'C' source is all converted to assembler, the rest of the toolchain loses all sight of the 'C' source - it has no idea that 'C' was ever involved.
This has 2 important results:
1. The standard 'C' support cannot be automatically provided - you must do it all manually. There is plenty of documentation on this in the Knowledgebase; eg, http://www.keil.com/support/docs/1646.htm
2. You lose all 'C' source level debugging capability.
You are right to be concerned about this - you should flag it as a major risk to your boss/client!
Hi Andrew,
Many thanks for your help.
I have already reported this to my supervisor, when I got the response from the FAE.
My supervisor told me that, this amazing startup.c was provided by our client. Our client purchased a software solution from third party and deliver this solution to us.
So they definitely knew this, they just didn't understand what this means.
Based on your help, I read some more articles.
I suspect that, C runtime environment is being setup/fiddled more than once, or it is never being well setup.
Either they didn't understand, or they did understand and were trying to be "clever".
Both of these are major risks to you / your project / your company - I'm not sure which is worse!
Do you have the option to go back to the client and/or the original supplier to get an explanation?
Most likely, I would not have such an option.
Amazing and fantastic.
But I found a very fundamental problem.
To me it doesn't sound fundamental at all. As long as the environment is set up properly, it doesn't matter if it's a .s or a .c file. File extension doesn't say much about the correctness of its contents. Since you are saying that the code is terrible in other ways, I think that the startup file will be the least of your problems.
This is the most fundamental problem, but there are also other critical problems within this project.
What kind of developer would create such a startup.c solution for C runtime environment setup?
As long as the environment is set up properly, it doesn't matter if it's a .s or a .c file.
Hi Mike,
You are right.
But we already know that many global variables are reset unintentionally in some specific cases; this is one of the persistent problems of this project for my colleagues.
This startup.c makes me feel that, the whole environment can not be trusted.
are reset unintentionally in some specific cases
Once the run-time environment is successfully setup, it is setup. This is likely to be the result of a problem in the program itself.
BUT how do you know that the setup was "successful"?!
If the setup is broken, it will leave the system in a broken state - likely to cause problems in later execution.
A classic example is the many C51 posts where the setup is "broken" in that it does not correctly configure the XDATA access...
"What will be the side-effect, when the C runtime environment is setup by the C extension "#pragma"?"
probably none.
as far as the mcu is concerned, it simply executes a series of commands sent to it. what generated those commands is irrelevant.
as to the wisdom of using .c start-up files, check the cmsis document and you will see that they plan to use .c start-up files later.
no, I wouldn't lose too much sleep over that.
CMSIS applies specifically to ARM Cortex-Mx, and one of the key goals of that architecture's design was to allow "all C" coding - in particular, witout requiring assembler startup code.
The 8051 is very different!
That's why I said early on that this can't be treated (just) as a generic topic - it does depend very much on the particular toolset!
the cmsis example is to show that there is nothing wrong with using .c start-up code.
and I am not sure why that wouldn't / couldn't be extended to cover the 8051.
Yes, the Cortex really are special.
No __irq keywords for interrupt handlers.
A fixed address for storage of information of the stack, so that the processor can initialize an initial stack on its own.
C is well qualified for low-level tasks.
One thing to care about when having strict C code to initialize a processor is that this init() function don't have access to the full C RTL until it has called a init function available with the C RTL - the call we normally see either directly before our main() is called, or the last call in a normal assembler startup file in case the C RTL init function performs the call to main().
Same thing with zeroing memory and assign of initialized data.
But having the init code in C or assembler is really irrelevant to this specific thread. In this case, we are talking about assembler initialization - but assembler instructions in a C file instead of in a separate assembler file.
This is bad modularization. And potentially, there may be part of the initialization in assembler and part in C, and lots of assumptions about compiler-specific requirements.
When talking about an all-C initialization for a Cortex processor, it would normally be the compiler vendor who supplies a complete system with the required helper functionality in the CRTL, and with a sample startup.c file containing the "normal" initialization steps.
'Yes, the Cortex really are special.'
like what?
"In this case, we are talking about assembler initialization - but assembler instructions in a C file instead of in a separate assembler file."
I am not sure if that (inclusion of assembler instructions in a C file) makes a big difference. end of the day, they produce the same result.
I do see a benefit to create a separate assembler file for those assembler instructions if you have tons of them -> essentially create a .asm start-up file.
but if the amount of assembler instructions is small, it probably makes more sense to include them in a .c file.
my point is that it is hard to make an absolute statement about whether it is right (or wrong) to embed assembler instructions in a .c file. it depends on many other factors.