串口打印调测

1 虚拟化打印调测

当启动一个OS时,loader跳转内核head.S后可能没有打印,在开MMU之前可以通过写串口寄存器物理地址直接打印,开MMU之后只能使用虚拟地址打印。

1.1 hvc指令

  • 用于虚拟机启动后,Hvc直接陷出到Hypervisor进行流程跟踪。
vm 中:head.s中开启mmu前,汇编代码hvc #2 或者c代码 asm("hvc #2") 
hyp侧:cou_vcpu_emulate_hvc64(),vmm_printf("hvc %u\n", iss)

1.2 串口调试

  1. C语言写串口
/* main.c增加vim2 uart串口打印接口,打印字符S */
/* pl011一般基地0x9000000,DR 0 */
void uart_pputc(void)
{
    while((*(uint32_t*)0xc81004cc) & (1 << 21))
              ;
          *(uint32_t*)0xc81004c0 = 'S';
    
}
  1. 汇编写串口
/* 或者使用汇编,使用x16,w17寄存器,以免使用常规寄存器干扰 */
    .globl uart_pputc
uart_pputc:
        mov  x16, #0x4cc             // #1288
        movk x16, #0xc810, lsl #16
        ldr  w16, [x16]
        and  w16, w16, #0x200000
        cbnz w16, .
        mov  x16, #0x4c0            // #1216
        mov  w17, #0x44             // #68
        movk x16, #0xc810, lsl #16
        str  w17, [x16]
        ret

/* head.S中preserve_boot_args进行跳转打印 */
preserve_boot_args:
        mov   x21, x0           // x21=FDT
        adr_1 x0, boot_args     // record the contents ofboot args
        stp   x21, x1, [x0]     // x0 .. x3 at kernel
entry
        stp   x2, x3, [x0, #16]
        b     uart_pputc        //debug print
        dmb   sy                // need before dc ivac
with MMU off 
<think>好的,用户想在STM32上配置和使用双串口进行打印操作。我需要根据提供的引用信息,结合自己的知识,给出清晰的步骤和建议。首先,用户提到的引用都是关于STM32不同型号的串口配置,特别是使用STM32CubeMX和HAL库的方法。需要注意用户可能使用的是STM32F103或F4系列,但配置步骤类似。 首先,用户需要配置两个串口,比如USART1和USART2。步骤应该包括在STM32CubeMX中启用这两个串口,设置正确的引脚,配置波特率等参数。然后生成代码,在生成的代码基础上添加中断和DMA的配置,确保两个串口可以同时工作。 引用[1]和[4]提到使用STM32CubeMX配置串口,包括时钟和引脚配置。引用[2]和[3]涉及中断处理和DMA的使用,以及使用printf函数重定向。用户需要双串口打印,所以可能需要为每个串口单独配置,或者重定向printf到其中一个,另一个用自定义函数发送数据。 接下来,需要检查用户是否需要同时使用中断或DMA来处理数据收发。例如,如果两个串口都需要频繁发送数据,使用DMA可能更高效,避免阻塞主程序。引用[2]提到DMA配置和中断处理,需要注意双缓冲区的使用和数据同步问题。 另外,用户可能需要在代码中分别初始化两个串口,并确保它们的时钟和GPIO正确配置。例如,USART1通常挂在APB2总线,而USART2在APB1,所以时钟使能时要选对。引用[3]中的代码示例展示了如何启用USART1的时钟,这可能对用户有帮助。 然后,关于printf的重定向,通常只能重定向到一个串口,所以另一个串口可能需要用自定义的发送函数,比如UART2_SendString。引用[3]也提到了使用printf,用户需要知道如何为第二个串口实现类似功能。 最后,测试部分需要用户验证两个串口是否能同时发送数据,比如在main循环中交替发送信息,或者通过中断接收数据。引用[2]中提到的空闲中断和DMA双缓冲区可能对接收数据有帮助,但用户的问题主要是打印功能,所以可能更关注发送部分。 总结步骤:配置两个串口,生成代码,添加发送函数,处理中断/DMA,重定向printf,测试。需要确保每个步骤都正确,尤其是时钟和引脚配置,避免冲突。同时,注意双串口同时使用的资源冲突问题,比如DMA通道是否被正确分配。</think>### STM32双串口打印功能配置步骤 #### 一、硬件与工具准备 1. 确认使用支持多串口的STM32型号(如STM32F103C8T6/F4系列) 2. 安装STM32CubeMX及对应HAL库 3. 准备USB转TTL模块(两个,对应双串口) #### 二、STM32CubeMX配置 1. **引脚分配**: - 选择USART1(通常PA9/PA10)和USART2(通常PA2/PA3) - 在Pinout视图确认引脚无冲突[^1][^4] 2. **参数配置**: ```c /* USART1配置示例 */ Mode: Asynchronous Baud Rate: 115200 Word Length: 8 Bits Parity: None Stop Bits: 1 /* USART2配置相同参数 */ ``` 注意APB总线时钟差异:USART1在APB2,USART2在APB1[^3] 3. **生成代码**: - 选择对应IDE(Keil/IAR等) - 勾选`Generate peripheral initialization as a pair of .c/.h files` #### 三、代码实现 1. **基础配置**: ```c /* main.c */ MX_USART1_UART_Init(); MX_USART2_UART_Init(); HAL_UART_Receive_IT(&huart1, &rx1_buf, 1); // 启用中断接收 HAL_UART_Receive_IT(&huart2, &rx2_buf, 1); ``` 2. **printf重定向(USART1)**: ```c #include <stdio.h> int __io_putchar(int ch) { HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, 10); return ch; } ``` 3. **自定义发送函数(USART2)**: ```c void UART2_Print(char *format, ...) { char buf[256]; va_list args; va_start(args, format); vsnprintf(buf, sizeof(buf), format, args); HAL_UART_Transmit(&huart2, (uint8_t*)buf, strlen(buf), 100); va_end(args); } ``` #### 四、中断配置 1. 在`stm32f1xx_it.c`中实现中断服务: ```c void USART1_IRQHandler(void) { HAL_UART_IRQHandler(&huart1); } void USART2_IRQHandler(void) { HAL_UART_IRQHandler(&huart2); } ``` 2. 接收回调函数: ```c void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart->Instance == USART1){ // 处理USART1接收数据 HAL_UART_Transmit(&huart1, &rx1_buf, 1, 10); } else if(huart->Instance == USART2){ // 处理USART2接收数据 HAL_UART_Transmit(&huart2, &rx2_buf, 1, 10); } } ``` #### 五、DMA优化(可选) 1. 在CubeMX中为两个串口分别配置DMA: - TX模式选择`Normal` - RX模式选择`Circular`[^2] 2. 使用双缓冲区策略: ```c __ALIGN_BEGIN uint8_t uart1_rx_buf[2][256]; HAL_UART_Receive_DMA(&huart1, uart1_rx_buf[0], 256); HAL_UART_Receive_DMA(&huart2, uart2_rx_buf[0], 256); ``` #### 六、测试验证 ```c while (1) { printf("USART1: Hello from UART1!\r\n"); UART2_Print("USART2: Hello from UART2!\r\n"); HAL_Delay(1000); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值