This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Pointer to Structure with pointer.

I'm having a problem with a pointer to struct. I'm working with the PC16552 UART, (it has 2 UARTs), and I created a struct for each UART like this:

typedef struct _uart
{
 uchar xdata *ucBuffer;
 uchar xdata *ucLineCt;
 uchar xdata *ucLineSt;
} uart;
Each uart is conected to a different external interrupt, and when that interrupt is generated, it calls a function getByte that have a pointer to a uart struct as parameter:
void int0(void) interrupt 0
{
 ...
 getByte(&Serial1);
 ...
}

void int1(void) interrupt 1
{
 ...
 getByte(&Serial2);
 ...
}

void getByte(uart *actualSerial) reentrant
{
 unsigned char ucByte;

 ucByte = *actualSerial->ucBuffer;
 ...
}
It works fine, but sometimes, I receive a wrong character. I was thinking that could be hardware, but I decided to make a dump of the block, and the dump solved the problem. I'm asking help, because I don't know what is it, if it's hardware or firmware... The problem occurs when I receive a 0xFF from the serial 2... Sometimes, it turns in 0xF7 or 0xF3. In the dump, I simply do this:
 if(actualSerial == &Serial2)
 {
  if(i < 20)
  Dump[i++] = ucByte;
 }

Parents
  • I assume the *serialAtual is used in the UART interrupt as well.

    In that case that is your problem.

    ANY handling of pointers and anything longer than a char in the body of the progtam MUST be done with interrupts disabled if such are used inside ISRs as well.

    Why:

    ;in the body
    ; a see below
    mov, r0,HIGH pointer
    ;b see below
    mov R1,LOW pointer

    say the pointer were 0x2ff at point a, at point b an interrupt happens that increment the pointer to 0x300.
    The result is that the program body routine read the pointer as 0x200.

    Not disabling interrupts during handling of >8bit values shared with interrupts is, in my opinion, the most common cause of flaky execution in 8 bit processors.

    Erik

Reply
  • I assume the *serialAtual is used in the UART interrupt as well.

    In that case that is your problem.

    ANY handling of pointers and anything longer than a char in the body of the progtam MUST be done with interrupts disabled if such are used inside ISRs as well.

    Why:

    ;in the body
    ; a see below
    mov, r0,HIGH pointer
    ;b see below
    mov R1,LOW pointer

    say the pointer were 0x2ff at point a, at point b an interrupt happens that increment the pointer to 0x300.
    The result is that the program body routine read the pointer as 0x200.

    Not disabling interrupts during handling of >8bit values shared with interrupts is, in my opinion, the most common cause of flaky execution in 8 bit processors.

    Erik

Children
  • Well, I've found something today... I was not initializing the reentrant Stack... After initializing it it works perfectly...
    Well, about the problem been hardware, I discarded it. It's not a time problem, because the acess time of the UART is 84ns, and I'm using a 89C52 with a 11.0592MHz Crystal.
    If it was the data bus, and I'd considered it, this problem will occur frequently, with all kind of data.
    The substitution that I'd made was put a attribution after loading data from the UART. It worked...
    About the pointer, I really didn't know about it, and from now, I'll observe it. But in this project, I'm not writing to these pointers. I'll check if I'm doing something similar...
    Thanks a lot for the help!!!
    A last question... What hapens exactly if you don't initialize the reentrant Stack??