support FAQ

Are functions reentrant?

Functions are not reentrant. The local variables are not placed on a stack; their address is set at compile time. If a function calls itself, or a function is being executed from both the main loop and within an interrupt, the second call to the function will use the same memory. In this case local variables will become corrupted.

ETPU_functions are reentrant, in the sense that multiple channels can dispatch the same function.

C functions called from within ETPU_functions are not reentrant.

top

Can my variables straddle resource boundaries?

In general, no. Boundaries created by the hardware or instruction set restrict how the compiler can allocate variables.

Wherever an architecture uses pages or other interrupted address spaces, there is the potential that a variable will straddle such a boundary. The risk is greatest when you specify the address of a variable in terms of another:

int one; //in one area
int two; //in another area
long three @ one; //oh oh... 

Remember the compiler does not take any special precautions for variables whose address is specified using the @ operator.

The compiler can handle most of these situations transparently. To make absolutely sure:

  1. Program using proper C data types. In the situation above, use a union to overlay the variables.

  2. Avoid using the @ operator.

  3. Check the listing file: addresses for compiler-allocated variables appear at the left of the declaration.

top

Can the compiler generate an assembly source file?

No. The compiler does not generate an intermediate assembly source file. The compiler and linker have built-in macro assembly functionality, so a separate assembly source file is not necessary. The assembly found in the listing file is actually a disassembly of the generated opcodes.

top

Division isn't working as I expect. What's wrong?

In C, both multiply and divide return numbers of the same precision as their arguments. This implies:

x = a/b;

will lose the fractional part of the division.

x = a/b * 256;

will shift the result of the integer divide 8 bits to the left but will not regain the fractional bits from the division.

x = (a * 256) / b;

Will return an accum value (for instance: for 24 bit input values, a 16.8 result) for the division, but limits a to being 8 bits shorter without loss of precision.

x = ((a/b) * 256) + (((a % b) * 256) / b);

Will return an accum type (say 16.8) for the division, but restricts the result of the division to less than 16 bits for no precision loss.

top

How can I add a #define to the linker command file in BCLIDE?

If the #define is not already present in a header file or C program module, create a new header file for it and list the file in the Include Files list. Select the Include Files tab and click Add File. In the Open dialog, choose the file and click OK.

It is also possible to specify #define values in the COMMAND= line in the Options tab in BCLIDE. This value is passed through to the compiler to use during code generation:

COMMAND= -dIDENTIFIER[=VALUE]

Please note:

  • This setting only applies to code generation during linking. Compiling C code into object files must not rely on this definition.

  • If VALUE has any embedded spaces, you must enclose it in quotes.

  • If VALUE has any embedded semicolon characters, you must enclose it in quotes.

top

How can the compiler link modules together?

In one of two ways. Byte Craft Limited supplies BClink, an optimizing linker. BClink takes a series of object files created by the compiler, and resolves references between them to create a single executable. For more information, see the product documentation.

Our products can also link modules together using Absolute Code Mode. Essentially, the compiler reads in object files when it compiles the main module. The compiler determines the libraries to read in by noting the name of each #included header file, and searching for a similarly-named .lib file. After compiling the main module, the compiler reads in each library file, in the reverse order of the #included header files.

top

How do I determine what processor state to preserve during interrupt calls?

Short answer: read the processor documentation, then compile your program and check. The processor's response to ISRs must be documented. The compiler's response will appear in the compiled code.

top

I have an application developed with an old version. Will it compile properly with the latest version?

Yes. If you have written your program according to our recommended practices in the product documentation, upgrading should be seamless. All Byte Craft Limited Code Development Systems have backward compatibility with previous language constructs.

Please note:

  • Improvements in the compiler can alter the generated code; this may impact your testing.
  • Device header files may change between versions. If you've written customized device header files, they may require some revision. Simply examine the stock headers that we ship with the product.
  • Remember to recompile your libraries when you upgrade your Code Development System product. All libraries to be linked or included into a program must be compiled with the same compiler.
top

I'm getting an "Undefined symbol(s)" error that refers to '__MUL8x8'. What's wrong?

__MUL8x8 is the name of a library routine required by the compiler. It is found in the "math library" supplied with the Code Development System. The library name is usually

processorname.lib

where processorname matches the part name or family name of the target processor.

The compiler will search for this file along its LIBRARY path.

In MPC, the compiler ships with three separate files: mpc12.lib, mpc14.lib and mpc16.lib. One of them is used depending on processor type.

top

I'm getting lots of "redeclared" error messages in my header files. What's wrong?

If you've authored your own device header file or other header file (e.g., for a library), check to see if it has standard C header protection in it.

The code looks like this:

#ifndef __HEADER_H
#define __HEADER_H 
/* Body of the header file. */ 
#endif /* __HEADER_H */

Replace HEADER_H with the filename of your header file, changing any periods for underscores.

These lines ensure that, no matter how many times a header file is #included, its declarations are only compiled once.

top

I'm having trouble declaring structs as types. The compiler refuses typedefs of long structs

There is a legacy limit in the compiler: typedefs cannot be longer than 256 characters. In most cases, this limit is never reached.

There is a completely effective workaround: using the tag facility in struct, union, and enum declarations. The tag serves as a kind of typedef: declaring a struct, union, and enum with a tag (but without a variable name) allows the tag to be used in subsequent declarations, including typedefs.

For instance:

struct tag_mystruct { int one; int two; int three; };

typedef struct tag_mystruct type_mystruct;

will allow a structure definition (or union or enum) of longer than 256 characters.

top

I'm invoking the compiler from CMD.EXE using "start", but another window appears. Why won't the compiler run?

The start command may require a "window title" on the command line before the name of the compiler executable. Invoke "help start" for the list of command line options.

top

I'm seeing a problem or error with compiler-generated code. What do I do?

First, try to determine the nature of the compiler-generated code. The compiler often puts labels in sections of code that it generates to distinguish them.

If errors appear in code generated at the end of the file, it is possibly the __DISPATCH() code that is at fault. This code is generated based on the #pragma thread directives found throughout the program; check each directive's expression and action to ensure that the symbols are declared, that the functions are defined or prototyped elsewhere, and so on.

If all else fails, contact Byte Craft Limited support.

top

I've compiled a source file, but the listing file shows no generated assembly. What's wrong?

If you chose to generate an object file (.OBJ), the compiler will not generate executable assembly code. The object file is an intermediate format, suitable for linking with BClink, or through Absolute Code Mode; in either case, code generation is always the last step. Even if you selected an executable (hex dump) format, the compiler will not generate assembly when it generates an object file.

top

The compiler isn't obeying my customized layout of memory resources and functions. What's wrong?

Make sure you're supplying all #pragma directives to BClink. BClink uses the same device configuration information during linking as the compiler does during Absolute Code Mode. BClink performs a final code generation pass over your object files, and needs this information to allocate variables and program code locations.

Either organize the directives in a header file that you can #include in the linker command file, or put the directives in the file directly. In BCLIDE, create a new header file and list it under Project|Properties, in the Include Files list under the Linker tab.

top

Two of my variables are overlapped; they occupy the same physical location in RAM. What's wrong?

The compiler has allocated two variables from two different memory spaces that happen to share the same physical locations. The declarations of these memory spaces need to be corrected.

If two named memory spaces (as declared with #pragma memory RAM) share the same or similar parameters, there's a chance that allocations could overlap. Alter the memory space declaration to avoid the overlap.

If one of the variables is not from a named memory location, it's possible that no memory remains unnamed (#pragma memory RAM directives with names occupy the entire RAM address space). In this case, use a name with the variable declaration or alter the #pragma memory RAM declarations to leave some unnamed global memory.

If the overlap is intentional, use the @ syntax in the variable declaration to place variables in the same location as other variables:

char abc;
char def @ &abc;
top

What is "Fractional Math"?

Mathematic calculations that operate between 0 and 1. It is used in numerous situations, including Fuzzy Logic and Linguistic Variables.

top