Newest decadriver for DW3000 family

Hi,
It seems dwt_getframelength() call corrupts stack memory, and results overwriting other local variables memories. We discussed it in the link.

I’ve been heard that new library shall be open source code that is used to be, and give more flexibilities to compilers have it optimised with whatever settings are enabled/disabled (-O1, -O2). Is this new library available already, or do you have a release/expected date? I’ve tested 6.0.14 (binary base) but this issue remains.

Can you get the dw instance and try dw->ioctl()?

Do you mean something like this?

uint16_t len = ((dwchip_s*)dw3000_probe_interf.dw)->ioctl();

I’m not able to access ->ioctl()

Hi @alliv,

What do you mean by the dw instance? The below function probes the correct dw driver and makes .dw valid.

dwt_probe((struct dwt_probe_s *)&dw3000_probe_interf);

But I cannot access dw->ioctl() from an above structure.

2nd part of my question is about clarifying if decadriver library shall be open source or remain binary base.

Much appreciated for your help

uint32_t tmp;
dw->dwt_driver->dwt_ops->ioctl(dw, DWT_GETFRAMELENGTH, 0, (void *)&tmp);

I have no issues with lib, because I am using the ioctl() approach above. The “dwt_xxx()” are wrappers on top of ioctl() and looks like some have issues, as you have pointed out.

I encountered this same bug in the most recent driver code, so as far as I can tell the issue has not been fixed by Qorvo. The ioctl() layer of functionality has pointer re-casting happening which can be extremely dangerous. The only reason for the ioctl() layer I can see is so Qorvo can compile multiple chip versions of the drivers into a single library. Practically speaking, I can only see a benefit to Qorvo (who are likely using a win32 based test tool and dev environment internally judging by some of the preprocessor defines in the code) and only downsides to most end users who must then endure obfuscation, increased code footprint and buggy driver code.

The specific problem, which took me quite a few hours to bottom out, is caused in dwt_getframelength() because a pointer of uint16_t type is required by the API compatibility layer but this is then converted to a uint32_t pointer by the DW3000 ioctl() translation layer for the DW3000 chip. When this pointer is later dereferenced, it tramples over the stack resulting in unpredictable behaviour in the calling application.

The first thing I did when I got the source code release from Qorvo was to remove the ioctl() layer and rename all the DW3000 chip driver level functions and then use an extern global dwchip structure. The code footprint is still bigger than the DW1000 driver but you do at least now have the possibility of the linker being able to optimize out unused functions, which it can’t when you define function pointers all over the place.

If you are using a binary release of the Qorvo code, you can workaround the problem as follows. Below is the code used in the compatibility layer for dwt_getframelength():

uint16_t tmp = 0;
(void) rng;
dw->dwt_driver->dwt_ops->ioctl(dw, DWT_GETFRAMELENGTH, 0, (void *)&tmp);
return tmp;

You can write your own dwt_getframelength() function as follows:

uint32_t tmp = 0;
(void) rng;
dw->dwt_driver->dwt_ops->ioctl(dw, DWT_GETFRAMELENGTH, 0, (void *)&tmp);
return (uint16_t)tmp;
1 Like