Frequently Asked Questions
- How must I start using the Simulated I/O functionality in CrossView Pro for watching my program's output and feeding my program's input before any hardware is in place?
- I have defined a bit variable using the _atbit() attribute. When I declare this bit as an external variable in a different module, the linker complains about an unresolved reference. Why?
- I have a piece of conditional code in my application for which the compiler generates no code at all! I also have a piece of conditional code that is executed unconditionally. Why?
- What is the difference between the const and _romC-language keywords?
- I have defined two overlayable sections in assembly language, but the locator does not overlay them. The mapfile shows two adjacent sections. What did I forget?
- Is your question not listed? Contact TASKING.
How must I start using the Simulated I/O functionality in CrossView Pro for watching my program's output and feeding my program's input before any hardware is in place?
Simulated I/O support has been included in the runtime libraries (module _simio.c) and is enabled by default in the I/O library routines. The default I/O streams as defined in header file stdio.h are mapped to stream numbers as follows:
| C streams | direction | CrossView stream# |
|---|---|---|
| stdin | input | stream 0 |
| stdout | output | stream 1 |
| stderr | output | stream 2 |
The only thing you have to do in CrossView is to activate the I/O stream numbers which are used by your application. Open the Simulated I/O Setup dialog window by selecting menu Debug > Simulated I/O Setup:

For each I/O stream you can set the direction, the format, and whether it should be associated to a file or to a CrossView window. Click the 'Activate' button to enable the selected stream. By default, all I/O streams will be associated to a CrossView window, and the directions are correct for supporting stdin, stdout and stderr. When you are ready activating streams, click OK to leave the dialogue. When debugging your application, I/O windows will automatically pop up when your application writes or reads data from a stream which has been activated in CrossView.
I have defined a bit variable using the _atbit() attribute. When I declare this bit as an external variable in a different module, the linker complains about an unresolved reference. Why?
When you define a bit-variable using the _atbit attribute, you name a bit within an existing _bitbyte or _sfrbyte variable. You do not actually allocate a bit in the XA memory space, but merely give a bit in an existing bitaddressable object its individual name. A bit definition with _atbit() is similar to a preprocessor definition using #define. The compiler will not generate an object or reference to an object for it, and the linker/locator is unaware of its existence. Hence, you cannot declare it as an external variable.
The correct way to declare an _atbit() bit in your application is to include the complete _bitbyte of _sfrbyte definition in every module where it is used, preferably in a header file.
I have a piece of conditional code in my application for which the compiler generates no code at all! I also have a piece of conditional code that is executed unconditionally. Why?
The reason is often that the compiler assumes that the test condition yields invariantly true or false at runtime. In such case, the compiler will perform optimizations by removing the condition test and the never-to-be-executed branch of code.
The compiler will generate an eternal loop here without code for testing the loop condition. This is a valid optimization, since the variable port_rdy is always zero at the test point, thus the condition is always true.
This may not be what you had in mind, since port_rdy might represent a memory-mapped peripheral register, or is a global variable that is written to by an interrupt service routine. In such case you must explicitly tell the compiler that the variable can be changed behind its back. By adding the volatile type qualifier to the variable definition/declaration, you force the compiler to actually perform the variable manipulations that you coded.
Following code will work as intended:
What is the difference between the <a href="#romconst">const and _romC-language keywords?
The type qualifier const specifies the read-only attribute for an object. The object does not necessarily have to be physically read-only and the qualifier does not explicitly determine a memory space for that object. const Is defined in the ANSI C standard, and it allows the compiler to check on illegal lvalue use.
To force an object into a specific memory space, you should use a storage specifier like _rom. It instructs the compiler to locate the object into internal/external ROM. Among the storage specifiers, _rom is special because it is te only one which implies the type qualifier const. This applies to all memory models.
When const is used instead of _rom, the constant object is allocated by default in XA code space. Other allocation schemes for strings and const objects can be selected under the Allocation tab of the EDE > Compiler Options menu. Refer to the Language Implementation chapter in the user manual for details.
I have defined two overlayable sections in assembly language, but the locator does not overlay them. The mapfile shows two adjacent sections. What did I forget?
The reason why the linker does not overlay them is probably because call tree information is missing. When not found, worst case situation is assumed and the sections will not be overlaid. If you are sure that data between both interrupt handlers is not shared you will have to add call tree (also called call graph) information will have to be specified explicitly through CALLS directives. In short it will look like this:
Due to the CALLS calls the linker concludes that INTRVAR and INTRIQ have the same root (referenced with the dummy name ROOT) and will overlay the sections involved.