in_word(addr) 和out_word(addr, data)在bootloader的调试作用

                                                               in_word(addr) 和out_word(addr, data)在bootloader的调试作用

in_word(addr)是读对应的寄存器的值,out_word是对寄存器写。驱动程序一般最终是经过多层封装后最终还是通过读写寄存器的接口对寄存器操作。

比如对某个GPIO的状态可以用in_word的函数

#define TLMM_BASE_ADDR      0x00800000
#define GPIO_IN_OUT_ADDR(x) (TLMM_BASE_ADDR + 0x1004 + (x)*0x10)

gpio59   3b
0x00800000+0x1004+0x590= 0x008013b4

{
if (in_word(0x008013b4)) 

printk(“gpio59为高电平\n”)

else

printk(“gpio59为低电平\n”)

}

如果对某个GPIO写1或者0可以用out_word(addr, data)

对gpio59设置为低电平

out_word(0x008013b4, 0);

对gpio59设置为高电平

out_word(0x008013b4, 1);

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32 bootloader是一种可以在芯片上运行的特殊程序,它可以通过串口或USB等接口接收新的程序文件,然后将其烧录到芯片的Flash中。 以下是一个简单的STM32 bootloader接收程序的示例代码,仅供参考: ```c #include "stm32f10x.h" #define APPLICATION_ADDRESS 0x08004000 // 应用程序起始地址 #define BOOTLOADER_TIMEOUT 5000 // 进入bootloader的超时时间,单位ms #define UART_TIMEOUT 500 // UART接收超时时间,单位ms #define CMD_JUMP_TO_APP 0x01 // 跳转到应用程序命令 #define CMD_ERASE_APP 0x02 // 擦除应用程序命令 #define CMD_WRITE_APP 0x03 // 写入应用程序命令 uint8_t uart_buf[256]; uint32_t uart_idx = 0; uint32_t timeout_cnt = 0; void jump_to_app(void) { // 关闭所有中断 __disable_irq(); // 关闭SysTick定时器 SysTick->CTRL = 0; // 关闭所有外设 RCC->APB1ENR = 0; RCC->APB2ENR = 0; // 关闭所有GPIO的输出 GPIOA->ODR = 0; GPIOB->ODR = 0; GPIOC->ODR = 0; GPIOD->ODR = 0; GPIOE->ODR = 0; GPIOF->ODR = 0; GPIOG->ODR = 0; // 设置栈指针和程序计数器 uint32_t app_start_addr = *(__IO uint32_t*)APPLICATION_ADDRESS; uint32_t app_stack_ptr = *(__IO uint32_t*)APPLICATION_ADDRESS; uint32_t app_entry_point = *(__IO uint32_t*)(APPLICATION_ADDRESS+4); __set_MSP(app_stack_ptr); __set_PSP(app_stack_ptr); __ASM volatile ("bx %0"::"r"(app_entry_point)); } void erase_app(void) { FLASH_Unlock(); FLASH_ErasePage(APPLICATION_ADDRESS); FLASH_Lock(); } void write_app(uint8_t* data, uint32_t len) { uint32_t addr = APPLICATION_ADDRESS; FLASH_Unlock(); for (uint32_t i = 0; i < len; i += 4) { uint32_t word = *((uint32_t*)(data + i)); FLASH_ProgramWord(addr, word); addr += 4; } FLASH_Lock(); } void process_command(uint8_t cmd, uint8_t* data, uint32_t len) { switch (cmd) { case CMD_JUMP_TO_APP: jump_to_app(); break; case CMD_ERASE_APP: erase_app(); break; case CMD_WRITE_APP: write_app(data, len); break; default: break; } } int main(void) { // 初始化串口 USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, &USART_InitStructure); USART_Cmd(USART1, ENABLE); // 进入bootloader while (1) { if (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == SET) { uart_buf[uart_idx++] = USART_ReceiveData(USART1); timeout_cnt = 0; } else { timeout_cnt++; if (timeout_cnt >= BOOTLOADER_TIMEOUT) { jump_to_app(); } } if (uart_idx >= 3) { uint32_t len = uart_buf[2] | (uart_buf[1] << 8) | (uart_buf[0] << 16); if (uart_idx >= len + 3) { process_command(uart_buf[3], uart_buf + 4, len); uart_idx = 0; } } } } ``` 在该示例中,我们通过USART1接收新的程序文件,并根据不同的命令来执行不同的操作。 具体来说,我们定义了三个命令: - CMD_JUMP_TO_APP:跳转到应用程序命令 - CMD_ERASE_APP:擦除应用程序命令 - CMD_WRITE_APP:写入应用程序命令 当收到这些命令时,我们分别执行了对应的操作: - 跳转到应用程序:首先关闭所有中断和外设,然后根据应用程序起始地址设置栈指针和程序计数器,最后跳转到应用程序入口点。 - 擦除应用程序:使用STM32的FLASH模块擦除应用程序所在的Flash页面。 - 写入应用程序:使用STM32的FLASH模块将新的程序文件写入到应用程序所在的Flash页面。 需要注意的是,在跳转到应用程序之前必须关闭所有中断和外设,否则可能会导致应用程序无法正常运行。同时,为了避免写入过程中出现错误,我们还需要在写入数据之前调用FLASH_Unlock()函数解锁Flash,写入完成后再调用FLASH_Lock()函数锁定Flash。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值