Sign in

username:

password:



Not a member?

Search Comp.Arch.Embedded



Search tips

embedded by Keywords

68HC11 | 68HC12 | 8051 | 8052 | ARM | ARM7 | Asic | AT91 | AT91RM9200 | Atmel | AVR | AVRStudio | Bootloader | CFP | CompactFlash | Cygnal | Cypress | Dataflash | DSP | eCos | EEPROM | Embedded Linux | Emulator | Endian | Ethernet | Firewire | FPGA | Freescale | GCC | GNUARM | GSM | H8 | HDLC | I2C | Infineon | Interrupts | Java | JTAG | LCD | LED | LPC2000 | MCU | Microchip | MMC | MPLAB | MSP430 | PC104 | PCB | PCI | PCMCIA | PowerPC | Rabbit | RS232 | RS485 | RTOS | SBC | SDRAM | Sensor | SPI | STK500 | UART | UML | USART | USB | Verilog | VHDL | VxWorks | Xilinx

Discussion Groups

Discussion Groups | Comp.Arch.Embedded | STR912 bitfield access to memory mapped peripherals

There are 4 messages in this thread.

You are currently looking at messages 0 to 4.

STR912 bitfield access to memory mapped peripherals - frikkiethirion - 11:17 25-07-08



Good day,
I wonder if somebody has managed to create a structured way of accessing
the memory mapped IO attached to the STR912 [ARM9] via bitfields. 

I can manipulate the members of a union that is declared in main(), bus as
soon as I make a pointer type of my union and point it to the memory bus, I
get unexpected results.

The following two posts, from 2000 and 2005, make it seem asif it is only
possible to access 4 byte values on the ARM memory architecture at a time
and that bitfield accesses won't work:
http://gcc.gnu.org/ml/gcc/2000-05/msg00776.html

http://archives.devshed.com/forums/development-94/new-volatile-keyword-changes-bitfield-access-size-from-32bit-to-132294
1.html


My test code is as follow:

main()
{
   uint32_t uwI;
   uint32_t *pwPointer;

   typedef struct
   {
      volatile uint32_t PLL_MDIV:8;   // [7:0]   PLL Pre-divider
      volatile uint32_t PLL_NDIV:8;   // [15:8]  PLL Feedback divider
      volatile uint32_t PLL_PDIV:3;   // [18:16] PLL Post-divider
      volatile uint32_t PLL_EN:1;     // [19]    PLL Enable (0=off, 1=on) 

      volatile uint32_t uwPAD:12;     // [31:20] -PADDING-
   } mySCU_PLLCONF_t;

   typedef union
   {
      volatile uint32_t        ALL;
      volatile mySCU_PLLCONF_t BITS;
   } mySCU_PLLCONF_u;
   
   mySCU_PLLCONF_u umyPLLCONF;
   volatile mySCU_PLLCONF_u *pPLLCONF;

   umyPLLCONF.BITS.PLL_MDIV = 0x80;   
   umyPLLCONF.BITS.PLL_NDIV = 0x10;   
   umyPLLCONF.BITS.PLL_PDIV = 0x2;      
   umyPLLCONF.BITS.PLL_EN   = 1;

   uwI=umyPLLCONF.ALL;
   The value in uwI is 0x000a1080, as expected.


   // ON SCU bus
   pwPointer = (uint32_t *)(AHB_NB_APB1_BASE + SCU_OFST); //5c00 2000
   pwPointer++; //increment one word, to get aligned with PLL //5c00 2004
   pPLLCONF = (mySCU_PLLCONF_u *)pwPointer;
       
   pPLLCONF->BITS.PLL_MDIV = 0x80;
   uwI=pPLLCONF->ALL;                
     //Value is 0x8080-->Both 'MDIV' and 'NDIV'altered...
   pPLLCONF->BITS.PLL_NDIV = 0x10;
   uwI=pPLLCONF->ALL;                
     //Value is 0x1010-->Both 'MDIV' and 'NDIV'altered...
}

I'm running gcc 4.3.1, compiled for target: arm-elf, with newlib. If it
will help, I could supply the detailed configure switches when I build the
toolchain and CFLAGS/LDFLAGS of my Makefile.

Any help will be much appreciated.

Regards,
Frikkie Thirion

Re: STR912 bitfield access to memory mapped peripherals - Anton Erasmus - 16:24 25-07-08

On Fri, 25 Jul 2008 10:17:33 -0500, "frikkiethirion"
<f...@zitera.co.za> wrote:

>Good day,
>I wonder if somebody has managed to create a structured way of accessing
>the memory mapped IO attached to the STR912 [ARM9] via bitfields. 
>
>I can manipulate the members of a union that is declared in main(), bus as
>soon as I make a pointer type of my union and point it to the memory bus, I
>get unexpected results.
>
>The following two posts, from 2000 and 2005, make it seem asif it is only
>possible to access 4 byte values on the ARM memory architecture at a time
>and that bitfield accesses won't work:
>http://gcc.gnu.org/ml/gcc/2000-05/msg00776.html
>
>http://archives.devshed.com/forums/development-94/new-volatile-keyword-changes-bitfield-access-size-from-32bit-to-13
22941.html
>
>
>My test code is as follow:
>
[code snipped]
>
>I'm running gcc 4.3.1, compiled for target: arm-elf, with newlib. If it
>will help, I could supply the detailed configure switches when I build the
>toolchain and CFLAGS/LDFLAGS of my Makefile.
>
>Any help will be much appreciated.

It is an extremely bad idea to use bitfields to access hardware
registers. There is absolutely no guarantee about how the actual
accesses wil be handled by the compiler.  Handle the bits by
reading/writing the register with required size, and mask the bits
as required.

Regards
  Anton Erasmus



Re: STR912 bitfield access to memory mapped peripherals - Robert Adsett - 19:36 25-07-08

In article <X...@giganews.com>, 
frikkiethirion says...
> I wonder if somebody has managed to create a structured way of accessing
> the memory mapped IO attached to the STR912 [ARM9] via bitfields. 
> 
> My test code is as follow:
> 
> main()
> {
>    uint32_t uwI;
>    uint32_t *pwPointer;
> 
>    typedef struct
>    {
>       volatile uint32_t PLL_MDIV:8;   // [7:0]   PLL Pre-divider
>       volatile uint32_t PLL_NDIV:8;   // [15:8]  PLL Feedback divider
>       volatile uint32_t PLL_PDIV:3;   // [18:16] PLL Post-divider

Don't do that, it's a bad idea. Seductively bad.  Why? you might ask.

	- Well first it's both compiler and architecture dependant. That 
means you cannot tell what's happening in the code by reading it making 
future maintenance a nightmare.  Anyone maintaing the code is going to 
have to look up the details on how this particular compiler deals with 
bitfield layout.
	- Also I suspect that the use of uint32_t in a bit field is not 
fully defined.  IIRC only int and unsigned int are allowed.  On an ARM 
they happen to map to the same thing but...  Of course that's particular 
to this example.

But, you respond, I will only ever be working with a single compiler and 
architecture.
	- Have you no sympathy for anyone else who has to maintain the 
project?  Maybe you are developing something that doesn't need to be 
maintained if you are not around?

If that doesn't convince you consider that what happens when you access 
a bitfield isn't fully specified.  As a for instance consider accessing 
PLL_MDIV above, the access could be via an 8, 16 or 32bit set of 
operations (and the 16 and 32 bit methos would require some sort of 
read-modify-write operation).  It is possible (and yes some hardware 
does have these restrictions) that all access's to this hardware must be 
made only via 32bit read/writes or maybe only via 8 bit read/writes.  
It's also possible that a RMW sequence will not work due to harware 
restrictions.  And, yes there are compilers that will optimize the 
access to 8 bits.

Bitfields on I/O are seductive (i've been seduced by them a time or two 
myself) but ultimately they cause more problems than they solve.  
Bitfields are only usefule to reduce in memory storage at the expense of 
access time.

Robert
** Posted from http://www.teranews.com **

Re: STR912 bitfield access to memory mapped peripherals - Arie - 06:07 27-07-08

"frikkiethirion" ...
> I wonder if somebody has managed to create a structured way of accessing
> the memory mapped IO attached to the STR912 [ARM9] via bitfields.
>
> I can manipulate the members of a union that is declared in main(), bus as
> soon as I make a pointer type of my union and point it to the memory bus, 
> I
> get unexpected results.

I know from bad experience that (at least some) GCC compilers do minimize 
the access - for a bitfield in a 32-bit word it only does a byte 
read-modify-write, which is deadly for the other bits if you are accessing 
an I/O register that can only be accessed 32-bits wide.
For memory it's OK, so I update a RAM based copy, then write the result to 
the I/O register. Use a critical section or mutex around the whole operation 
if other drivers use the other bits...

Arie de Muynck