How to read or write peripheral registers

Revision as of 08:44, 22 May 2020 by Registered User


1. Installation[edit source]

For reading and writing STM32MP1 registers, we will use Devmem tool. There are two ways for installing it:

  • If you have internet access on the board through apt-get
  • Else by building on the host PC and deploying on the image

1.1. Using apt-get[edit source]

Enter the following commands to install Devmem:

 sudo apt-get update
 sudo apt-get install devmem2

For more information about apt-get, see the Package_repository_for_OpenSTLinux_distribution article.

1.2. Building on the host PC[edit source]

In our case we will use the Distribution Package to deploy Devmem on the board, if you want to use the Developer Package instead of, see How_to_integrate_an_external_software_package article.

Enter the following commands:

  • Build the package with bitbake:
 bitbake devmem2
  • Add it to the targeted image:
 echo 'IMAGE_INSTALL_append += "devmem2"' >> meta-st/meta-st-openstlinux/recipes-st/images/st-image-weston.bbappend
  • Rebuild the image:
 bitbake st-image-Weston

Then you have to flash the generated image on your board with STM32CubeProgrammer.

2. Use of Devmem[edit source]

To use Devmem, enter the following command:

 devmem2 [address] [type] [data]

Where:

  • [address] corresponds to the register address you want to read
  • [type] corresponds to the output value size you want (b, h, w or l, respectively byte, halfword, word or long). Assigning a type is not necessary if you only read the register and the default output will be a word.
  • [data] corresponds to the data value you want to set on the register, assigning a type is mandatory in this case . If you don't assign a data, it will only read the register.

3. Examples of Devmem use[edit source]

3.1. UART4 baud rate[edit source]

The UART baud rate is generated from UART clock frequency, with USARTDIV parameter found in the USART_BRR register. By default in OpenSTLinux Starter Package delivery, UART4 baud rate is set to 115 000, the Clock frequency CLOCK_UART4_K value is 64 000 000 Hz and the USARTDIV is equal to 556. These results are known and thanks to Devmem we will retrieve the USARTDIV value by looking at STM32MP1 registers.

On the STM32MP157 Reference Manual, we find out that the base address of UART4 is 0x4001 0000 and the USARTDIV value is located at the offset 0x0C.

 devmem2 0x4001000C
/dev/mem opened.
Memory mapped at address 0xb6fc300c.
Read at address 0x4001000C (0xb6fc300c): 0x0000022C

Which is equal to 556 in decimal.

3.2. GPIO[edit source]

In this example, we will check the output value of GPIO port A pins 13 and 14 corresponding to leds 6 and 5 on the DK2. According to the Reference Manual, we find out that the base address for GPIOA is 0x5000 2000 and the output value of leds is located at the offset 0x14.

However, GPIOs' clock have to be enabled at first if we want to see some results in registers. Else it will output 0 has you can see:

 devmem2 0x50002014
/dev/mem opened.
Memory mapped at address 0xb6f43014.
Read at address 0x50002014 (0xb6f43014): 0x00000000

The clock is called RCC_MP_AHB4ENSETR and is located at the address 0x5000 0A28.

 devmem2 0x50000A28
/dev/mem opened.
Memory mapped at address 0xb6fdca28.
Read at address 0x50000A28 (0xb6fdca28): 0x00000000

In this register, the first eleven bits (from LSB to MSB) allow enabling respectively from GPIOA to GPIOK (1 enable, 0 disable). In our case we only need the GPIO A to be enabled so we will write 0x1 in the register.

 devmem2 0x50000A28 w 0x1
/dev/mem opened.
Memory mapped at address 0xb6fdca28.
Read at address 0x50000A28 (0xb6fdca28): 0x00000000
Write at address 0x50000A28 (0xb6fdca28): 0x00000001, readback 0x00000001

Now let's check again in the GPIOA's register:

 devmem2 0x50002014
/dev/mem opened.
Memory mapped at address 0xb6f43014.
Read at address 0x50002014(0xb6f43014): 0x00002400

In my case only the led 5 is enabled, the following table shows the output value of the register in function of leds 5 and 6 states.

Led 5 Enabled Led 5 Disabled
Led 6 Enabled 0x400 0x4400
Led 6 Disabled 0x2400 0x6400

For example, to set both leds enabled, set 0x400 as value of the register:

 devmem2 0x50002014 w 0x400
/dev/mem opened.
Memory mapped at address 0xb6f43014.
Read at address 0x50002014 (0xb6f43014): 0x00002400
Write at address 0x50002014 (0xb6f43014): 0x00000400, readback 0x00000400

4. Restricted Access[edit source]

Keep in mind Devmem tool can only allow you to access peripheral registers, indeed all the registers in M4 and A7 cores are secured and will make the board rebooting if you try to read it.

Besides when trying to access a register, make sure the related peripheral has not been isolated on the MCU side. Else you would not be able to access it due to access rights.