Arm Mbed OS support forum

MAXREFDES101_Source_Code: Error in USBAudio.h: no member named 'attach' in 'mbed::Callback<void ()>

I am working with the MAXREFDES101_Source_Code and trying to compile it with Mbed Studio on Mbed-OS 6.
I could managed some errors depending on the older version of this Code but now i am coming to an end with my knowledge.
I changed the variable definition Functionpointer updateVol to Callback<void()> updateVol because Functionpointer doesn’t exist in Mbed OS 6 anymore. After that I get this error in the same Code a few lines above:
void attach(void(*fptr)(void)) {
updateVol.attach(fptr);
}
Error: No member named ‘attach’ in 'mbed::Callback<void ()>'clang(no_member)
I don’t know what I did wrong or with what I should change ‘attach’.
Thank you for any help!

Hello Jan-Niklas,

Try to assingn the fptr to the updateVol (which is now a Callback<void()> type) rather than calling attach(fptr), as follows:

void attach(void(*fptr)(void)) {
    updateVol = callback(fptr);
}

Before making the assignment call the callback(fptr) to cast the function pointerfptr to a Callback<void()> type.

Thank you Zoltan,
I think that worked!
I have an similar issue like this in LSO13B7DH03.cpp with _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.01f);
The Error told me the same as my former problem. Can I use your solution here too? In this case I have more arguments and this seems to be another problem for the program.

I think in this case the problem seems to be different. The _csTimeout data member is a Timeout which has various attach methods defined. Could you show us the error reported by the compiler?

Sure, there are three errors in this file:
First:
//Save pointer to spi peripheral

_spi = spi;

//_spi->frequency(600000);

_spi->format( 8, 0 );

_internalEventCallback.attach(this, &LS013B7DH03::_cbHandler);

Second:
// Activate LCD

_CS->write(1);

_csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.01f);

return LS013B7DH03_OK;

}
Third:
// Wait for the ChipSelect line

_CS->write(1);

_csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.01f);

return LS013B7DH03_OK;

}

in each of these lines the error says: no member named ‘attach’ in ‘mbed::Callback<void (int)>’

Is the _csTimeout data member defined as mbed::Timeout _csTimeout; in the LS013B7DH03.h file? If yes, try to replace

_csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.01f);

with

_csTimeout.attach(callback(this, &LS013B7DH03::_cbHandlerTimeout), 10ms);

and

_internalEventCallback.attach(this, &LS013B7DH03::_cbHandler);

with

_internalEventCallback.attach(callback(this, &LS013B7DH03::_cbHandler));

When I do this, the compiler says that he have to many arguments (expecting 0 but got 2 or 3)
Too many arguments to function call, expected 0, have 3clang(typecheck_call_too_many_args)

too many arguments, expecting 0 but got 2 or 3

If the _csTimeout is a Timeout then the attach method has to have two arguments. First is the callback function to be called when a time period elapsed. The second argument specifies the time period. Please check my previous reply. I modified it to always pass two arguments to the _csTimeout.attach method.

NOTE: To pass 0 parameters to the attach method doesn’t make any sense (there is nothing to attach).

I understand that, I dont know why I get this message…
When I try to co,pile again, this is my Error output:
[Error] LS013B7DH03.cpp@67,25: no member named ‘attach’ in ‘mbed::Callback<void (int)>’
[Error] LS013B7DH03.cpp@125,29: too many arguments to function call, expected 0, have 2
[Error] LS013B7DH03.cpp@170,29: too many arguments to function call, expected 0, have 2

[Error] LS013B7DH03.cpp@67,25: no member named ‘attach’ in ‘mbed::Callback<void (int)>’

The _internalEventCallback seems to be of a ‘mbed::Callback<void (int)> so try to replace

_internalEventCallback.attach(this, &LS013B7DH03::_cbHandler);

with

_internalEventCallback = callback(this, &LS013B7DH03::_cbHandler);

The other two errors are very strange. Please check again in the LS013B7DH03.h header file the type of the _csTimeout data member. Is it really a Timeout.
Could you please let us know the version of Mbed OS 6 you use to build the program?

The first error seems to be fixed now, thank you!

For the other two errors I searched in my LS013B7DH03.h file and there is in line 100 _csTimeout defined as Timeout: mbed::Timeout _csTimeout;
My OS 6 version is the mbed-os 6.12.0

The problem is caused by using callback as parameter name in the function definition.
This results in name clash with the callback function used for casting the function pointer to a Callback
Try to rename the function parameter callback, for example to callbackPtr. Remember to change it also in the header file and in the function’s body as follows:

int LS013B7DH03::update( cbptr_t callbackPtr ) {
    ...
    _completionCallbackPtr = callbackPtr;
    ...
    _csTimeout.attach(callback(this, &LS013B7DH03::_cbHandlerTimeout), 10ms);
    ...
}
int LS013B7DH03::clearImmediate( cbptr_t callbackPtr ) {
    ...
    _completionCallbackPtr = callbackPtr;
    ...
    _csTimeout.attach(callback(this, &LS013B7DH03::_cbHandlerTimeout), 10ms);
    ...
}

Thank you again Zoltan! It seems that the compiler have no error in this field anymore.
But I have another question, I hope thats ok…
After this error I got a new one which says, that I have an undeclared identifier BLE in BLE_ICARUS.h. In this file the ble/BLE.h which should be included could not found. Could that be a problem because I used the MAX32630FTHR as target which have no BLE feature?
I am using this target because the Maxim Integrated page told me to do that.

You can pretend that the MAX32630FTHR has a BLE feature by modifying the mbed-os/targets/targets.json file as follows:

...
    "MAX32630FTHR": {
...
        "features_add": [
            "STORAGE",
            "BLE"
        ],
...

Then try to compile the program and see how it works out.

Now I get many errors in BLE_ICARUS, the first one can not include build_version.h :
[Error] build_version.h@1,1: expected unqualified-id

Hopefully the other errors will be eliminated if this one could be fixed…
Do you have an idea why I get this error?

In BLE_ICARUS.cpp we have:

#include "Peripherals.h"
#include "../../version.h"

In version.h we have:

#include "build_version.h"

The [Error] build_version.h@1,1: expected unqualified-id could mean that something is wrong before this line. It means there is something wrong in the Peripherals.h file. Indeed, the code is trying to use the Serial class which doesn’t exist in Mbed OS 6.5 and higher anymore (hence, Serial is an unqualified-id):

...
#include "Serial.h"
...
class Peripherals {
public:
...
    static Serial *setDaplinkSerial(Serial * device) { mDaplinkSerial = device; return device; }
    static Serial *daplinkSerial(void) { return mDaplinkSerial; }
...
private:
...
    static Serial *mDaplinkSerial;
...
};

You can try to replace the Serial class with SerialBase or UnbufferedSerial.

Ok but I already changed the Serial.h version with the BufferedSerial.h because of the new version of mbed. Is this also correct or should I changed it to unbufferedSerial?

This is what the documentation says:

Unlike the BufferedSerial class, the UnbufferedSerial class does not use intermediary buffers to store bytes to transmit to or read from the hardware. The user application is responsible for processing each byte as it is received. The method to read data returns only one byte for every call. Therefore, we recommend you use this class when you need more control and for use in interrupt handlers with the RTOS. You can also use this class to write multiple bytes at once. Because it does not acquire a mutex lock, you must ensure only one instance uses the serial port.

For normal blocking applications that require a serial channel for something other than the console, BufferedSerial performs better than UnbufferedSerial and causes less CPU load and fewer latency issues. Only applications that are short of RAM and cannot afford buffering or that need more control of the serial port and use it from IRQ should use UnbufferedSerial.

You can view more information about the configurable settings and functions in the class reference.

So my conclusion is, if there are some interrupt handles using the Serial, according to the documentation you should use the UnbufferedSerial. Otherwise, the BufferedSerial performs better.

Allright I changed the BufferedSerial to UnbufferedSerial in Peripherals.h in the class Peripherals as you explained above. Now I got this errors exactly in the lines I already changed:
changed lines:
static UnbufferedSerial *setDaplinkSerial(UnbufferedSerial * device) { mDaplinkSerial = device; return device; }
static UnbufferedSerial *daplinkSerial(void) { return mDaplinkSerial; }

Errors:
[Error] Peripherals.h@86,93: incompatible pointer types assigning to ‘mbed::BufferedSerial *’ from ‘mbed::UnbufferedSerial *’
[Error] Peripherals.h@87,59: cannot initialize return object of type ‘mbed::UnbufferedSerial *’ with an lvalue of type ‘mbed::BufferedSerial *’
[ERROR] In file included from .\Drivers\MAX30001\MAX30001.cpp:37:

Did I missed something?

In the private section of the Peripherals class change the type of mDaplinkSerial to UnbufferedSerial* too, as shown below:

class Peripherals {
public:
...
private:
...
   static UnbufferedSerial *mDaplinkSerial;
...
};