我已经看到这个主题已经在许多其他问题中讨论过,但我无法找到适合我的具体情况的答案。
我正在使用 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 …
我使用 CubeMx 来生成 USB 虚拟 com 端口设备的启动代码。效果很好。但我需要在 1 个 USB 接口上实现 2 个虚拟 com 端口。
我似乎找不到任何信息来源如何做到这一点。是否可以?
我正在使用一台 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,并且我在这里使用这个编程器。
我想连接到它们两个并独立调试/刷新/迭代。
所以,我的设置如下:
PC |-> USB1 -> ST-LINK-Programmer1 -> STM32_Board1
|-> USB2 -> ST-LINK-Programmer2 -> STM32_Board2
我通常用一块板来做这件事的方法非常简单。
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,但这也不起作用......套接字仍在使用中。
这样做的正确方法是什么?配置 …
我正在使用 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) 我已将 UART 配置为以 DMA 模式接收,其中缓冲区的大小约为 64 字节。因此,基本上,HAL_UART_RxCpltCallback() DMA 接收完成中断仅在接收到 64 个字符时才会触发。
STM32中有没有一种方法可以为DMA Rx配置超时,当缓冲区仅部分填充(即接收到的字符少于64个)并且我们在指定的超时时间内不再接收到任何字符时,DMA将然后引发相同的基于 HAL_UART_RxCpltCallback() 的中断,让消费者使用 UART 当前接收到的任何部分数据?
尝试在 STM32L476 Nucleo-64 板上调试我的示例眨眼 LED 代码,但 gdb 无法连接到 OpenOCD(连接几乎立即因错误而断开)。我到处读过很多帖子,但没有一个有帮助。尝试使用 -c 添加命令到 OpenOCD,但行为没有改变。
我的代码在 Eclipse 的发布和调试配置中进行编译。我可以使用拖放功能刷新 bin 文件(虽然该板具有内置 STLink 插件),并且看起来代码在板上完美运行(LED 闪烁)。
在Centos7上使用以下版本进行交叉编译:
由于使用 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) 我正在开发一个项目,其中涉及解析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 …
我正在使用带有 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) 正如标题所示,我想使用 swo 在 stm32F1 设备上进行调试,而不使用 st-link utils。我想我已经刷新了代码以通过我的芯片上的 swo 发送消息,但我无法与正确的设备建立连接一些教程建议我将 putty 与 telnet 端口 2332 一起使用。关于我的配置的具体信息:
我的 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。