Skip to content

Ticker::once_ms() warning when used with argument #6155

Closed
@mrengineer7777

Description

@mrengineer7777

Board

ESP32 Feather

Device Description

Adafruit ESP32 Feather dev board

Hardware Configuration

No

Version

v2.0.2

IDE Name

PlatformIO in Visual Studio Code

Operating System

Win10

Flash frequency

N/A

PSRAM enabled

no

Upload speed

115200

Description

Compiling Ticker give me a warning.

Calling this works fine, no warning:
Save_Ticker.once_ms(ms, EP_Save);

Calling this results in a worrisome warning message:
WiFiCtrl.SoftAP_Shutdown_Timer.once_ms(1000*timeout_secs, ShutdownSoftAP, u);

The difference is that the callback function "ShutdownSoftAP" has a parameter "u". It is this parameter that the compiler complains about. It seems to be an issue with the template in Ticker.h.

Background:
I am compiling under native IDF because I need access to functions that don't exist yet in Arduino. I have copied in arduinoespressif\cores and arduinoespressif\library\Ticker. I did fix many circular include dependencies. I am NOT compiling Arduino as IDF component. Tried that, finally gave up.

Targeting: platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.2idf/platform-espressif32-2.0.2.zip
This uses IDF 4.4, Arduino 2.0.2
https://github.com/tasmota/platform-espressif32/releases/tag/v2.0.2idf

Sketch

void WiFiCtrlClass::ScheduleSoftAPShutdownTimeSecs(uint32_t timeout_secs, bool DisconnectClients) {
  //Serial.printf("Scheduling SoftAP shutdown for %u secs\r\n", timeout_secs);

  uint32_t u;
  DisconnectClients == true ? u=1 : u=0;

  if(timeout_secs == 0)
    WiFiCtrl.SoftAP_Shutdown_Timer.detach();
  else
    WiFiCtrl.SoftAP_Shutdown_Timer.once_ms(1000*timeout_secs, ShutdownSoftAP, u);
}

void static ShutdownSoftAP(uint32_t disconnect_clients) {
  if(disconnect_clients==0 && WiFi.softAPgetStationNum()>0) {                         //Client is still connected. Try again in 1 minute.
      Serial.printf("ShutdownSoftAP() Clients=%u\r\n",WiFi.softAPgetStationNum());
      WiFiCtrl.ScheduleSoftAPShutdownTimeSecs(10, false);
      return;
    }
    //Serial.println("Shutting down SoftAP");
    WiFi.enableAP(false);
}

---From Ticker.h---
template<typename TArg>
  void once_ms(uint32_t milliseconds, void (*callback)(TArg), TArg arg)
  {
    static_assert(sizeof(TArg) <= sizeof(uint32_t), "attach_ms() callback argument size must be <= 4 bytes");
    uint32_t arg32 = (uint32_t)(arg);
    _attach_ms(milliseconds, false, reinterpret_cast<callback_with_arg_t>(callback), arg32);
  }

Debug Message

lib/Ticker/Ticker.h:92:37: warning: cast between incompatible function types from 'void (*)(unsigned int)' to 'Ticker::callback_with_arg_t' {aka 'void (*)(void*)'} [-Wcast-function-type]
     _attach_ms(milliseconds, false, reinterpret_cast<callback_with_arg_t>(callback), arg32);

It appears to be unhappy with casting (unsigned int) to (void*).

Other Steps to Reproduce

Originally my callback function had a Boolean parameter, but I changed it to uint32_t because the template casts it to uint32_t. I get pretty much the same warning.

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.

Activity

mrengineer7777

mrengineer7777 commented on Jan 19, 2022

@mrengineer7777
CollaboratorAuthor

Possibly related: #2849
The proposed change modifies once_ms so that it no longer casts the argument.

template<typename TArg> void once_ms(uint64_t milliseconds, void (*callback)(TArg), TArg arg) { static_assert(sizeof(TArg) <= sizeof(void*), "attach() callback argument size must be <= sizeof(void*)"); _attach_us(1000ULL * milliseconds, false, reinterpret_cast<callback_with_arg_t>(callback), (void*)arg); }

Edit: just tested with modified library in #2849. It still gives the same warning :(

VojtechBartoska

VojtechBartoska commented on Apr 11, 2022

@VojtechBartoska
Contributor

Hello, can you please retest this on v2.0.3-rc1?

mrengineer7777

mrengineer7777 commented on Apr 11, 2022

@mrengineer7777
CollaboratorAuthor

Retested, still fails. Not surprising since v2.0.3-rc1 didn't modify Ticker.h.

In file included from lib/WiFiCtrl/WiFiCtrl.h:4,
                 from lib/WiFiCtrl/WiFiCtrl.cpp:1:
lib/Ticker/Ticker.h: In instantiation of 'void Ticker::once_ms(uint32_t, void (*)(TArg), TArg) [with TArg = unsigned int; uint32_t = unsigned int]':
lib/WiFiCtrl/WiFiCtrl.cpp:541:80:   required from here
lib/Ticker/Ticker.h:92:37: warning: cast between incompatible function types from 'void (*)(unsigned int)' to 'Ticker::callback_with_arg_t' {aka 'void (*)(void*)'} [-Wcast-function-type]
     _attach_ms(milliseconds, false, reinterpret_cast<callback_with_arg_t>(callback), arg32);

Setup: VSCode with Platformio.
platformio.ini config:

framework = espidf
platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.3rc1/platform-espressif32-2.0.3.zip

Note: since framework is IDF, my project includes a copy of Ticker.c/h. Yes I updated them.

Also note: I started a separate project with framework=arduino and was able to implement most needed functionality. The warning message about once_ms() does not occur for the Arduino framework, likely because the libraries are precompiled. The warning message is annoying but at the moment we aren't developing under IDF. I will understand if you want to close out this issue.

VojtechBartoska

VojtechBartoska commented on Apr 11, 2022

@VojtechBartoska
Contributor

Thanks for testing, I'm adding this to our Roadmap and we will take a look on it.

newHeiko

newHeiko commented on Oct 8, 2022

@newHeiko

JFTR: I updated my arduino-esp32 core to 2.0.5 today and this warning now shows up when compiling using the Arduino IDE as well.

Minimalist sketch to reproduce:

#include <Ticker.h>

Ticker tick;

void callbackFunc(int i)
{
  // just a dummy to do something with the parameter
  delay(i);
}

void setup() {
  // put your setup code here, to run once:
  tick.attach(1000, callbackFunc, 30);
}

void loop() {
  // put your main code here, to run repeatedly:
}

Warning message:

In file included from /home/heiko/elektronik/arduino-bugreport/sketch_oct08a/sketch_oct08a.ino:1:
/home/heiko/.arduino15/packages/esp32/hardware/esp32/2.0.5/libraries/Ticker/src/Ticker.h: In instantiation of 'void Ticker::attach(float, void (*)(TArg), TArg) [with TArg = int]':
/home/heiko/elektronik/arduino-bugreport/sketch_oct08a/sketch_oct08a.ino:13:37:   required from here
/home/heiko/.arduino15/packages/esp32/hardware/esp32/2.0.5/libraries/Ticker/src/Ticker.h:58:38: warning: cast between incompatible function types from 'void (*)(int)' to 'Ticker::callback_with_arg_t' {aka 'void (*)(void*)'} [-Wcast-function-type]
     _attach_ms(seconds * 1000, true, reinterpret_cast<callback_with_arg_t>(callback), arg32);
                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Compiling for ESP32-S2, compiler warnings: All.

Hope this helps,
Heiko

P.S: With my limited understanding of C++ templates, I guess the issue is the hard "void *" argument of callback_with_arg_t vs. the more flexible TArg.

self-assigned this
on Jan 4, 2023
added this to the 2.0.7 milestone on Jan 4, 2023

11 remaining items

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Status: Needs investigationWe need to do some research before taking next steps on this issue

Type

No type

Projects

Status

Done

Relationships

None yet

Development

No branches or pull requests

Issue actions

    Ticker::once_ms() warning when used with argument · Issue #6155 · espressif/arduino-esp32