Skip to main content
MMust.5
Senior
June 22, 2023
Solved

7 USART3 registers == 28 bytes. What are the other addresses in USART3 for?

  • June 22, 2023
  • 15 replies
  • 3910 views

STM32F407 Discovery

 

 

typedef struct __UART_HandleTypeDef
{
USART_TypeDef *Instance;
UART_InitTypeDef Init;
const uint8_t *pTxBuffPtr;
uint16_t TxXferSize;
__IO uint16_t TxXferCount;
uint8_t *pRxBuffPtr;
uint16_t RxXferSize;
__IO uint16_t RxXferCount;
__IO HAL_UART_RxTypeTypeDef ReceptionType;
DMA_HandleTypeDef *hdmatx;
DMA_HandleTypeDef *hdmarx;
HAL_LockTypeDef Lock;
__IO HAL_UART_StateTypeDef gState;
__IO HAL_UART_StateTypeDef RxState;
__IO uint32_t ErrorCode;
} UART_HandleTypeDef;

 

I take the USART3 setting as an example.
The starting address for storing this UART_HandleTypeDef structure will be 0x4000 4800.
USART3 has 7 registers. Each register is 32 bits.
7*32==224/8==28 bytes
7 USART3 registers occupy 28 bytes.
These 7 registers are configured by the USART_TypeDef *Instance structure;
0x4000 4800 + 28 bytes== 4000 481C
0x4000 4800 ----- 4000 481C There are 7 registers in this address limit.

tim2.png

But USART3 is allocated a lot more addresses 0x4000 4800 - 0x4000 4BFF What's in there?
And most importantly, I'm wondering where it is stored:

 

UART_InitTypeDef Init;
const uint8_t *pTxBuffPtr;
uint16_t TxXferSize;
__IO uint16_t TxXferCount;
uint8_t *pRxBuffPtr;
uint16_t RxXferSize;
__IO uint16_t RxXferCount;
__IO HAL_UART_RxTypeTypeDef ReceptionType;
DMA_HandleTypeDef *hdmatx;
DMA_HandleTypeDef *hdmarx;
HAL_LockTypeDef Lock;
__IO HAL_UART_StateTypeDef gState;
__IO HAL_UART_StateTypeDef RxState;
__IO uint32_t ErrorCode;

 

And what does it set up? Or they are ordinary variables and are stored as ordinary data, while registers are not configured.
That is, there are only 7 registers in this address limit 0x4000 4800 - 0x4000 4BFF, right?
What is the rest of the space for?

This topic has been closed for replies.
Best answer by MMust.5

I understood everything, thanks.

tim2.png

If the address was stored in the UART_HandleTypeDef structure, then it would be as I described at the beginning))

I messed up something and thought that the address in the UART_HandleTypeDef structure is saved.

15 replies

Tesla DeLorean
Guru
June 22, 2023

It is not memory in the RAM sense, it is a window into combinational logic of the peripherals.

The sizes here are more about convenience of decoding address boundaries by looking at higher order address bits, in binary, and that's how the logic / machine works.

Each peripheral is given a 1KB (0x400 byte) window, and passed the low order 10-bit to decode in whatever fashion the logic choses. The UART peripheral is stepped-and-repeated for each instance implemented in hardware.

A subdivision of the ARM's 4GB (32-bit) address space, and accessed like all other memory, is a convenient and consistent method. You can use pointer, structures, and DMA to access it. The debugger can access via the same address bus and methods. If the address doesn't decode, the MCU can Hard Fault to indicate an access that is out-of-bounds, and likely erroneous. 

Perhaps you can find some college level texts covering computer, CPU, and peripheral architecture and design?

 

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Tesla DeLorean
Guru
June 22, 2023

The UART_HandleTypeDef structure is a software/library side method of tracking settings, buffers, associated peripherals, DMA and callbacks.The USART_TypeDef *Instance; is a pointer to the hardware that implements the logic gates and register window to the peripheral.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Peter BENSCH
ST Technical Moderator
June 22, 2023

Indeed, this seems like an incredible waste of address space, but this is due to the fact that the starting address is as clear as possible and, above all, easily adaptable via the many derivatives.
In addition to what @Tesla DeLorean wrote:
If you take a look at the corresponding reference manual, you will usually find 0x400 (1KB) blocks, regardless of whether it is UART or USB. When the STM32 was defined many years ago and the drivers were to be built as homogeneously as possible, address blocks of the same size were defined for access. A block size of:

  • 0x10 = 16 bytes = 4 double words (registers) is much too small,
  • 0x100 = 256 bytes = 64 registers would have been just about enough,
  • 0x400 = 1024 bytes = 256 registers is completely sufficient for all current and expected peripherals

It should be noted that undefined address ranges are to be considered reserved.

Regards
/Peter

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
Tesla DeLorean
Guru
June 22, 2023

Basically it trades lower transistor count and uniformity / orthogonal design.

In old MCU designs everything was tightly packed and decoded (see 8051) all the registers and peripherals. These were hard to expand on, and design methods became more automated, structured, and hierarchical so you'd design the UART logic once, and then drop repeated instances into the design with a decoded chip select from the next level up, and truncated address bus to decode the internal registers.

Depending on the number of transistors committed to the decode, the same registers might appear to be replicated every 32 bytes, or whatever,

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
LCE
Principal II
June 22, 2023

> This must be stored within USART3 addresses

These are variables stored somewhere in SRAM.

MMust.5
MMust.5Author
Senior
June 22, 2023

The starting address for the UART_HandleTypeDef structure is 0x4000 4800
7 registers occupy 28 bytes.
Immediately after setting the registers, this is stored

UART_InitTypeDef Init;
const uint8_t *pTxBuffPtr;
uint16_t TxXferSize;
__IO uint16_t TxXferCount;
uint8_t *pRxBuffPtr;
uint16_t RxXferSize;
__IO uint16_t RxXferCount;
__IO HAL_UART_RxTypeTypeDef ReceptionType;
DMA_HandleTypeDef *hdmatx;
DMA_HandleTypeDef *hdmarx;
HAL_LockTypeDef Lock;
__IO HAL_UART_StateTypeDef gState;
__IO HAL_UART_StateTypeDef RxState;
__IO uint32_t ErrorCode;

This is not stored somewhere in SRAM, but immediately after the registers are adjusted.
Because in the UART_HandleTypeDef structure everything is stored in order.

LCE
Principal II
June 22, 2023

Check your *.map file in the release or debug folder, search for "huart3" (or whatever you named it), there you will see its address and length.

MMust.5
MMust.5Author
Senior
June 23, 2023

huart3.Init.BaudRate = 9600;
huart3 is the start address USART3 address 0x4000 4800
BaudRate is in the UART_HandleTypeDef structure and must come immediately after the registers.
I looked in Memory, but it doesn't happen.

tim2.png

LCE
Principal II
June 23, 2023

> huart3.Init.BaudRate = 9600;
> huart3 is the start address USART3 address 0x4000 4800

Yes...


> BaudRate is in the UART_HandleTypeDef structure and must come immediately after the registers.

No...


> I looked in Memory, but it doesn't happen.

Yes, because the register area is not used for variables (UART_HandleTypeDef huart3) created by the user.

huart3 is a structure = lots of variables, and includes the pointer "Instance" to the hardware registers starting at USART3 address 0x4000 4800.
Just because the first member / variable of the struct Instance is a pointer, does NOT mean that the struct is placed there.

Again, check your map file, search the memory for huart3.Instance, which should have the value of 0x4000 4800, but is somewhere in SRAM, where variables are normally placed.

Sorry, but if you don't get it now, I can't explain it any better.