- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我也在 STM32 社区论坛中发布了相同的 question,但没有收到回复。
我在启用了 C++14 的项目中使用 stm32 HAL 库。它向我发出以下警告,我无法摆脱。
../platform/stm32/l4/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc.h:735:57:
warning: conversion to void will not access object of type 'volatile uint32_t {aka volatile long unsigned int}' UNUSED(tmpreg); \
当调用 __GPIOX_CLK_ENABLE() 或 __HAL_RCC_GPIOX_CLK_ENABLE 时会发生这种情况。
有没有人能够摆脱上述警告而使 HAL 源代码完好无损。
或者任何可以做的事情的想法。
当前警告级别为-Wall。
我在 l4 和 f4 系列代码中都遇到过上述问题。
示例代码:
int main(void)
{
HAL_Init();
__GPIOB_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Pin = GPIO_PIN_7;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_InitStructure.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
for (;;)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
HAL_Delay(500);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
HAL_Delay(500);
}
}
罪魁祸首是 __GPIOB_CLK_ENABLE()
,它被扩展为以下内容(在 ST 驱动程序中)。
#define __HAL_RCC_GPIOB_CLK_ENABLE() do { \
__IO uint32_t tmpreg; \
SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOBEN); \
/* Delay after an RCC peripheral clock enabling */ \
tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOBEN); \
UNUSED(tmpreg); \
} while(0)
我最初的问题是想找到一个解决方案,让底层的 ST 驱动程序完好无损。一种可能的解决方案是使用直接寄存器访问,而无需通过提供方便的宏的库。
提前谢谢你。
最佳答案
问题是 -std=c++14
将 volatile
表达式的语义转换为 (void)
,并引入了一个显然*无条件警告它,并且 ST 的一名编码员试图“三重确定”寄存器读取将发生。
UNUSED()
宏的定义是
#define UNUSED(x) ((void)(x))
和__IO
定义为
#define __IO volatile
那么 __HAL_RCC_GPIOB_CLK_ENABLE()
的扩展就是
do {
volatile uint32_t tmpreg;
RCC->AHB2ENR |= RCC_AHB2ENR_GPIOBEN;
/* Delay after an RCC peripheral clock enabling */
tmpreg = RCC->AHB2ENR & RCC_AHB2ENR_GPIOBEN;
((void)(tmpreg));
} while(0)
寄存器的延时和回读是各种STM32 errata saying推荐的
A delay between an RCC peripheral clock enable and the effective peripheral enabling should be taken into account in order to manage the peripheral read/write to registers.
[...]
insert a dummy read operation from the corresponding register just after enabling the peripheral clock.
由于所有外设寄存器当然都被声明为 volatile
,一个仅包含相关寄存器的简单表达式将强制通过相同的外设总线进行具有必要等待状态的回读,因此这就足够了:
do {
RCC->AHB2ENR |= RCC_AHB2ENR_GPIOBEN;
/* Delay after an RCC peripheral clock enabling */
RCC->AHB2ENR;
} while(0)
其余的可能是针对一些有缺陷的编译器的过度设计的解决方法,但我还没有看到一个如此糟糕以至于可以优化 volatile 类型的表达式。
然而,存在边缘情况,将 volatile 变量强制转换为 (void)
,其中语义在 C++14 中明显发生了变化。
让我们举个简单的例子
void x() {
volatile int t;
t=1;
((void)(t));
}
Arm gcc 7.2.1 invoked with -O3 -mcpu=cortex-m4 -mthumb -Wall -x c++ -std=c++11
将其编译为
x():
sub sp, sp, #8
movs r3, #1
str r3, [sp, #4]
ldr r3, [sp, #4]
add sp, sp, #8
bx lr
和the same code compiled with -std=c++14
是
x():
sub sp, sp, #8
movs r3, #1
str r3, [sp, #4]
add sp, sp, #8
bx lr
...和一个警告:
<source>: In function 'void x()':
<source>:5:13: warning: conversion to void will not access object of type 'volatile int'
((void)(t));
~^~
另请注意第二种情况中缺少的 ldr
指令。使用 C++14 写入后不会访问该变量。
My original question is intended to find out a solution, leaving the underlying ST driver intact. One possible solution would be to use the direct register access without going through the library provided convenient macro.
我建议继续前进并避免使用库,恕我直言,HAL 最好被视为示例或实现建议的集合。
*我找不到禁用它的方法。这并不意味着没有。
关于c++ - C++14及以上的stm32 hal库警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49061212/
我需要移植一个 bash 脚本,它使用已弃用的 HAL 工具,如 hal-get-property或 hal-find-by-capability去开发。 HAL声明 HAL 已合并到 udev,但我
我正在研究 Spring Data REST,特别是 HAL 浏览器。我一直在关注 http://docs.spring.io/spring-data/rest/docs/current/refere
Level 3例如,RESTful API 的功能自定义媒体类型,如 application/vnd.service.entity.v1+json。在我的情况下,我使用 HAL在我的 JSON 中提供
我在 PropertyNotified 信号期间从处理程序调用 org.freedesktop.Hal.Device 上的 GetProperty。我仅对已添加或更改的属性调用 GetProperty
我正在尝试理解另一位程序员编写的代码。它使用I²C通信以将数据写入 STM32 微 Controller 的 EEPROM。 一般来说我理解他的代码是如何工作的,但我不明白他为什么使用HAL_LOCK
我正在研究如何实现针对多个微 Controller 的自定义C++ HAL,这些微 Controller 可能具有不同的体系结构(ARM,AVR,PIC等),同时又保持良好的状态。 我继承了几个大型的
我正在做一个 C++(使用 cmake)嵌入式 HAL 层,并尝试添加一个特定于某些 MCU 的库。现在这里的问题是从上层访问库函数。 我的解决方案是使用该特定板的 cmake 文件来定义一个宏,在该
对于在 x86 硬件上运行的 Linux 操作系统,要在内核中调用作为 TCP/IP 驱动程序(对于 x86)的一部分的 TCP_listen(),用户空间客户端应用程序调用 listen() 接口(
跟随我的post我想知道驱动程序和 HAL 之间有什么区别? 最佳答案 从这里doc : 硬件硬件抽象层定义了相机服务调用的标准接口(interface),您必须实现该接口(interface)才能使
在Linux中,HAL提供硬件抽象,设备驱动也提供硬件抽象。你能解释一下两者之间的区别吗? 最佳答案 设备驱动程序在特定缓冲区和控制标志 block 位置与特定设备通信。硬件抽象层抽象出特定设备如何工
我在通过 USART 接收数据时遇到了一些麻烦。我真正想要实现的是,我可以通过 USART 接收没有特定长度(只有最大可能长度)的命令。所以我使用中断例程来检查接收到的每个字符,但不知何故我仍然无法实
我正在使用 Spring Boot 2 构建一个 API,而 Angular 6 客户端必须处理如下响应: { "_embedded" : { "userResourceList" : [
我有以下问题 我有 Spring 数据休息的基本配置(没什么特别的,没什么自定义的)。 使用 spring-data-rest-webmvc 2.0.0 RELEASE 和 spring-data-j
我试图在我的 stm32f4 发现上闪烁 LED。不知何故,它停留在延迟功能上。我已将 SysTick 中断优先级更改为 0 并添加了 IncTick() , GetTick()职能。我错过了什么?
干杯... 我知道它代表硬件抽象层,但它到底是做什么的?它是为 VB 等高级语言设计的与硬件通信吗? IN/OUT 指令是调用 HAL 例程还是通过 I/O 管理器直接与硬件的设备驱动程序通信? 提前
哪里可以找到 DirectX HAL 规范? 服用 this diagram正确 然后所有 GPU 供应商都必须编写他们的设备驱动程序,以便他们与 HAL 对话。 HAL 在哪里指定? MSFT 如何
我正在做一个需要设置简单 LCD 的项目。此 LCD 使用 'st7032i' 芯片来控制 LCD。 我想通过 I²C 接口(interface)控制 LCD。 作为 Controller ,我使用
我遇到了以下问题:我的电子板上有 2 个输入: #define TOR1_IN_uC_Port GPIOC #define TOR1_IN_uC_Pin GPIO_P
大家好,我正在尝试使用 stm32 HAL 库进行串行 rx 中断,但出现了我不知道的错误。 这是一个非常简单的程序。 PC 将字节提供给 stm32 板,stm32 将使用 rx 中断例程获取这些字
我正在尝试找到一种标记 USB 闪存设备的方法,以便我可以通过编程方式进行测试,而无需安装它或更改标签。 我是否可以修改设备的任何属性,而不会导致设备的行为/外观对用户而言有所不同? 运行 Ubunt
我是一名优秀的程序员,十分优秀!