Why is arm code so obfuscated?

Why are all the examples of arm code I see obfuscated and redundant?

Why is a pointer created that points to the base address? Why not just use the base like this?

AT91C_BASE_PMC->PMC_PCER = …

Or, why not do this instead of creating a pointer,

#define pPMC AT91C_BASE_PMC

Wouldn’t that do the same thing?

Not only is that redundant, but the register member of the pointer also says PMC.

pPMC->PMC_PCER = …

I already know I’m pointing to the PMC thats why a special pointer pPMC was made!

Why does this have to be so long winded? Since whoever writes all these examples likes to type alot of junk why couldnt they do it like this,

Power_management_controller->peripheral_clock_enable_register

This way is also long winded but its not redundant and I dont have to remember what every register abbreviation is. What I would really prefer is that it would be done in a simple non-redundant way such as this,

PMC->PCER

Am I the only person who is unsatisfied with the way arm code is written?

        AT91PS_PMC  pPMC  = AT91C_BASE_PMC;
	AT91PS_PIO  pPIOA = AT91C_BASE_PIOA;
	AT91PS_RSTC pRSTC = AT91C_BASE_RSTC;
	
	// Enable the clock for PIO and UART0
	pPMC->PMC_PCER = ( ( 1 << AT91C_ID_PIOA ) | ( 1 << 1 ) ); // n.b. 

	
	// Configure the PIO Lines corresponding to LED1 to LED4
	pPIOA->PIO_PER = LED_MASK; // pins controlled by PIO (GPIO)
	pPIOA->PIO_OER = LED_MASK; // pins outputs

The example code does not look that bad, but I would probably have done it a little differently, just using a simple #define for each register.

I guess it depends on your preferences.

it’s nothing to do with ARM but C

here is The International Obfuscated C Code Contest http://www.ioccc.org/

go there and you will change your mind :slight_smile:

Tsvetan

I just want to know why ATMEL decided to write header files that force you to use redundant abbreviations. The AVR header files were so simple. If you want to write to an io register you just go ioreg = 0xff; but on the SAM io regs are set up as a structure with a custom typedef for EACH IO DEVICE and you have to set up this custom pointer to access any io register. Not only is that a pain, but the structure member names contain a redundant device abbreviation along with another abbreviation for the actual io register. Preferably they could have just spelled out what the io register is or expand the most meaningful word out of the abbreviation. Theres 3x redundant device abbreviation along with a >3 letter register abbreviation which is not obvious and must be looked up over and over again or added as a comment. Even if I did memorize what all those abbreviations stand for, I will forget if I go away from my code for any amount of time. I AM FORCED TO REDUNDANTLY TYPE DEVICE ABBREVIATIONS MAKING A SIMPLE IO REGISTER OPERATION TAKE UP ALMOST AN ENTIRE LINE AND IF I WANT TO COMMENT WHATS GOING ON IT HAS TO TAKE UP A SECOND LINE.

WHO THOUGHT OF DOING THIS WAY!!!

Yes, indeed. I’ve found the following way of coding OK for the LED blinking project

int main()
{//* Begin
    int i;
    // First, enable the clock of the PIO because peripheral clocks disabled after reset
    // Peripheral Clock required for SW1 & SW2 only. According to SAM7S64 manual (page 227),
    // the Power Management Controller (PMC) controls the PIO Controller clock in order to save power.
    // Writing any of the registers of the user interface does not require the PIO Controller clock to be
    // enabled. This means that the configuration of the I/O lines does not require the PIO Controller
    // clock to be enabled. Thus, output LED1 or LED2 high / low doesn't require PMC.
    // However, when the clock is disabled, not all of the features of the PIO Controller are available.
    // Note that the Input Change Interrupt and the read of the pin level require the clock to be
    // validated. Therefore, we need enabling the PMC only for input lines at SW1 & SW2

    //  AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1 << AT91C_ID_PIOA ) ;
       *AT91C_PMC_SCER = AT91C_CKGR_MOSCEN;   // main oscillator enable
       *AT91C_PMC_PCER = 1<<AT91C_ID_PIOA;    // peripheral clock enable

    // then, we configure the PIO Lines corresponding to LED1 to LED2
    // to be outputs. No need to set these pins to be driven by the PIO because it is GPIO pins only.
    //  AT91F_PIO_CfgOutput( AT91C_BASE_PIOA, LED_MASK ) ;
       *AT91C_PIOA_PER = LED_MASK;
       *AT91C_PIOA_OER = LED_MASK;

    //  AT91F_PIO_SetOutput( AT91C_BASE_PIOA, LED_MASK ) ;
    //  Clear the LED's. On the SAM7S-P64 board we must apply a "1" to turn off LEDs
       *AT91C_PIOA_SODR = LED_MASK;

    // Loop forever
    for (;;)
    {
        // Once a Shot on each led
	for ( i=0 ; i < NB_LEB ; i++ )
        {
	    //AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, led_mask[i]) ;
            *AT91C_PIOA_SODR = led_mask[i];  //set output data register
	    wait();
	    //AT91F_PIO_SetOutput( AT91C_BASE_PIOA, led_mask[i] ) ;
            *AT91C_PIOA_CODR = led_mask[i];  //clear output data register
	    wait();
        }// End for
    }// End for
}//* End

outer_space:
Not only is that a pain, but the structure member names contain a redundant device abbreviation along with another abbreviation for the actual io register.

As annoying as this is, you can’t really blame ATMEL for this. They are just making header files that conform to the original “C” standard. In the K&R standard for C (published in 1978), there was a requirement that the names of structure members be unique, even outside of the structure. So an old C compiler would reject code like:

struct foo {
  int a;
};
struct bar {
  int a;
};

They got rid of this requirement in the ANSI C standard, published about a decade later, and more recent standards like C99 and C++ don’t require structure member names to be unique either.

If you look at some of the header files that come with a modern system, you’ll still see this same sort of thing… for example, in the structure struct sockaddr_in, which is used to hold internet addresses, every member has the prefix sin_.

After you look at code like this for a while, your eyes will start to filter out these prefixes for you, and you hands will type them automatically. If it bothers you a lot, you can probably just make a copy of that structure, change all of the names, and cast AT91C_BASE_PIOA to a pointer of your new type.

Am I the only person who is unsatisfied with the way arm code is >written?

Heck NO!!!

I am so glad i ran into this post. I thought I was the only person who thought the Atmel ARM code is goofy.

Why does this have to be so long winded?

it kinda reminds me of Java code. :lol:

A couple points:

You’re complaining about this line:

AT91PS_PMC pPMC = AT91C_BASE_PMC;

It is entirely unnecessary. Just remove it and replace all instances of pPMC with AT91C_BASE_PMC.

I personally am quite attached to how Atmel’s register include files are set up. It allows you to quickly write code for one peripheral, then move it over to another. For example I set up SPI0 on a board of mine, and then to set up SPI1, I just copied the old code then had to change the base pointer to SPI1. Very quick and easy.

I too am used to the AVR world where you just use the reference names, no base pointers. But there are just so many registers on ARMs that it would become very, very confusing as to what peripheral each register was associated with if those base pointers were there.