lpcware

Aligned memory access

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by rodrigo.such on Tue Dec 06 05:18:03 MST 2011
Hi guys,
  
  I´m using the LPCXpresso [COLOR=red][FONT=&quot]v4.1.0 [Build 190] [27/09/2011] [/FONT][/COLOR][FONT=&quot]and a LPC1768 LPCXpresso Board.[/FONT]
  [FONT=&quot] [/FONT]
  My problem, I guess, is related with a non-aligned access to register.
  First of all, I´m not using CMSIS. Because of some internal reasons we decide to develop our own hardware access library.
  So let me try to describe my issue;
  
  I`u describe my problem based in the clock configuration because It was the first thing I had to do, and so, the first place I´ve noticed the problem. However, I this is not a clock problem.
  According to LPC1768 User manual, I have several registers to configure the system clock. The PLL0CFG is one of them and it is described as follow:
  [COLOR=#1F497D] [/COLOR]
  [B][COLOR=red][FONT=&quot]14:0 MSEL0[/FONT][/COLOR][/B]
  [B][COLOR=red][FONT=&quot]15 Reserved[/FONT][/COLOR][/B]
  [B][COLOR=red][FONT=&quot]23:16 NSEL0[/FONT][/COLOR][/B]
  [B][COLOR=red][FONT=&quot]31:24 Reserved[/FONT][/COLOR][/B][B][COLOR=red][/COLOR][/B]
  [COLOR=#1F497D] [/COLOR]
  
  In order to access the PLL0CFG, bits I´ve declared this struct type:
  [COLOR=#1F497D] [/COLOR]
  [B][COLOR=#7F0055][FONT=&quot]typedef[/FONT][/COLOR][/B][COLOR=black][FONT=&quot] [/FONT][/COLOR][B][COLOR=#7F0055][FONT=&quot]union[/FONT][/COLOR][/B][FONT=&quot][/FONT]
  [COLOR=black][FONT=&quot]{[/FONT][/COLOR][FONT=&quot][/FONT]
  [COLOR=#005032][FONT=&quot]UInt32[/FONT][/COLOR][COLOR=black][FONT=&quot] [/FONT][/COLOR][COLOR=#0000C0][FONT=&quot]Value[/FONT][/COLOR][COLOR=black][FONT=&quot];[/FONT][/COLOR][FONT=&quot][/FONT]
  [B][COLOR=#7F0055][FONT=&quot]struct[/FONT][/COLOR][/B][FONT=&quot][/FONT]
  [COLOR=black][FONT=&quot]{[/FONT][/COLOR][FONT=&quot][/FONT]
  [COLOR=#005032][FONT=&quot]UBitField32[/FONT][/COLOR][COLOR=black][FONT=&quot] [/FONT][/COLOR][COLOR=#0000C0][FONT=&quot]MSEL[/FONT][/COLOR][COLOR=black][FONT=&quot] :15;[/FONT][/COLOR][FONT=&quot][/FONT]
  [COLOR=#005032][FONT=&quot]UBitField32[/FONT][/COLOR][COLOR=black][FONT=&quot] [/FONT][/COLOR][COLOR=#0000C0][FONT=&quot]Reserved[/FONT][/COLOR][COLOR=black][FONT=&quot] : 1;[/FONT][/COLOR][FONT=&quot][/FONT]
  [COLOR=#005032][FONT=&quot]UBitField32[/FONT][/COLOR][COLOR=black][FONT=&quot] [/FONT][/COLOR][COLOR=#0000C0][FONT=&quot]NSEL[/FONT][/COLOR][COLOR=black][FONT=&quot] : 8;[/FONT][/COLOR][FONT=&quot][/FONT]
  [COLOR=#005032][FONT=&quot]UBitField32[/FONT][/COLOR][COLOR=black][FONT=&quot] [/FONT][/COLOR][COLOR=#0000C0][FONT=&quot]Reserved1[/FONT][/COLOR][COLOR=black][FONT=&quot] : 8;[/FONT][/COLOR][FONT=&quot][/FONT]
  [COLOR=black][FONT=&quot]}Bits;[/FONT][/COLOR][FONT=&quot][/FONT]
  [COLOR=black][FONT=&quot]}[/FONT][/COLOR][COLOR=#005032][FONT=&quot]TClkPllCfg[/FONT][/COLOR][COLOR=black][FONT=&quot];[/FONT][/COLOR]
  [COLOR=#1F497D] [/COLOR]
  And I´m using this define:
  [B][COLOR=red][FONT=&quot] [/FONT][/COLOR][/B]
  [COLOR=#1F497D] [/COLOR]
  [B][COLOR=#7F0055][FONT=&quot]#define[/FONT][/COLOR][/B][COLOR=black][FONT=&quot] PLL0CFG (*(TClkPllCfg *)0x400FC084)[/FONT][/COLOR]
  [COLOR=black][FONT=&quot] [/FONT][/COLOR]
   “0x400FC084” is the register address.[FONT=&quot][/FONT]
  
                 In some time I try to configure this register just writing it as follow.
  [COLOR=#1F497D] [/COLOR]
  [COLOR=black][FONT=&quot]PLL0CFG[/FONT][/COLOR][COLOR=black][FONT=&quot].[/FONT][/COLOR][COLOR=#0000C0][FONT=&quot]MSEL[/FONT][/COLOR][COLOR=black][FONT=&quot] = p_m;[/FONT][/COLOR][FONT=&quot][/FONT]
  [COLOR=black][FONT=&quot]PLL0CFG[/FONT][/COLOR][COLOR=black][FONT=&quot].[/FONT][/COLOR][COLOR=#0000C0][FONT=&quot]NSEL[/FONT][/COLOR][COLOR=black][FONT=&quot] = p_n;[/FONT][/COLOR]
  [COLOR=#1F497D][FONT=&quot] [/FONT][/COLOR]
  Using the debugger I see that the first line works fine. However when I run the second line, all the register is written with the same value, and therefore, I lost the MSEL value.
  This same .c code had been successfully used with EWARM (IAR embedded workbench) and works fine. The problem only occurs when using LPCXpresso.
  
  Based in these behaivor, I had some guesses:
  
  According to LPC17XX User Manual[COLOR=#1F497D], [/COLOR][B][COLOR=red][FONT=&quot]Unaligned accesses are usually slower than aligned accesses. In addition, some memory[/FONT][/COLOR][/B]
  [B][COLOR=red][FONT=&quot]regions might not support unaligned accesses[/FONT][/COLOR][/B][B][COLOR=red][FONT=&quot]. Therefore, ARM recommends that[/FONT][/COLOR][/B]
  [B][COLOR=red][FONT=&quot]programmers ensure that accesses are aligned.[/FONT][/COLOR][/B]
  [COLOR=#1F497D] [/COLOR]
  There is no specification of what memory regions I cannot have unaligned accesses but, I think, the registers works this way; I mean, I cannot access registers using non-aligned instructions.
  
  Seeing the disassembly I´ve noticed that EWARM (IAR embedded workbench), uses only aligned instructions to write the register, (STR instruction). At the same time the LPCXpresso uses STRB instruction that is non-aligned. Furthermore, using the “instruction step mode” I can see that everything is fine until the STRB instruction. The address and the data are correct, but the STRB instruction doesn’t write only one byte but all register, reinforcing my guess.
  [FONT=&quot] [/FONT]
  The disassembly code can be seen attached:
  [COLOR=#1F497D] [/COLOR]
  [CENTER][CENTER][COLOR=#1F497D] [/COLOR][/CENTER][/CENTER]

Does anyone know how to solve this problem without changing my C code? I do not want to use masks to access the register because I´d have to change a lot of C code that has already been tested and approved with others compilers. I was thinking about some compiler flag to avoid the using of non-aligned instructions by the compiler, but I don’t know if it exists.
  
  Tks in advance.

Outcomes