Dereferncing a pointer doesn't return the real value in the memory address

0

I'm developing an embedded application on STM8S using STVD IDE and Cosmic C compiler. I'm trying to read FLASH memory byte by byte to calculate CRC. Following is my code snippet:

uint32_t crc32_buffer(const uint8_t *buf, uint32_t len)
{
    uint32_t index = 0;
    uint32_t crc = 0xFFFFFFFF;
    uint32_t flashIndex = 0;
    uint8_t *ptr = buf;
    volatile uint8_t value = 0;
    volatile uint8_t i = 0;

    for (index = 0; index < len; index++)
    {
        value = *ptr;
        flashIndex = (crc & 0xFF) ^ value;
        ptr++;
        crc = (crc >> 8) ^ table[flashIndex];

        if(bytesCntr >= 2685)
        {
           i++;
        }
    }

    return ~crc;
}

The code works fine until 2694 bytes are read from the FLASH. Viewing Memory in the debugging session, I make sure that the next byte in the FLASH has value of 0C. Checking the value of ptr, I make sure it has the address of this 0C byte in the FLASH (which is 0x8B15). However, value variable always get the value of 8B instead of 0C after ptr is dereferenced.

I also tried to exclude unnecessary variables so it be like this:

crc = (crc >> 8) ^ table[(crc & 0xFF) ^ buf[index]];

But the table index was not as it should be as the memory location was read as 8B instead of 0C.

I found that the byte before and the byte after address 0x8B15 are read correctly. Only this address is read wrongly.

UPDATE-1

The disassembly of the value = *ptr; is as following:

LDW X, (0x11,SP)
LD  A, (X)
LD  (0x13,SP),A

When reading the byte at address 0x8B15, if I put a breakpoint at the second assembly line and then the value in the memory location is read correctly as 0C. However, if I put the breakpoint at the third assembly line instead, I find that register X has 0x8B15 (the right address) but register A has 0x8B (the wrong value).

UPDATE-2

I added an if statement inside the for loop for debugging (to put my breakpoint). I found that the code saved in memory byte which is read wrongly is always the code inside this if statement. The disassembly of this code always have something to do with SP. Even if I changed the code, the problematic memory byte is always the first instruction in the if statement. And I also noticed that the wrong read value is always 0x8B regardless what is the right value. Here is the disassembly saved in this memory location:

0x8b15 <crc32_buffer+104>   0x0C01 INC   (0x01,SP)  INC   (_CRC_ONGOING_s,SP) 
c
pointers
memory
embedded
asked on Stack Overflow Jul 18, 2019 by Salahuddin • edited Jul 22, 2019 by Salahuddin

2 Answers

0

I came across the same issue last week .. It seems to be a problem with the debugging Firmware and your code both accessing the same location. If you have an active breakpoint at that same Flash location you are trying to read with your code, then your code ends up reading 0x8B from that location. If you remove or deactivate all breakpoints, the location is read correctly..

answered on Stack Overflow Apr 4, 2021 by GonMad
0

In addition to my previous answer (see above or below ..I couldn't edit that one).. Active breakpoints substitute the existing instruction at that particular Flash memory location with a BREAK instruction (opcode 0x8B), so when that memory location is read from within the application code, 0x8B will be the result. So this is not really a 'problem', but rather a limitation of software breakpoints as implemented within the SWIM debugging firmware on the STM8S.

answered on Stack Overflow Apr 7, 2021 by GonMad

User contributions licensed under CC BY-SA 3.0