This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

FreeRTOS and MSP430F5418

Expert 1175 points

Other Parts Discussed in Thread: MSP430F5418

Hai,

I am using MSP430F5418 with FreeRTOS.

I downloaded FreeRTOS 6.1.0 from their website and configure it for my processor.

My modifications are given below.

1. Replaced "ORG 0xFFE0 + TIMERA0_VECTOR" in portext.s43 with the following (Line 126)
        ORG 0xFF80 + TIMER0_A0_VECTOR
2. modify vPortSetupTimerInterrupt() in port.c with the following (Line 117)
       TA0CTL = MC1 | TASSEL0 | TACLR;
       TA0CCR0 = ( portACLK_FREQUENCY_HZ / configTICK_RATE_HZ ) - 1;;
       TA0CCTL0 = CCIE;
3. Replaced all "call #function_name" with "calla #function_name" in portext.s43 (Line 102,80,77)

But the scheduler is working properly but functions like vTaskDelay, vTaskResume is not working.

My code is given below..


int main( void )
{
  WDTCTL = WDTPW + WDTHOLD;
  xTaskCreate (vMyTask2, (const signed portCHAR * const) "Task 2", 160, NULL, (tskIDLE_PRIORITY + 1), &xTask2);
  xTaskCreate (vMyTask1, (const signed portCHAR * const) "Task 1", 160, NULL, (tskIDLE_PRIORITY + 1), &xTask1);
  vTaskStartScheduler();
}

void vMyTask1 ( void *  pvParameters )
{
  for( ;; )
  {
    i++;
  }
}

void vMyTask2 ( void *  pvParameters )
{
  for( ;; )
  {
    i = 0;
    vTaskDelay(10);
  }
}

The error I got when executing is "User error: Illegal opcode found on address 0x2BBBA "

The address will change if I add or remove statements in the eternal loop.

Can anybody please answer my question?

Regards,

Hari

  • Hari said:
    Replaced all "call #function_name" with "calla #function_name" in portext.s43 (Line 102,80,77)

    Did you also replace all RET by RETA? If not, the return is done only to a 16 bit address (lower 64k), which might be somewhere in the wild (and trying to execute an illegal opcode there). Also, 16 bits are left as garbage on the stack, causing more havoc.

    Also, registers should be saved on stack using the PUSHA instruction, to maintain any possibly existing 20 bit values. This is usually only necessary if you're using data above 64k, but still...

     

  • Thank you for your valuable answer

    Yes sir, I replaced ret with RETA

    But when I write PUSHA, Compiler shows Error[40]: Bad instruction.

    I am using msp430f5418 with IAR 5.10

  • Hari said:
    But when I write PUSHA, Compiler shows Error[40]: Bad instruction.

    My fault. There's no address mode 'A' version of the PUSH/POP, only the extended command PUSHX.A/POPX.A or the multi-register PUSHM.A #x,Rstart (which can push several registers at once on stack)

  • I tried it too. But after it execute the following code the control goes to 0x00 (exactly after reti) movx.a &pxCurrentTCB, r12
    movx.a @r12, r1
    POPX.A r15
    movx.a r15, &usCriticalNesting
    POPX.A r15
    POPX.A r14
    POPX.A r13
    POPX.A r12
    POPX.A r11
    POPX.A r10
    POPX.A r9
    POPX.A r8
    POPX.A r7
    POPX.A r6
    POPX.A r5
    POPX.A r4
    /* The last thing on the stack will be the status register.
    Ensure the power down bits are clear ready for the next
    time this power down register is popped from the stack. */
    bicx.a #0xf0,0(SP)
    reti
    Why is it so??
  • First, the POPX can be grouped together using the POPM.A instruction. It pops up to all 16 registers (well, it makes no sense for all 16, since popping R1 will move stack for the pop of R0 and popping R3 is futile and R2 may not be popped as 20 bit at all )

    Using POPM.A  #12, R15 will pop R15 to R4 from sthe stack, while PUSHM.A #12,R15 will push R4 to R15 to stack (automatically inversed order!)

    The combination pop/move can be fouped as a single instruction, since push and pop, liek all other orthogonal operations, can as well push and pop from and to a memory location (even register indirect).

    The last instruction to modify the saved status register may NOT be 20 bit. The status register is 16 bit (even including the 4 'additional' address bits. Also, the return address is 16 bit on the stack (the additional 4 bits are int eh upper bits of the status register, which are undefined for status purposes, but used on 430X devices).

    So what your BIC effectively does is clearing the return address to y0000 to y000f (the upper 4 bit of the 20 bit return ar enot touched), since all .A instructions will implicitely clear the upper 12 bits of a 32 bit memory location.

    Use a normal standard 16 bit BIC(.W) for the status on the stack. And since the stack is usually in the lower 64k (no ram above), not even a BICX(.W) is required.

**Attention** This is a public forum