Go to Post Multiple event winners are what drive me and my friends to be better and achieve more. - Akash Rastogi [more]
Home
Go Back   Chief Delphi > Technical > Programming
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Closed Thread
Thread Tools Rate Thread Display Modes
  #1   Spotlight this post!  
Unread 26-02-2007, 11:08
Adam Y.'s Avatar
Adam Y. Adam Y. is offline
Adam Y.
no team (?????)
 
Join Date: Mar 2002
Location: Long Island
Posts: 1,979
Adam Y. is a splendid one to beholdAdam Y. is a splendid one to beholdAdam Y. is a splendid one to beholdAdam Y. is a splendid one to beholdAdam Y. is a splendid one to beholdAdam Y. is a splendid one to beholdAdam Y. is a splendid one to behold
Send a message via AIM to Adam Y.
Shadow Register Problem

I have ran into a problem that someone here might be able to answer. The problem is that I am programing a microcontroller using bit fields created in a structure. The problem comes as I am trying to modify a series of registers that only have 32-bit access. I can't read or write to these registers using a conventional bit field because otherwise the registers would be corrupted. The solution I have read makes perfect sense. You create another structure and then load up the entire 32-bit of the same register and then modify and read the bit fields from that shadow register. Unfortunately, this makes the code a lot more convoluted in in that you constantly have to be making sure that both structures are being updated as seen in the following example I have below which is only checking the a flag. Any solutions on how to make this code more readable or is this the best way to program those registers?
Edit: I know I can just write to those registers in one go but that is a step backwards in readability from where I am right now.
Code:
 while(ECanaShadow.CANMC.bit.CCR==0){ECanaShadow.CANMC.all=ECanaRegs.CANMC.all;};
}
__________________
If either a public officer or any one else saw a person attempting to cross a bridge which had been ascertained to be unsafe, and there were no time to warn him of his danger, they might seize him and turn him back without any real infringement of his liberty; for liberty consists in doing what one desires, and he does not desire to fall into the river. -Mill

Last edited by Adam Y. : 26-02-2007 at 11:13.
  #2   Spotlight this post!  
Unread 26-02-2007, 12:19
The Lucas's Avatar
The Lucas The Lucas is offline
CaMOElot, it is a silly place
AKA: My First Name is really "The" (or Brian)
FRC #0365 (The Miracle Workerz); FRC#1495 (AGR); FRC#4342 (Demon)
Team Role: Mentor
 
Join Date: Mar 2002
Rookie Year: 2001
Location: Dela-Where?
Posts: 1,564
The Lucas has a reputation beyond reputeThe Lucas has a reputation beyond reputeThe Lucas has a reputation beyond reputeThe Lucas has a reputation beyond reputeThe Lucas has a reputation beyond reputeThe Lucas has a reputation beyond reputeThe Lucas has a reputation beyond reputeThe Lucas has a reputation beyond reputeThe Lucas has a reputation beyond reputeThe Lucas has a reputation beyond reputeThe Lucas has a reputation beyond repute
Send a message via AIM to The Lucas
Re: Shadow Register Problem

Do you consider macros more or less readable than what you have?

A macro for that statement off the top of my heads is
Code:
#define writeShadow(S,R)   while((S).CANMC.bit.CCR==0){(S).CANMC.all=(R).CANMC.all;};
Then you just say:

Code:
writeShadow(ECanaShadow,ECanaRegs)
I haven't tested that, but it should be close. I assume those are the structs that are going to change from statement to statement. Anyway it is a start if you like it.
__________________
Electrical & Programming Mentor ---Team #365 "The Miracle Workerz"
Programming Mentor ---Team #4342 "Demon Robotics"
Founding Mentor --- Team #1495 Avon Grove High School
2007 CMP Chairman's Award - Thanks to all MOE members (and others) past and present who made it a reality.
Robot Inspector
"I don't think I'm ever more ''aware'' than I am right after I burn my thumb with a soldering iron"
  #3   Spotlight this post!  
Unread 26-02-2007, 12:25
Adam Y.'s Avatar
Adam Y. Adam Y. is offline
Adam Y.
no team (?????)
 
Join Date: Mar 2002
Location: Long Island
Posts: 1,979
Adam Y. is a splendid one to beholdAdam Y. is a splendid one to beholdAdam Y. is a splendid one to beholdAdam Y. is a splendid one to beholdAdam Y. is a splendid one to beholdAdam Y. is a splendid one to beholdAdam Y. is a splendid one to behold
Send a message via AIM to Adam Y.
Re: Shadow Register Problem

Quote:
Originally Posted by The Lucas View Post
Do you consider macros more or less readable than what you have?

A macro for that statement off the top of my heads is
Code:
#define writeShadow(S,R)   while((S).CANMC.bit.CCR==0){(S).CANMC.all=(R).CANMC.all;};
Then you just say:

Code:
writeShadow(ECanaShadow,ECanaRegs)
I haven't tested that, but it should be close. I assume those are the structs that are going to change from statement to statement. Anyway it is a start if you like it.
Yes. This is exactly what Im thinking off. Thank you. It's exponentially much easier to read that than having two structures whose only difference is the name.
Quote:
I haven't tested that, but it should be close. I assume those are the structs that are going to change from statement to statement. Anyway it is a start if you like it.
The two structures are going to be the same but both structures have multiple registers defined. So my macro is going to have the register defined and then the specific bit of the register.
Code:
#define writeShadow(S,R)   ECanaShadow.(S).bit.(R)
Unfortunately, its not working because the compiler is giving me an error that it's expecting a field name.
__________________
If either a public officer or any one else saw a person attempting to cross a bridge which had been ascertained to be unsafe, and there were no time to warn him of his danger, they might seize him and turn him back without any real infringement of his liberty; for liberty consists in doing what one desires, and he does not desire to fall into the river. -Mill

Last edited by Adam Y. : 26-02-2007 at 13:09.
  #4   Spotlight this post!  
Unread 26-02-2007, 14:07
Dave K.'s Avatar
Dave K. Dave K. is offline
Engineer/Mentor
FRC #0930
Team Role: Mentor
 
Join Date: Jan 2007
Rookie Year: 2005
Location: WI
Posts: 91
Dave K. is a splendid one to beholdDave K. is a splendid one to beholdDave K. is a splendid one to beholdDave K. is a splendid one to beholdDave K. is a splendid one to beholdDave K. is a splendid one to beholdDave K. is a splendid one to behold
Re: Shadow Register Problem

Quote:
Originally Posted by Adam Y. View Post
I have ran into a problem that someone here might be able to answer. The problem is that I am programing a microcontroller using bit fields created in a structure. The problem comes as I am trying to modify a series of registers that only have 32-bit access. I can't read or write to these registers using a conventional bit field because otherwise the registers would be corrupted. The solution I have read makes perfect sense. You create another structure and then load up the entire 32-bit of the same register and then modify and read the bit fields from that shadow register. Unfortunately, this makes the code a lot more convoluted in in that you constantly have to be making sure that both structures are being updated as seen in the following example I have below which is only checking the a flag. Any solutions on how to make this code more readable or is this the best way to program those registers?
Edit: I know I can just write to those registers in one go but that is a step backwards in readability from where I am right now.
Code:
 while(ECanaShadow.CANMC.bit.CCR==0){ECanaShadow.CANMC.all=ECanaRegs.CANMC.all;};
}
How a particular compiler packs bits is something which can vary from compiler to compiler. While many may allocate the bits in order, others may not, or may choose to order them differently.

I realize that some CPU vendor's header files promote this approach, and for CPU specific hardware registers, portablity isn't a big concern. Where I've seen problems like this create a mess is many years later, when you want to impliment a new compiler, from a new vendor.

That said, I'm unclear as to why you are unable to operate directly on the registers with your structures. If the compiler is generating code that utilizes bit set/clear instructions, those should be read/modify/write type of operations and should perform no differently than you manually read/modify/writing the registers as you seem to propose.

The only time I've had to 'shadow' anything is when dealing with 'write only' types of registers, and that just amounts to keeping a local variable which contains the correct data, and then when modified, gets pushed out to the hardware perhipheral... so perhaps this is the scenario you are trying to address.

As long as you are pursuing non-portable solutions, you might also look at defining a union between an unsigned long (I'm assuming your unidentified CPU considers this a 32 bit variable) and your structure. With the union, you could read the hardware register into a u32, operate on the bits within the struct, and then store the u32 back into the register.


My personal preference for working with hardware registers is to create #defines and just use bit and/or operations to modify the registers as desired. Its both portable and readable.

Code:
#define CANMC_CCR   0x1000
#define CANMC_XYZ   0x2000
// etc.

u32 ltmp;

    ltmp = hardware_register
    ltmp |= CANMC_XYZ;        // turn on XYZ
    ltmp &= ~CANMC_CCR;     // turn off CCR
    hardware_register = ltmp;

    // and you can combine bits like this, which will generate only one OR instruction rather than multiples for each bit set (or clear) action.

    ltmp |= CANMC_XYZ + CANMC_CCR
__________________
--Dave
  #5   Spotlight this post!  
Unread 26-02-2007, 15:29
Adam Y.'s Avatar
Adam Y. Adam Y. is offline
Adam Y.
no team (?????)
 
Join Date: Mar 2002
Location: Long Island
Posts: 1,979
Adam Y. is a splendid one to beholdAdam Y. is a splendid one to beholdAdam Y. is a splendid one to beholdAdam Y. is a splendid one to beholdAdam Y. is a splendid one to beholdAdam Y. is a splendid one to beholdAdam Y. is a splendid one to behold
Send a message via AIM to Adam Y.
Re: Shadow Register Problem

Quote:
That said, I'm unclear as to why you are unable to operate directly on the registers with your structures. If the compiler is generating code that utilizes bit set/clear instructions, those should be read/modify/write type of operations and should perform no differently than you manually read/modify/writing the registers as you seem to propose.
Well. Reading the manual it makes it pretty clear that if Im going to do any operations to certain registers that I either have to do it to all 32-bits or risk corrupting the register which would actually mean your example code wouldn't work unless you added a few extra zeros. Don't ask me why because its not applicable for any of their other peripherals that I have used. Only the CAN bus is like this.
Quote:
I realize that some CPU vendor's header files promote this approach, and for CPU specific hardware registers, portablity isn't a big concern. Where I've seen problems like this create a mess is many years later, when you want to impliment a new compiler, from a new vendor.
Im not too worried about this happening because there is probably only going to be one compiler for this device for as long as I live.
__________________
If either a public officer or any one else saw a person attempting to cross a bridge which had been ascertained to be unsafe, and there were no time to warn him of his danger, they might seize him and turn him back without any real infringement of his liberty; for liberty consists in doing what one desires, and he does not desire to fall into the river. -Mill
  #6   Spotlight this post!  
Unread 26-02-2007, 19:44
The Lucas's Avatar
The Lucas The Lucas is offline
CaMOElot, it is a silly place
AKA: My First Name is really "The" (or Brian)
FRC #0365 (The Miracle Workerz); FRC#1495 (AGR); FRC#4342 (Demon)
Team Role: Mentor
 
Join Date: Mar 2002
Rookie Year: 2001
Location: Dela-Where?
Posts: 1,564
The Lucas has a reputation beyond reputeThe Lucas has a reputation beyond reputeThe Lucas has a reputation beyond reputeThe Lucas has a reputation beyond reputeThe Lucas has a reputation beyond reputeThe Lucas has a reputation beyond reputeThe Lucas has a reputation beyond reputeThe Lucas has a reputation beyond reputeThe Lucas has a reputation beyond reputeThe Lucas has a reputation beyond reputeThe Lucas has a reputation beyond repute
Send a message via AIM to The Lucas
Re: Shadow Register Problem

Quote:
Originally Posted by Adam Y. View Post
Yes. This is exactly what Im thinking off. Thank you. It's exponentially much easier to read that than having two structures whose only difference is the name.

The two structures are going to be the same but both structures have multiple registers defined. So my macro is going to have the register defined and then the specific bit of the register.
Code:
#define writeShadow(S,R)   ECanaShadow.(S).bit.(R)
Unfortunately, its not working because the compiler is giving me an error that it's expecting a field name.
Macros are very literal, so try it without the ().

Code:
#define writeShadow(STRCT, BITN)   ECanaShadow.STRCT.bit.BITN
Generally you always use () since you are usually doing math with them and the () keep the order of ops correct. But in this case I think they are messing up the variable name (you might want to print out a macro to test it). Also shouldn’t there be more to your statement than
Code:
ECanaShadow.STRCT.bit.BITN
like
Code:
ECanaShadow.STRCT.bit.BITN = 
ECanaRegs.STRCT.bit.BITN
__________________
Electrical & Programming Mentor ---Team #365 "The Miracle Workerz"
Programming Mentor ---Team #4342 "Demon Robotics"
Founding Mentor --- Team #1495 Avon Grove High School
2007 CMP Chairman's Award - Thanks to all MOE members (and others) past and present who made it a reality.
Robot Inspector
"I don't think I'm ever more ''aware'' than I am right after I burn my thumb with a soldering iron"
  #7   Spotlight this post!  
Unread 27-02-2007, 00:25
Dave K.'s Avatar
Dave K. Dave K. is offline
Engineer/Mentor
FRC #0930
Team Role: Mentor
 
Join Date: Jan 2007
Rookie Year: 2005
Location: WI
Posts: 91
Dave K. is a splendid one to beholdDave K. is a splendid one to beholdDave K. is a splendid one to beholdDave K. is a splendid one to beholdDave K. is a splendid one to beholdDave K. is a splendid one to beholdDave K. is a splendid one to behold
Re: Shadow Register Problem

Quote:
Originally Posted by Adam Y. View Post
Well. Reading the manual it makes it pretty clear that if Im going to do any operations to certain registers that I either have to do it to all 32-bits or risk corrupting the register which would actually mean your example code wouldn't work unless you added a few extra zeros. Don't ask me why because its not applicable for any of their other peripherals that I have used. Only the CAN bus is like this.

Im not too worried about this happening because there is probably only going to be one compiler for this device for as long as I live.
... I just wanted you to be aware that portability issues exist.

The example code would work fine for the bit positions denoted, as there is no need to prepend zero's to a number. Certainly if you wanted to denote a bit position greater than 16, then it would be proper to add something like a 'UL' suffix to the constant.

Since you haven't mentioned which CPU this is for, and curiosity got the better of me, I used Google and turned up some example code for the TMS320 series.

TI's example code is inconsistent, some of it shows direct manipulation, others show using this shadow register workaround.

Finally, one example came clean with the following embedded comment:

Code:
/* Create a shadow register structure for the CAN control registers. This is
needed, since, only 32–bit access is allowed to these registers. 16–bit access
to these registers could potentially corrupt the register contents. This is
especially true while writing to a bit (or group of bits) among bits 16 – 31 */

struct ECAN_REGS ECanaShadow;
There's a better treatment in TI document SPRAA85A, if you aren't already aware of it.

... ok, so this is a workaround for the C compiler which may generate a 16 bit read/modify/write operation. It is an understandable optimization for the compiler, but a bit surprising that TI doesn't offer some native functionality to denote memory locations that are 32bit wide access only.

Since optimization appears to be the problem, then my examples of |= and &= would similarly be optimized and create the same problem.


In any event, this seems to work ok:

Code:
struct foo {
	unsigned bit1:1;
 	unsigned bit2:1;
	unsigned bit3:1;
	unsigned many:3;
};

struct bar {
	struct foo cat;
	struct foo dog;
};

struct bar x;
struct bar y;

#define eCANWrite(a,b,c) y=x; y.a.b=c; x=y;

void test(void) {

	eCANWrite(cat,many,1);

        // produces the same code as

	y=x;
	y.cat.many = 1;
	x=y;

}
__________________
--Dave
  #8   Spotlight this post!  
Unread 27-02-2007, 09:25
Adam Y.'s Avatar
Adam Y. Adam Y. is offline
Adam Y.
no team (?????)
 
Join Date: Mar 2002
Location: Long Island
Posts: 1,979
Adam Y. is a splendid one to beholdAdam Y. is a splendid one to beholdAdam Y. is a splendid one to beholdAdam Y. is a splendid one to beholdAdam Y. is a splendid one to beholdAdam Y. is a splendid one to beholdAdam Y. is a splendid one to behold
Send a message via AIM to Adam Y.
Re: Shadow Register Problem

Quote:
TI's example code is inconsistent, some of it shows direct manipulation, others show using this shadow register workaround.
I am sorry but I was not explicit in the fact that only certain registers need the manipulation others can just be written to directly. I am pretty sure anything from the Mailbox in the name can be modified directly. In addition to that fact their example code is not the best example because I did in fact find errors in their code for their CAN bus. To configure the pins as the CAN transmit and receive they have it being done with and without the shadow registers in two different examples which had me confused yesterday.
Quote:
... I just wanted you to be aware that portability issues exist.
I understand. The way the chip is designed though I doubt it would be easy to port the code because of how many different TI specific features it has. Also, I have never done anything like this ever in my entire life so I might just rewrite the entire code at a latter time to make it more portable.
Quote:
Since you haven't mentioned which CPU this is for, and curiosity got the better of me, I used Google and turned up some example code for the TMS320 series.
Its for the TMS320F2801 processor and that example code is probably what I have all ready on my computer.
__________________
If either a public officer or any one else saw a person attempting to cross a bridge which had been ascertained to be unsafe, and there were no time to warn him of his danger, they might seize him and turn him back without any real infringement of his liberty; for liberty consists in doing what one desires, and he does not desire to fall into the river. -Mill
Closed Thread


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Shadow of the Colossus - Absolutly Amazing Zero-Bee Chit-Chat 0 07-01-2006 13:35
pic: The Shadow Claw bradleym1559 Robot Showcase 8 27-02-2005 15:10
pic: 1241 Robot - Shadow CD47-Bot Robot Showcase 2 11-04-2004 13:16
Shadow? Jack Chit-Chat 9 03-02-2003 20:28
How to register Jeremy Roberts General Forum 0 02-10-2002 01:09


All times are GMT -5. The time now is 00:21.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi