标签: stm32

STM32 SPI 硬件和严格别名警告

我已经看到这个主题已经在许多其他问题中讨论过,但我无法找到适合我的具体情况的答案。

我正在使用 STM32F0 微控制器。SPI 接收/发送 FIFO 的顶部可通过存储器访问进行访问。这个特殊的微控制器允许我从 FIFO 顶部读取/写入 8 位或 16 位。更准确地说,当执行 LDRB/STRB 指令时,将 8 位从 FIFO 弹出/推送到 FIFO,而当执行 LDRH/STRH 指令时,将从 FIFO 弹出/推送 16 位。

STMicroElectronics 提供的硬件抽象层提出了这种语法来读取 SPI FIFO。

return *(volatile uint8_t*)&_handle->Instance->DR; // Pop 1 byte
return *(volatile uint16_t*)&_handle->Instance->DR; // Pop 2 byte

*(volatile uint8_t*)&_handle->Instance->DR = val; // Push 1 byte
*(volatile uint16_t*)&_handle->Instance->DR = val; // Push 2 bytes
Run Code Online (Sandbox Code Playgroud)

SPI FIFO 顶部的DR一个指针在哪里uint32_t*

我已经使用这种语法构建了我的软件,并且它工作得很好。唯一的问题是 g++ 抛出了很多关于类型双关的警告。更确切地说:

Inc/drivers/SPI.h:70:50:警告:取消引用类型双关指针将破坏严格别名规则 [-Wstrict-aliasing] return *(volatile uint16_t*)&_handle->Instance->DR;

经过一些阅读后,看起来在 C++ 中使用 union 并不是一个好主意。无论如何我确实尝试过但遇到了一些问题。实际上,通过联合中的指针访问内存会使我的微控制器崩溃,就像未对齐的内存访问一样。

static_cast …

c++ microcontroller hal stm32 type-punning

5
推荐指数
1
解决办法
1289
查看次数

STM32双CDC(VCP)类

我使用 CubeMx 来生成 USB 虚拟 com 端口设备的启动代码。效果很好。但我需要在 1 个 USB 接口上实现 2 个虚拟 com 端口。

我似乎找不到任何信息来源如何做到这一点。是否可以?

usb cdc stm32

5
推荐指数
1
解决办法
6450
查看次数

STM32F4 I2C 与 DMA 不工作

我正在使用一台 STM32F4,我想与我的 LSM303 加速度计进行通信。为此,我使用 I2C,仅使用 I2C 工作正常,但当我尝试使用 DMA 时,它停止工作。当我使用 HAL_I2C_Master_Transmit_DMA 时,它可以工作,并且我得到了 IRQHandler 和 . 但是之后当我想使用 HAL_I2C_Master_Receive_DMA 时,它说 I2C 的状态尚未准备好...我读到 I2C 与 STM32FX 有点混乱,但我不明白为什么它在没有 DMA 的情况下工作正常。

此外,当它命中 Master_Transmit_DMA 的回调 I2C_DMAXferCplt 时,它表示 I2C_HandleTypeDef 的 CurrentState 仍然等于 HAL_I2C_STATE_BUSY_TX,因此它不会将状态恢复为 READY。这就是为什么当我调用 Master_Receive_DMA 时它没有收到任何东西。

这是我的 I2C 初始化:

    void MX_I2C2_Init(void)
      {
          I2C_ST_INS.Instance = I2C2;
          I2C_ST_INS.Init.ClockSpeed = 400000;
           I2C_ST_INS.Init.DutyCycle = I2C_DUTYCYCLE_2;
           I2C_ST_INS.Init.OwnAddress1 = 0;
          I2C_ST_INS.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
          I2C_ST_INS.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
          I2C_ST_INS.Init.OwnAddress2 = 0;
          I2C_ST_INS.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
          I2C_ST_INS.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;

          HAL_I2C_Init(&I2C_ST_INS);

        }

   void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
   {
          GPIO_InitTypeDef GPIO_InitStruct;
          if(i2cHandle->Instance==I2C1) …
Run Code Online (Sandbox Code Playgroud)

stm32 i2c dma

5
推荐指数
2
解决办法
5708
查看次数

如何使用 OpenOCD 同时与两块 STM32 板通信?

假设我有两个 STM32,并且我在这里使用这个编程器。

我想连接到它们两个并独立调试/刷新/迭代。

所以,我的设置如下:

硬件

PC |-> USB1 -> ST-LINK-Programmer1 -> STM32_Board1 |-> USB2 -> ST-LINK-Programmer2 -> STM32_Board2

SW

我通常用一块板来做这件事的方法非常简单。

openocd -f config.cfg

这是我调用的配置文件:

source [find interface/stlink-v2.cfg] transport select hla_swd source [find target/stm32f4x.cfg] reset_config none

然后,在另一个终端中,我像这样调用arm-gdb:

arm-none-eabi-gdb build/FW.elf

在 ~/.gdbinit 中,我有这一行:

target remote localhost:3333

什么不起作用

这是非常明显的...我为第一个 OpenOCD 使用端口 3333,但第二个实例尝试使用相同的端口并失败

Error: couldn't bind tcl to socket: Address already in use

我尝试过的

我已经查看了此处的文档,但我无法了解如何在我的config.cfg文件中调用这些选项。

我还尝试将有关 tcl_port 和 gdb_port 的这些命令添加到实际的命令行参数中,例如 openocd -f config.cfg -c tcl_port 4444,但这也不起作用......套接字仍在使用中。

我真正的问题

这样做的正确方法是什么?配置 …

debugging gdb arm stm32 openocd

5
推荐指数
1
解决办法
5680
查看次数

在 Nucleo STM32 板上设置 SWV printf

我正在使用 Atollic Truestudio IDE(基本上是 Eclipse)在各种 STM32L4 Nucleo 板上开发固件。到目前为止,我一直通过 UART 使用 printf,这要归功于虚拟 COM 端口。

我想使用 STM32 ITM 迁移到 printf。

更准确地说,我致力于 Nucleo-L4A6ZG。调试是通过 gdb 服务器进行的。

在 Atollic 上,我修改了调试配置以启用核心时钟为 80MHz 的 SWV。我按照 STM32L4 参考手册中的描述修改了启动脚本,如下所示。我不确定这是必要的,因为 TrueStudio/Eclipse 允许从 GUI 设置 SWV,但这种方式似乎更容易:

# Set character encoding
set host-charset CP1252
set target-charset CP1252

# Reset to known state
monitor reset

# Load the program executable
load        

# Reset the chip to get to a known state. Remove "monitor reset" command 
#  if the code is not located at …
Run Code Online (Sandbox Code Playgroud)

debugging arm stm32 nucleo

5
推荐指数
1
解决办法
8770
查看次数

指定超时后有意接收完成 UART DMA 中断

我已将 UART 配置为以 DMA 模式接收,其中缓冲区的大小约为 64 字节。因此,基本上,HAL_UART_RxCpltCallback() DMA 接收完成中断仅在接收到 64 个字符时才会触发。

STM32中有没有一种方法可以为DMA Rx配置超时,当缓冲区仅部分填充(即接收到的字符少于64个)并且我们在指定的超时时间内不再接收到任何字符时,DMA将然后引发相同的基于 HAL_UART_RxCpltCallback() 的中断,让消费者使用 UART 当前接收到的任何部分数据?

stm32 dma stm32f4 stm32f7

5
推荐指数
1
解决办法
3446
查看次数

Gdb无法连接stm32上的OpenOCD

尝试在 STM32L476 Nucleo-64 板上调试我的示例眨眼 LED 代码,但 gdb 无法连接到 OpenOCD(连接几乎立即因错误而断开)。我到处读过很多帖子,但没有一个有帮助。尝试使用 -c 添加命令到 OpenOCD,但行为没有改变。

我的代码在 Eclipse 的发布和调试配置中进行编译。我可以使用拖放功能刷新 bin 文件(虽然该板具有内置 STLink 插件),并且看起来代码在板上完美运行(LED 闪烁)。

在Centos7上使用以下版本进行交叉编译:

  • 工具链(gdb):gcc-arm-none-eabi-8-2018-q4-major
  • OpenOCD:0.10.0-11-20190118-1134

由于使用 eclipse 不起作用,我尝试了命令行,

(我在这个环境中不是经验丰富的开发人员,所以我找不到比 stm32l4discovery.cfg 更接近我的 stm32l476 板的配置文件,如果使用它可能出现一些问题,请告诉我)

./bin/openocd -f scripts/board/stm32l4discovery.cfg -c "init"
Run Code Online (Sandbox Code Playgroud)

开始,

GNU MCU Eclipse 64-bit Open On-Chip Debugger 0.10.0+dev-00462-gdd1d90111 (2019-01-18-11:37)
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
adapter speed: 500 kHz
adapter_nsrst_delay: 100 …
Run Code Online (Sandbox Code Playgroud)

gdb stm32 openocd

5
推荐指数
1
解决办法
1万
查看次数

Arm:objcopy 如何知道 elf 中的哪些部分包含在二进制或 ihex 中?

我正在开发一个项目,其中涉及解析arm elf 文件并从中提取部分。

显然,elf 文件中有很多部分没有加载到闪存中,但我想知道 objcopy 到底如何知道要在二进制文件中包含哪些部分以直接闪存到闪存中?

以arm elf文件的以下readelf为例:

节标题: [Nr] 名称 类型 地址 关闭大小 ES Flg Lk Inf Al

[0] 空 00000000 000000 000000 00 0 0 0

[1] .isr_vector PROGBITS 08020000 010000 0001f8 00 WA 0 0 4

[2].firmware_header_PROGBITS 080201f8 0101f8 000004 00 WA 0 0 4

[3] .text PROGBITS 08020200 010200 01e11c 00 AX 0 0 64

[4] .ARM.extab PROGBITS 0803e31c 033a68 000000 00 W 0 0 1

[5] .exidx ARM_EXIDX 0803e31c 02e31c 000008 00 AL 3 …

c embedded linker elf stm32

5
推荐指数
1
解决办法
1380
查看次数

STM32:使用带有字符匹配ISR和DMA缓冲区的USART

我正在使用带有 FreeRTOS 和 STM32CubeMX 的STM32L432设备。

我尝试通过基于 ASCII 协议的 USART 实现 M2M 通信。协议序列的长度可以不同,但​​具有最大长度和定义的结束字符 (' \r ' / 0x0D )。

因此,我考虑使用 DMA(如FIFO)收集所有 RX-USART 数据,并使用基于USART_ICR_CMCF标志的地址匹配 isr 来确定结束字符。

初始化USART1并启用地址匹配ISR

void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle) {
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(uartHandle->Instance==USART1) {
    /* USART1 clock enable */
    __HAL_RCC_USART1_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();
    GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* USART1 interrupt Init */
    HAL_NVIC_SetPriority(USART1_IRQn, 5, 0);
    HAL_NVIC_EnableIRQ(USART1_IRQn);

    /* USER CODE BEGIN USART1_MspInit 1 …
Run Code Online (Sandbox Code Playgroud)

fifo stm32 dma usart stm32cubemx

5
推荐指数
1
解决办法
3020
查看次数

在stm32上使用调试器swo

正如标题所示,我想使用 swo 在 stm32F1 设备上进行调试,而不使用 st-link utils。我想我已经刷新了代码以通过我的芯片上的 swo 发送消息,但我无法与正确的设备建立连接一些教程建议我将 putty 与 telnet 端口 2332 一起使用。关于我的配置的具体信息:cubemx swo 配置 我的 main 上的相关代码

    int _write(int file, char *ptr, int len)
{
    int DataIdx;
    for (DataIdx = 0; DataIdx < len; DataIdx++)
    {
        __io_putchar(*ptr++);
    }
    return len;
}
Run Code Online (Sandbox Code Playgroud)

...

   int main(){
    while (1)
      {
        printf("Hi\n");
      }
}
Run Code Online (Sandbox Code Playgroud)

我看过一些使用 eclipse 配置或 st-link utils 的教程,但我有一个非常自定义的工具链(我使用 conan、obko cmake 配置https://github.com/ObKo/stm32-cmake、 ocb 和 linux )用于唯一目的使用 c++ 2017 和 boost 这样的库,所以我不能使用 st-link utils。

c c++ stm32 jtag

5
推荐指数
1
解决办法
1827
查看次数

标签 统计

stm32 ×10

dma ×3

arm ×2

c ×2

c++ ×2

debugging ×2

gdb ×2

openocd ×2

cdc ×1

elf ×1

embedded ×1

fifo ×1

hal ×1

i2c ×1

jtag ×1

linker ×1

microcontroller ×1

nucleo ×1

stm32cubemx ×1

stm32f4 ×1

stm32f7 ×1

type-punning ×1

usart ×1

usb ×1