Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading value from memory location (with 24-bit address) in 8-bit microcontroller

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: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:

enter image description here

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?

like image 749
Salahuddin Avatar asked Jul 16 '19 08:07

Salahuddin


2 Answers

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.

like image 79
Rishikesh Raje Avatar answered Nov 03 '22 19:11

Rishikesh Raje


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.

like image 29
Salahuddin Avatar answered Nov 03 '22 18:11

Salahuddin