This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Cortex-M3: Changing an ISR address is being reset

Note: This was originally posted on 22nd March 2011 at http://forums.arm.com

Hi,

I have the following code and see some unexpected behavior. If someone could provide some help - my search so far has not led to anything useful.

Code:

printf("Addr %08x\n",*((unsigned int *)164));
*((unsigned int *)164) = 12;
asm volatile ("dmb");
printf("Addr2 %08x\n",*((unsigned int *)164));
printf("Addr3 %08x\n",*((unsigned int *)164));


I would typically expect to get the following printout (lets say the address is initially 0x0008080d):

Addr 0008080d
Addr2 0000000c
Addr3 0000000c


But I get:

Addr 0008080d
Addr2 0000000c
Addr3 0008080d


Now the printf causes some interrupts in the back but I would not expect this to change my ISR address of this peripheral (PWM).

Any thoughts why the address is being reset?

Many Thanks for any help on this.

EDIT:
If I pack the call "*((unsigned int *)164) = 12;" into a function I get the following result, which points that it might be related to something with the actual function call (may it be printf or whatever). But it just adds to my confusion right now.


Addr 0008080d
Addr2 0008080d
Addr3 0008080d
Parents
  • Note: This was originally posted on 22nd March 2011 at http://forums.arm.com

    Many thanks already for these replies. I should have quoted that I had  the volatile before. As I changed the code and finally saw a change I  though I made progress :) - but didn't as per your comment. Now with  volatile (and that is definitely the right way) I do not see any change  in the memory address's content.

    Basically the output is:

    Addr 0008080d
    Addr2 0008080d
    Addr3 0008080d


    The assembly output where it changes looks like below.

    ...
    135 0080 1A4F       ldr r7, .L12+48
      83:sensor_test.c ****   printf("%u %i\n",time(), SE); // unrelated
    136                 .loc 1 83 0
    137 0082 8022       movs r2, #128
    138 0084 0146       mov r1, r0
    139 0086 1A48       ldr r0, .L12+52
    140 0088 A047       blx r4
    141                 .loc 1 96 0
    142 008a 3B68       ldr r3, [r7, #0]
    143 008c 1948       ldr r0, .L12+56
    144 008e 1968       ldr r1, [r3, #0]
    145 0090 A047       blx r4
      99:sensor_test.c ****   *paddr = 12; // HERE
    146                 .loc 1 99 0
    147 0092 3B68       ldr r3, [r7, #0]
    148 0094 0C22       movs r2, #12
    149 0096 1A60       str r2, [r3, #0]
    100:sensor_test.c ****   printf("Addr2 %08x\n",*paddr);
    150                 .loc 1 100 0
    151 0098 1968       ldr r1, [r3, #0]
    152 009a 1748       ldr r0, .L12+60
    153 009c A047       blx r4
    101:sensor_test.c ****   printf("Addr3 %08x\n",*paddr);
    ...


    I am not an expert in assembler but hope my analysis is right. The magic  seems to happen in "str r2, [r3, #0]", store register 2 (#12) in  address of r3, which is r7. R7 loads the data from a label (ldr r7,  .L12+48). This does to refer to the word:

    196 00ec 00000000   .word   .LANCHOR1


    I cannot locate this LANCHOR further. However, I think it really would  be the memory address. So it may be some sort of write protection if I  am not mistaken.

    Any other thoughts?

    Sidenote: The MCU is an Atmel SAM3U 4E, Cortex M3.
Reply
  • Note: This was originally posted on 22nd March 2011 at http://forums.arm.com

    Many thanks already for these replies. I should have quoted that I had  the volatile before. As I changed the code and finally saw a change I  though I made progress :) - but didn't as per your comment. Now with  volatile (and that is definitely the right way) I do not see any change  in the memory address's content.

    Basically the output is:

    Addr 0008080d
    Addr2 0008080d
    Addr3 0008080d


    The assembly output where it changes looks like below.

    ...
    135 0080 1A4F       ldr r7, .L12+48
      83:sensor_test.c ****   printf("%u %i\n",time(), SE); // unrelated
    136                 .loc 1 83 0
    137 0082 8022       movs r2, #128
    138 0084 0146       mov r1, r0
    139 0086 1A48       ldr r0, .L12+52
    140 0088 A047       blx r4
    141                 .loc 1 96 0
    142 008a 3B68       ldr r3, [r7, #0]
    143 008c 1948       ldr r0, .L12+56
    144 008e 1968       ldr r1, [r3, #0]
    145 0090 A047       blx r4
      99:sensor_test.c ****   *paddr = 12; // HERE
    146                 .loc 1 99 0
    147 0092 3B68       ldr r3, [r7, #0]
    148 0094 0C22       movs r2, #12
    149 0096 1A60       str r2, [r3, #0]
    100:sensor_test.c ****   printf("Addr2 %08x\n",*paddr);
    150                 .loc 1 100 0
    151 0098 1968       ldr r1, [r3, #0]
    152 009a 1748       ldr r0, .L12+60
    153 009c A047       blx r4
    101:sensor_test.c ****   printf("Addr3 %08x\n",*paddr);
    ...


    I am not an expert in assembler but hope my analysis is right. The magic  seems to happen in "str r2, [r3, #0]", store register 2 (#12) in  address of r3, which is r7. R7 loads the data from a label (ldr r7,  .L12+48). This does to refer to the word:

    196 00ec 00000000   .word   .LANCHOR1


    I cannot locate this LANCHOR further. However, I think it really would  be the memory address. So it may be some sort of write protection if I  am not mistaken.

    Any other thoughts?

    Sidenote: The MCU is an Atmel SAM3U 4E, Cortex M3.
Children
No data