Mover SP y PC utilizando ensamblaje en línea en MPS430-GCC

3

Estoy escribiendo un programador de tareas simple para mi MSP430F5529 USB Launchpad. Necesito actualizar el puntero de pila (SP), luego habilitar las interrupciones y luego actualizar el contador del programa (PC). Pero estoy recibiendo un error con mi código de ensamblaje en línea.

void start_scheduler(void)
{
  asm volatile("mov.w task1stack, SP \n"
               "EINT \n"
               "mov.w func1, PC \n"
          );
}
  • task1stack es el área de la pila para la ejecución de la tarea. Es una matriz.
  • func1 es una función.
  • en lugar de mayúsculas para 'SP' y 'PC', también probé en minúsculas. Pero el error todavía estaba presente.

Pero con el código anterior, el compilador muestra el siguiente error

kernel.c:(.text+0x8e): undefined reference to 'SP'
kernel.c:(.text+0x96): undefined reference to 'PC'

Preguntas:

  1. ¿Cómo actualizar SP y PC?
  2. ¿Puede "mov.w task1stack, SP \ n" copiar la dirección del arreglo en SP? ¿Es correcta mi sintaxis?
  3. ¿Puede "mov.w func1, PC \ n" copiar la dirección de la función en la PC? ¿Es correcta mi sintaxis?
pregunta robomon

1 respuesta

4

Por curiosidad ociosa, busqué cómo FreeRTOS maneja el cambio de contexto. Definen dos macros para manejar esto de la siguiente manera. Quizás esto ofrezca algunas pistas sobre la sintaxis. Evidentemente, el puntero de pila se conoce como "r1".

De CPU MSP430 :

  

El procesador contiene 16 registros de 16 bits, de los cuales 4 son   dedicado a fines especiales: R0 es el contador del programa, R1 es el contador   puntero de pila, R2 es el registro de estado y R3 es un registro especial   Se llama generador constante, proporcionando acceso a 6 de uso común.   Valores constantes sin necesidad de un operando adicional. R3 siempre   lee como 0 y las escrituras se ignoran. R4 a R15 están disponibles   para uso general.

/* 
 * Macro to save a task context to the task stack.  This simply pushes all the 
 * general purpose msp430 registers onto the stack, followed by the 
 * usCriticalNesting value used by the task.  Finally the resultant stack 
 * pointer value is saved into the task control block so it can be retrieved 
 * the next time the task executes.
 */
#define portSAVE_CONTEXT()                                   \
    asm volatile (  "push   r4                      \n\t"    \
                    "push   r5                      \n\t"    \
                    "push   r6                      \n\t"    \
                    "push   r7                      \n\t"    \
                    "push   r8                      \n\t"    \
                    "push   r9                      \n\t"    \
                    "push   r10                     \n\t"    \
                    "push   r11                     \n\t"    \
                    "push   r12                     \n\t"    \
                    "push   r13                     \n\t"    \
                    "push   r14                     \n\t"    \
                    "push   r15                     \n\t"    \
                    "mov.w  usCriticalNesting, r14  \n\t"    \
                    "push   r14                     \n\t"    \
                    "mov.w  pxCurrentTCB, r12       \n\t"    \
                    "mov.w  r1, @r12                \n\t"    \
                );

/* 
 * Macro to restore a task context from the task stack.  This is effectively
 * the reverse of portSAVE_CONTEXT().  First the stack pointer value is
 * loaded from the task control block.  Next the value for usCriticalNesting
 * used by the task is retrieved from the stack - followed by the value of all
 * the general purpose msp430 registers.
 *
 * The bic instruction ensures there are no low power bits set in the status
 * register that is about to be popped from the stack.
 */
#define portRESTORE_CONTEXT()                                \
    asm volatile (  "mov.w  pxCurrentTCB, r12       \n\t"    \
                    "mov.w  @r12, r1                \n\t"    \
                    "pop    r15                     \n\t"    \
                    "mov.w  r15, usCriticalNesting  \n\t"    \
                    "pop    r15                     \n\t"    \
                    "pop    r14                     \n\t"    \
                    "pop    r13                     \n\t"    \
                    "pop    r12                     \n\t"    \
                    "pop    r11                     \n\t"    \
                    "pop    r10                     \n\t"    \
                    "pop    r9                      \n\t"    \
                    "pop    r8                      \n\t"    \
                    "pop    r7                      \n\t"    \
                    "pop    r6                      \n\t"    \
                    "pop    r5                      \n\t"    \
                    "pop    r4                      \n\t"    \
                    "bic    #(0xf0),0(r1)           \n\t"    \
                    "reti                           \n\t"    \
                );
    
respondido por el Dave Tweed

Lea otras preguntas en las etiquetas