Вопрос

I have the following snippet of code:

uint8_t     *ptrconfig;
uint8_t     *ptrspi;

ptrconfig = &TempDeviceConfig.ConfigSize;
ptrspi = &spi_out_array[0];
for ( Count = 0U; Count < DEVICE_USER_SETTINGS_WORDCOUNT +1U; Count++ )
{
    *ptrspi++ = *ptrconfig++;
}

However it is not working as expected breakpointing on the second line shows that the address of TempDeviceConfig.ConfigSize is 0x2BD5 however the address the pointer points to is 0x216F.

Why do I get an unexpected value of pointer?

EDIT: A bit of clarification, I can't say exactly what is inside TempDeviceConfig because I need to be careful how much code appears on the internet, but yes it is a struct and it contains a total of 50+ bytes which are to be written to an external flash chip over SPI. My aim here is to copy the struct into the SPI array which sends the data out.

Это было полезно?

Решение

uint8_t     *ptrconfig;
...
ptrconfig = &TempDeviceConfig.ConfigSize;

Apparently TempDeviceConfig is a struct (or union?), and ConfigSize is a member which is of type uint8_t.

*ptrspi++ = *ptrconfig++;

ConfigSize is a single uint8_t object. You can advance the pointer only once; it then points just past the object, and cannot be dereferenced. Your code assumes that ptrconfig points to an element of an array of uint8_t. It doesn't. It doesn't make sense to loop over a single object.

I can't guess what the code should be doing without seeing the declarations of the objects you're using. But if your intent is to copy the entire structure (including any padding) into spi_out_array, a call to memcpy() is a much simpler way to do it. (Copying raw structure contents to an external interface can be quite error-prone, but if the written data is only read by the current system it could be ok.)

If memcpy() is not available because you're programming for a small embedded system, you can easily implement it yourself, either as a function or as inline code. For example:

struct foo { /* ... */ } obj;
unsigned char out_array[sizeof obj];   // or perhaps bigger
unsigned char *from = (unsigned char*)&obj;
unsigned char *to = out_array; // or &out_array[0]
for (int i = 0; i < sizeof obj; i ++) {
    *to++ = *from++;
}

I've defined out_array as an array of unsigned char, because that's the most portable 1-byte type in C; an object's representation is defined as a sequence of unsigned char values. But you can almost certainly use uint8_t instead.

If your goal is to copy the entire representation of the structure as raw bytes, it doesn't make sense to refer to a particular member; just treat the entire structure as a byte sequence.

But first check whether your implementation supports memcpy (if so, it should be declared in <string.h>). "Freestanding implementations" aren't required to support any standard library functions, but yours might support some subset of the hosted standard library.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top