2013-04-01 02:06 AM
2013-04-01 04:42 AM
What packing is being used here? Does the sizeof() match your expectation? Look at how it works on a RAM address, in the debugger. Look at the assembler code generated.
2013-04-01 06:40 AM
Thank's clive1,
Packing is off, and sizeof() returns the correct size. On another place in the same program I use another structure to write page aligned in an eeprom. I didn't go in and learn about the ARM assembler instructions yet, assembler I'm not the hero, but as far as I can go with it, it seams to be correct. 08001230 <processData_SetDefaultValues>: 8001230: 4b08 ldr r3, [pc, #32] ; (8001254 <processData_SetDefaultValues+0x24>) 8001232: 2201 movs r2, #1 8001234: 801a strh r2, [r3, #0] 8001236: 20c8 movs r0, #200 ; 0xc8 8001238: 4907 ldr r1, [pc, #28] ; (8001258 <processData_SetDefaultValues+0x28>) 800123a: 4a08 ldr r2, [pc, #32] ; (800125c <processData_SetDefaultValues+0x2c>) 800123c: 8058 strh r0, [r3, #2] 800123e: 2080 movs r0, #128 ; 0x80 8001240: 8099 strh r1, [r3, #4] 8001242: 80da strh r2, [r3, #6] 8001244: 0081 lsls r1, r0, #2 8001246: 2210 movs r2, #16 8001248: 2000 movs r0, #0 800124a: 8119 strh r1, [r3, #8] 800124c: 729a strb r2, [r3, #10] 800124e: 72d8 strb r0, [r3, #11] 8001250: 4770 bx lr 8001252: 46c0 nop ; (mov r8, r8) 8001254: 40002850 .word 0x40002850 8001258: 00001388 .word 0x00001388 800125c: 000002ee .word 0x000002ee2013-04-01 07:15 AM
While not explicitly stated, I'd be concerned that the memory doesn't perform write granularity below 32-bits. ie It's a register, not a memory with selective byte write lanes/selects.
Try this approach:void processData_SetDefaultValues(void)
{
processData_t pd;
uint32_t *src, *dst;
int i = (sizeof(pd) + 3) / 4; // Size rounded to 32-bit words
// Perform localized initialization, and do a 32-bit wide copy
pd.actPageNo = 1;
pd.sollQTY = 200;
pd.lcd_BackLight = 5000;
pd.lcd_Contrast = 750;
pd.rpm_Ticks = 512;
pd.actProfile = 16;
pd.dummy = 0;
src = (uint32_t *)&pd;
dst = (uint32_t *)(RTC_BASE + 0x50); // RTC_BKPxR
while(i--)
*dst++ = *src++;
}
2013-04-01 07:31 AM
perhaps Printf is confused about what it is being asked to print because of the #define.
and because of things like actProfile being a char and being told to print like a 32bit %d
I use ''placement new'' in C++ but I think this should work in CprocessData_t * ProcessData = ((processData_t *)(RTC_BASE + 0x50));
forgive my stupidity, it's Monday. But it may still be a type related issue caused by the define.2013-04-01 08:05 AM
@rocketdawg
printf is not the problem, see second part of my example from first post. The problem doesn't appear on reading the regs using a struct, just on writing it goes wrong. @clive1 Sorry I didn't say what controller it is. It's a STM32F051. Yes writing the 32Bit regs entirely works perfect. I tried to make the access to this regs more elegant, because I like to hold process critical data in it, which I like to have present also after a power fail. And that registers are heavily accessed. So I have to do it by hand again. Thank's clive1 Ju2013-04-01 08:10 AM
@rocketdawg
just read the edit in your post. We accept the Monday-excuse ;) Ju2013-04-01 08:55 AM
A reasonable abstraction might be to hold the current/working data in a copy of the registers, and then a routine to flush to the NV memory of choice when you change the copy. A RAM based copy should also be faster.