我一直在使用STM32 hal驱动程序,我注意到当它们要为寄存器赋值时,它们会使用如下代码:
#define __IO volatile
typedef struct
{
__IO uint32_t CR1; /*!< USART Control register 1, Address offset: 0x00 */
__IO uint32_t CR2; /*!< USART Control register 2, Address offset: 0x04 */
__IO uint32_t CR3; /*!< USART Control register 3, Address offset: 0x08 */
__IO uint32_t BRR; /*!< USART Baud rate register, Address offset: 0x0C */
__IO uint32_t GTPR; /*!< USART Guard time and prescaler register, Address offset: 0x10 */
__IO uint32_t RTOR; /*!< USART Receiver Time Out register, Address offset: 0x14 */
__IO uint32_t RQR; /*!< USART Request register, Address offset: 0x18 */
__IO uint32_t ISR; /*!< USART Interrupt and status register, Address offset: 0x1C */
__IO uint32_t ICR; /*!< USART Interrupt flag Clear register, Address offset: 0x20 */
__IO uint32_t RDR; /*!< USART Receive Data register, Address offset: 0x24 */
__IO uint32_t TDR; /*!< USART Transmit Data register, Address offset: 0x28 */
__IO uint32_t PRESC; /*!< USART clock Prescaler register, Address offset: 0x2C */
} USART_TypeDef;
#define D2_APB1PERIPH_BASE (0x40000000UL)
#define UART4_BASE (D2_APB1PERIPH_BASE + 0x4C00UL)
#define UART4 ((USART_TypeDef *) UART4_BASE)
UART4->CR = whatever!
所以我试着用C在电脑上测试,但我有点困惑,下面的程序是我写的:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define startaddress ((mytype*) (0x6d9ff93b))
typedef struct
{
volatile uint32_t myTypeValue;
}mytype;
int main()
{
mytype* inst;
inst = startaddress;
inst->myTypeValue = 0x10;
printf("address is : %x \n",inst);
return 0;
}
output :
Process finished with exit code -1073741819 (0xC0000005)
这程序将崩溃在inst->myTypeValue = 0x10;
.否则它将显示这地址已经被分配给它.例如这是这输出:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define startaddress ((mytype*) (0x6d9ff93b))
typedef struct
{
volatile uint32_t myTypeValue;
}mytype;
int main()
{
mytype* inst;
inst = startaddress;
// inst->myTypeValue = 0x10;
printf("address is : %x \n",inst);
return 0;
}
output :
address is : 6d9ff93b
Process finished with exit code 0
现在我有一些问题,stm32库工作是因为地址是寄存器而不是SRAM吗?因为我记得当我在FMC上使用SDRAM时,我可以在地址0xC0000000处做同样的事情,它工作得很好。
如果赋值是错误的,为什么编译器在第二个例子上工作,并且只在我试图使用结构体内部的变量时崩溃?为什么不在赋值inst = startaddress;
时崩溃?
1条答案
按热度按时间a8jjtwal1#
STM32中的这些地址是定义的,它们引用存储器Map的硬件寄存器。
您的代码是不同的。要与STM代码等效,它必须是:
stm32库工作是因为地址是寄存器而不是SRAM吗?
是的。您在STM CMSIS头文件中看到的那些地址(不是库!!!!)是由制造商定义的,并且与硬件相关。
因为我记得当我在FMC上使用SDRAM时,我可以在地址0xC 0000000处做同样的事情,它工作得很完美。
这是因为由灵活内存控制器管理的内存库之一在此地址暴露给内核。芯片制造商也定义了这些地址。
如果赋值错误,为什么编译器在第二个示例中工作,并且只在我尝试使用结构体内部的变量时崩溃?为什么不在赋值inst = startaddress时崩溃;它自己?
因为你定义了一个指针,并给它赋值,这是可以的。但是这个指针包含了一个无效的引用,当你试图解引用它时-系统失败了。
我认为你需要重读一下你最喜欢的C书中的指针章节,因为你对指针的理解相当有限。如果你想用裸机编程uC,这是相当重要的知识