us******@btconn ect.com wrote:
Code space (flash memory) is quite large at 64K, its the ram that's
precious, a meagre 1K. If I could clump the flags together in a single
block then the code to access them would be fairly trivial. Probably
do it as a macro something like (untested):
#define GetFlag(Flag) (FlagRam[(Flag>>3)] & (1<<(Flag&7)) ? 1 : 0
You could use macros such as that or write access functions which would
be smaller, but slower.
First, some compilers, specifically for 8051, which supports bit access,
has a separate data type for a bit variable, which the linker will
allocate for all the linked modules. The 8051 is limited to 128 bits
for direct bit access. Other compiler/linker implementations probably
don't have this level of support for bit variable allocation.
You can use bitfields within each module. It will combine all the bits
within the module into a structure that is rounded up to the next full
increment used for structs, probably 8, 16, or 32 bits.
Here's another approach to save even more space:
Write a preprocessor that will collect declarations from the files that
you will include for a specific build and generate a header file that
defines a structure containing all the bit-fields.
[ Module 1 ]
#ifdef USEGLOBALBITS
#include "globalbits .h"
#else
struct {
int:1 m1flaga;
int:1 m1flagb;
...
} m1flags;
#endif
....
/* use the bit variables */
if (m1flags.m1flag a){
m1flags.m1flagb = 0;
}
[ globalbits.h ]
/* This file is automatically generated. Do not edit. */
struct {
/* declarations from module1.c */
#define m1flags globalflags
int:1 m1flaga;
int:1 m1flagb;
/* declarations from module3.c */
#define m2flags globalflags
int:1 m3flagx;
int:1 m2flagy;
...
} globalbittype;
extern globalbittype globalflags;
The preprocessor would take as parameters the names of the modules to be
included. It would then scan those modules looking for the specific
declarations for globalflags ("#ifndef GLOBALBITS" to "#endif"), picking
out the bit declarations. It defines a single struct containing all the
bitfields. One caveat is that the bitfield names must all be unique.
The strict identifier format used above is not required, so you can use
whatever names you want.
The reason for the #ifdef is that the modules will compile on their own
if USEGLOBALBITS is not defined, but bits from separate modules will not
be combined within a single bitfield. You can use that before you have
the preprocessor working.
When you have the preprocessor working have your script or makefile run
the preprocessor, specifying the modules to be included, then compile
and link the separate code files. Viola -- minimum RAM for bit variables.
The preprocessor doesn't need to be able to do general parsing -- only
recognizing the delimiters for the sections that hold the definitions.
--
Thad