Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
06/06/07 12:44
Modified:
  06/06/07 12:46

Read: times


 
#140310 - I used what I called a \'cache\'
Responding to: ???'s previous message
The problem with a queue (which I did try, btw) is that the adapter sends a confirmation message to the micro upon receiving a message to be transmitted to the J1850 network. When I send messages through the adapter to the network, that message has to be handled; I do this by simply waiting for the confirmation message to be received before doing anything else. That clears the message out of the buffer and ensures that the connection to the adapter is still good simultaneously.

Unfortunately, a situation is inevitable wherein the adapter starts receiving a message from the micro, finishes receiving the message from the micro, sends a message to the micro from the J1850 network, and only then sends the confirmation message to the micro. This results in the micro waiting forever, and pretty much junks the idea of using a queue.

What I wound up using is what I called a 'cache': an array of n unsigned chars, along with round_up(n/8) bytes of flags to indicate freshness of data. My serial ISR, upon complete reception of a message from the adapter (from either the adapter or the network), stores a unique identifier for each message (I'm only dealing with a dozen or so) in the buffer. Then, in the main loop, I check for all the messages that I'm interested in.

One weakness of this approach is that if I don't check for every possible identifier, the buffer will eventually be completely filled with those identifiers, leaving no room for useful information. If the buffer is full, I suppose the oldest piece of information could be overwritten, but I've not needed to try that. Does anybody know what this structure might be called?

void setCacheFlag(unsigned char position){//takes position of bit to set, from 0 to 7
//this outlining section contains the cache code
//always sets that bit, for simplicity
unsigned char scratch=0x80;
unsigned char i=0x00;
if(position>=8){
while((position-=8)>8){
i++;
}
}
scratch>>=position;//put bit into proper position
cacheUsed[i]|=scratch;//set that bit in the used flag
}

void clearCacheFlag(unsigned char position){
unsigned char scratch=0x80;
unsigned char i=0x00;
if(position>=8){
while((position-=8)>8){
i++;
}
}
scratch>>=position;//shift bit into proper position
scratch=~scratch;//complement scratch character
cacheUsed[i]&=scratch;//clear that bit in cacheUsed
}

bit checkCacheFlag(unsigned char position){//returns state of cache flag in input position
//should this function just be folded into checkInCache and insertInCache, to remove call overhead?
//will just be called in for loop anyway; just leave in function for debugging
unsigned char scratch=0x80;
unsigned char i=0x00;
if(position>=8){
while((position-=8)>8){
i++;
}
}
scratch>>=position;
scratch&=cacheUsed[i];
return scratch!=0x00;
}

bit insertInCache(unsigned char input){//finds first unused index, sets that flag, and overwrites
//that element. Returns 1 if successful, 0 if no unused indices found
unsigned char i=0x00;
for(i=0x00; i<0x10; i++){//for every element in cache
if(!checkCacheFlag(i)){//if that element is unused
setCacheFlag(i);//mark it as used
compressedCache[i]=input;//store the information
return 1;//report success
}
}
return 0;//should only get here if was unable to report success; thus, report failure
}

unsigned char messageInCache(unsigned char input, unsigned char dontCareMask){
//returns 0x00 if no match or first matching character in cache
unsigned char i=0x00;
if(!dontCareMask){//if precise match is required,
//can do more efficient search
for(i=0x00; i<0x10; i++){
if(compressedCache[i]==input){
if(checkCacheFlag(i)){
clearCacheFlag(i);
return compressedCache[i];
}
}
}
}else{
for(i=0x00; i<0x10; i++){
if(checkCacheFlag(i)){//if that slot is used,
unsigned char scratch=input^compressedCache[i];//check for match within tolerance
scratch|=dontCareMask;
if(scratch==dontCareMask){//if matches within tolerance, then clear that slot and return matching char
clearCacheFlag(i);
return compressedCache[i];
}
}
}
}
return 0x00;
}

List of 20 messages in thread
TopicAuthorDate
Software design problem            01/01/70 00:00      
   Something like this, maybe?            01/01/70 00:00      
      Well, yes, actually...            01/01/70 00:00      
      Duhr and a question            01/01/70 00:00      
         Which ones did you look at ?            01/01/70 00:00      
         Duhr and an answer            01/01/70 00:00      
   Is it not possible to            01/01/70 00:00      
      Horses for courses            01/01/70 00:00      
         have fun            01/01/70 00:00      
   A Queue?            01/01/70 00:00      
      I used what I called a \'cache\'            01/01/70 00:00      
         Gah, code repost            01/01/70 00:00      
            you need to read it all, THEN process            01/01/70 00:00      
            Your approach is much more general...            01/01/70 00:00      
               Prioritizing?            01/01/70 00:00      
            Some suggestions Bob            01/01/70 00:00      
               Thank you, sir!            01/01/70 00:00      
                  Division / modulus not always slow            01/01/70 00:00      
         Are we making this too difficult?            01/01/70 00:00      
            I don't think so, it seems to work pretty well...            01/01/70 00:00      

Back to Subject List