Page 1 of 1
MALLOC_CAP_32BIT and float
Posted: Fri Mar 23, 2018 12:42 pm
by nitski
Hello all,
Is float type capable for MALLOC_CAP_32BIT ?
I used simple the code :
Code: Select all
float *test=(float *) heap_caps_malloc(sizeof(float)*10,MALLOC_CAP_32BIT);
for(i=0;i<10;i++)test[i]=i;
It causes to LoadStoreError. With int it works fine...
Re: MALLOC_CAP_32BIT and float
Posted: Fri Mar 23, 2018 3:21 pm
by kolban
Howdy,
Ive been horribly wrong in a lot of my posts recently but, undeterred in flaunting my ignorance ... my answer would be "sure that works fine". My understanding is that MALLOC_CAP_32BIT allocates storage from the heap aligned to 32bit boundaries. For example, if one called it 5 times allocating 1 byte, then the 20 bytes would be taken from the heap.
We would want to look and see how many bytes a float would be ... but I'm going to guess 32 or 64 bits.
The first test I can think of is to examine the return value from heap_caps_malloc(). Make sure it isn't NULL. If (for some reason) you asked for 80 bytes (sizeof(float) * 10 = 8 * 10 = 80) and there wasn't 80 bytes of contiguous storage available then you would get NULL and an attempt to write into NULL[0] would fail.
Re: MALLOC_CAP_32BIT and float
Posted: Sat Mar 24, 2018 2:00 am
by ESP_Sprite
I think it's not capable of doing that. The MALLOC_CAP_32BIT is a bit misleading: the actual reality is that only L32I/S32I instructions can access this memory to retrieve data, and those instructions are only capable of loading integer values.
Re: MALLOC_CAP_32BIT and float
Posted: Thu Nov 17, 2022 3:03 pm
by kindaTall
I realize this is super old. But I just ran into this problem today.
I was wondering if this has been fixed in newer versions. We are currently still on 4.4 and are running into this issue.
Though I expect this to be a silicon issue tbh.
We are currently working around this, by casting the malloced float array to int32_t, then reading or casting the address of the float value, which we want to write, to an int32_t pointer and then writing the value of that integer.
But this is all very ugly.
Re: MALLOC_CAP_32BIT and float
Posted: Thu Nov 17, 2022 10:55 pm
by ESP_igrr
Hi kindaTall,
Allocating MALLOC_CAP_32BIT memory may (on the ESP32) give you part of Instruction RAM, which is not usable for floating-point operations. If you intend to store floats, i would suggest using MALLOC_CAP_DEFAULT.
(On chips other than the ESP32, no Instruction RAM is added to the heap allocator, so all the allocated memory is Data RAM, and this issue does not occur.)
Re: MALLOC_CAP_32BIT and float
Posted: Mon Nov 21, 2022 9:10 am
by kindaTall
Hello ESP_igrr,
Thank you for your quick response. For now, I have shifted and optimized some allocations, so that we have sufficient 8B capable memory.
I realize the error may be niche, but I think it might warrent an update in the documentation.
This workaround seems to also work, though I understand it will be less efficient:
void write_to_32_bit_malloc(float * dst, float * src, size_t len){
int32_t * dst_i = (int32_t * ) dst;
for(int i = 0; i < len; i++){
dst_i[i] = *(int32_t*)(src + i);
}
}
Is it in anyway possible to implement something like this on the backend, so that write/reads to Instruction RAM are never floating-point operations, but instead take this detour?
Re: MALLOC_CAP_32BIT and float
Posted: Fri Nov 25, 2022 7:24 am
by ESP_igrr
kindaTall wrote:
Is it in anyway possible to implement something like this on the backend, so that write/reads to Instruction RAM are never floating-point operations, but instead take this detour?
I think it is possible, in theory. However given the fact that this workaround is only necessary for the ESP32 chip, I don't think it's likely that we will implement it. In newer chips, the memory layout is more linear and there is no need to allocate memory from IRAM.