0

I'm trying to understand someones code and they are reading a memory space in the GPIO region (0x4002 0000 - 0x4002 03FF), but it's a higher address than the GPIO registers (they only go to 0x24).

Can you use all the extra space above 0x4002 0024 and below 0x4002 03FFF? What would happen if this space is read from?

EDIT: I totally forgot I could just post the code. I bolded the line that causes me headaches:

R0 = 0x15

PUSH    {R3,LR} ;
ADD.W   R0, R0, R0,LSL#1 ; 
MOV     GPIO_Port_A_Address, #0x40020000
LSLS    R0, R0, #2      ; 
ADDS    R2, GPIO_Port_A_Address, R0 ;
LDRB    R2, [R2,#4]     ; 
MOVS    R1, #1          ; 
LSL.W   R1, R1, R2      ; 

LDR R0, [GPIO_Port_A_Address,R0] ;

UXTH    R1, R1          ; 
BL      sub_8001ED8     ; 
MOVS    R0, #0          ; 
POP     {R3,PC} ;
artless noise
  • 21,212
  • 6
  • 68
  • 105
eibwen
  • 195
  • 8
  • 1
    Which microcontroller? Is the code you're looking at even for the same micro you're thinking about? The only 'generic' aspect is that 0x40000000 - 0x5fffffff in the Cortex-M3 memory map is where peripherals go. Anything beyond that is part-specific. – Notlikethat Aug 15 '16 at 13:37
  • Yeah, it's the STM32F205. Of course I'm reading the same datasheet for the uC the code was written for. I'm specifically asking about the GPIO region, which is why I stated that in my original question. – eibwen Aug 15 '16 at 15:13
  • 1
    Right, if that context were in the question to begin with, then I wouldn't have had to ask. With only "Cortex-M3" to go on, "the GPIO region" is meaningless, because CPU cores don't have GPIOs. Similarly, for all we know "someone's code" which we can't see and reason about could feasibly turn out to be, say, some random misidentified STM32F1 code off the internet (where that address range would be the DMA controller) and thus render the question invalid. A good question contains _all_ the relevant details. – Notlikethat Aug 15 '16 at 16:21
  • So now that you have all the details, do you have any useful advice? What did knowing it's a STM32F205 tell you that you needed to know? – eibwen Aug 16 '16 at 01:03
  • I'm thinking it might be a piece of code ported from a different platform where these addresses are defined. Or the memory may actually contain something useful and just be undocumented. I've seen examples of both in various third-party code. – Carsten Hansen Aug 16 '16 at 01:22
  • I added the code to the original question. – eibwen Aug 16 '16 at 10:19

1 Answers1

0

As a start, there are other GPIO ports that live at every multiple of 0x200 from 0x40020000 - 0x400223FF and beyond that but still in your range, there are the CRC peripheral, RCC, and Flash controller. The relevant memory map is on page 50 of RM0033 (Rev 3, old version so page number is probably wrong).

0x40023C00 - 0x40023FFF Flash interface register
0x40023800 - 0x40023BFF RCC
0x40023000 - 0x400233FF CRC
0x40022000 - 0x400223FF GPIOI
0x40021C00 - 0x40021FFF GPIOH
0x40021800 - 0x40021BFF GPIOG
0x40021400 - 0x400217FF GPIOF
0x40021000 - 0x400213FF GPIOE
0X40020C00 - 0x40020FFF GPIOD
0x40020800 - 0x40020BFF GPIOC
0x40020400 - 0x400207FF GPIOB
0x40020000 - 0x400203FF GPIOA

The code you have posted, as best I have been able to calculate, does access some unimplemented addresses (0x40020100, 0x400200FC), so I'm not sure what's going on there, or if I have miscalculated. In testing on an STM32F207, I can confirm that you can read and write to this without getting a fault, but the registers are unimplemented and always read as zero.

It would be a really bad idea to use peripheral registers as general purpose memory. Not every bit will be R/W, not all addresses may be implemented, and that's not even getting into the fact that you'll be configuring hardware based on application data and not correct register values. The range you've specified includes the flash controller and RCC, both of which are vital to the operation of the microcontroller.

If you are out of memory, there are some memory spaces that you may be able to use as general purpose if they are not already used for another purpose. The STM32F2's have a 4 kB backup SRAM that can be used, though there is some setup required to make it R/W. The USB peripheral(s) also has some RAM built in for endpoint buffers. If you aren't using USB, you could abuse some of this memory, and you could configure the USB peripheral so there aren't any bad side effects.

rjp
  • 1,760
  • 13
  • 15
  • If the implied context of the question is correct, though, it's not even peripheral registers being accessed, just some reserved address space which happens to (presumably) read as zero rather than faulting (unless possibly there might be some undocumented debug/integration test registers there). Either way, it sounds a lot more like plain buggy code than anything sneaky. – Notlikethat Aug 15 '16 at 20:11
  • So are you saying that reading an address that falls in the GPIO address range, just above the register range would/could result in a fault? – eibwen Aug 16 '16 at 01:07
  • It could. It depends on how it is implemented in the hardware. I'm going to edit the answer after looking over the code you added. – rjp Aug 16 '16 at 17:06
  • Do you have the value for `R2` at the `LDRB` instruction and `R0` at the instruction in question? I'm getting `0x400200FC`, which would mean the `LDRB R2,[R2,#4]` would be accessing `0x40020100`, which I do agree is not a valid address to read. It then also accesses `0x400201FC` which is also not valid. – rjp Aug 16 '16 at 17:19