| ??? 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; } |
| Topic | Author | Date |
| 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 |



