I thought it should be as simple as:
uint32_t getCrc(void)
{
uint32_t expectedCrc = *(uint32_t*)0x27FF0;
return expectedCrc;
}
And if the memory location has the following value:
Then the expectedCrc
should equal to 0xECD8743D
But surprisingly, the value is: 0x82828282
I tried defining a pointer to uint32_t
and assign the memory address to it as following:
uint32_t getCrc(void)
{
uint32_t *ptr = (uint32_t*)0x27FF0;
uint32_t expectedCrc = *ptr;
return expectedCrc;
}
But the value of the pointer itself was 0xFFFF
and expectedCrc
equal 0x82828282
I found these two values in a different memory address:
I also tried the same with char *ptr = (char*)0x27FF0
but it gave the same values.
Finally, I tried to check what is the size of a pointer to char in this controller using uint8_t size = sizeof(char*);
and the answer was 0xb0
which equals 176
.
I think it has something to do with the 24-bit memory address and the CPU architecture. I'm working on stm8
controller.
Could someone explain why does this happen?
UPDATE
I tried replacing the address 0x27FF0
with 0xFFF0
and it worked fine. So the problem is with the long address. I want to write the CRC value in the last address to avoid over-writing it with the code itself in case the program went bigger. How can I handle this?
From the Cosmic compiler datasheet https://www.cosmic-software.com/pdf/cxstm8_pd.pdf
cxstm8 provides 2 different memory models depending on the size of the application.
For applications smaller that 64k, the “section 0” memory model provides the best code density by defaulting function calls and pointers to 2 bytes.
For applications bigger than 64k, the standard memory model provides the best flexibility for using easily the linear addressing space. Each model comes with its own set of libraries.
This may be the cause for your problem. If you want to access the memory location of above 16 bit address directly you need to use the correct memory model.
As @Raje answered that it is about the memory models, I did further reading in the COSMIC user's guide and I found the following:
The STM8 compiler supports two memory models for application larger than 64K, allowing you to choose the most efficient behavior depending on your processor configuration and your application. All these models allow the code to be larger than 64K and then function pointers are defaulted to @far pointers (3 bytes). Data pointers are defaulted to @near pointers (2 bytes) unless explicitly declared with the @far modifier.
Therefore, the solution was to add @far
to the pointer's type as following:
uint32_t calculatedCrc = 0;
expectedCrc = *(@far uint32_t*)0x27FF0;
This got the problem solved.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With