planificador y pila

-4

desarrollo mi propio planificador en la placa stm32f407

Tengo diferentes colas de tareas con diferentes prioridades y frecuencias

quiero gestionar las operaciones de pila yo mismo cuando estoy en el evento SysTick_Handler cada 10 ms

desde dónde comenzar en las operaciones de inserción y apertura

¿Debo definir mi propia pila o qué?

¿Cualquier buen artículo tutorial o ejemplo si tiene ??? gracias de antemano ..

    
pregunta sedfy Elkebear

2 respuestas

0

Normalmente, cada tarea tendrá su propia pila privada. Guarda y restaura el puntero de la pila cuando cambia las tareas en su SysTick_Handler .

También me gusta tener una pila separada para el conmutador de tareas, básicamente, tratarla como una tarea separada también, aunque puede usar la pila del sistema predeterminada si lo desea.

    
respondido por el Majenko
0

La guía definitiva para ARM Cortex M3 y Cortex-M4 ** CAPÍTULO 10 Características de soporte del sistema operativo * el increíble libro que encontré y quiero compartir este ejemplo de trabajo con usted

#include "stm32f4xx.h"
// Keil::Device:STM32Cube HAL:Common

    #define LED0 (1<<7)
    #define LED1 (1<<8)
    #define LED2 (1<<9)
    #define LED3 (1<<10)

    /* Macros for word accesses */
    #define HW32_REG(ADDRESS) (*((volatile unsigned long *)(ADDRESS)))
    /* Use Breakpoint to stop when error is detected
    (KEIL MDK specific intrinsic) */
    /* it can be changed to while(1) XXif needed */
    #define stop_cpu __breakpoint(0)
    void LED_initialize(void); // Initialize LED
    void task0(void); // Toggle LED0
    void task1(void); // Toggle LED1
    void task2(void); // Toggle LED2
    void task3(void); // Toggle LED3
    // Event to tasks
    volatile uint32_t systick_count=0;
    // Stack for each task (8Kbytes each - 1024 x 8 bytes)
    long long task0_stack[1024], task1_stack[1024],
    task2_stack[1024], task3_stack[1024];
    // Data use by OS
    uint32_t curr_task=0; // Current task
    uint32_t next_task=1; // Next task
    uint32_t PSP_array[4]; // Process Stack Pointer for each task
    // -------------------------------------------------------------
    // Start of main program
    int main(void)
    {
    SCB->CCR |= SCB_CCR_STKALIGN_Msk; // Enable double word stack alignment
    //(recommended in Cortex-M3 r1p1, default in Cortex-M3 r2px and Cortex-M4)
    LED_initialize();
    // Starting the task scheduler
    // Create stack frame for task0
    PSP_array[0] = ((unsigned int) task0_stack)
    + (sizeof task0_stack) - 16*4;
    HW32_REG((PSP_array[0] + (14<<2))) = (unsigned long) task0;
    // initial Program Counter
    HW32_REG((PSP_array[0] + (15<<2))) = 0x01000000; // initial xPSR
    // Create stack frame for task1
    PSP_array[1] = ((unsigned int) task1_stack)
    + (sizeof task1_stack) - 16*4;
    HW32_REG((PSP_array[1] + (14<<2))) = (unsigned long) task1;
    // initial Program Counter
    HW32_REG((PSP_array[1] + (15<<2))) = 0x01000000; // initial xPSR
    // Create stack frame for task2
    PSP_array[2] = ((unsigned int) task2_stack)
    + (sizeof task2_stack) - 16*4;
    HW32_REG((PSP_array[2] + (14<<2))) = (unsigned long) task2;
    // initial Program Counter
    HW32_REG((PSP_array[2] + (15<<2))) = 0x01000000; // initial xPSR
    // Create stack frame for task3
    PSP_array[3] = ((unsigned int) task3_stack)
    + (sizeof task3_stack) - 16*4;
    HW32_REG((PSP_array[3] + (14<<2))) = (unsigned long) task3;
    // initial Program Counter
    HW32_REG((PSP_array[3] + (15<<2))) = 0x01000000; // initial xPSR
    curr_task = 0; // Switch to task #0 (Current task)
    __set_PSP((PSP_array[curr_task] + 16*4)); // Set PSP to topof task 0 stack
    NVIC_SetPriority(PendSV_IRQn, 0xFF); // Set PendSV to lowest possible priority
    SysTick_Config(168000); // 1000 Hz SysTick interrupton 168MHz core clock
    __set_CONTROL(0x3); // Switch to use Process Stack, unprivilegedstate
    __ISB(); // Execute ISB after changing CONTROL (architecturalrecommendation)
    task0(); // Start task 0
    while(1){
    stop_cpu;// Should not be here
    };
    }
    // ------------------------------------------------------------
    void task0(void) // Toggle LED #0
    { while (1) {
    if (systick_count & 0x80) {GPIOE->BSRRL = LED0;} // Set LED 0
    else {GPIOE->BSRRH = LED0;} // Clear LED 0
    };
    }
    // ------------------------------------------------------------
    void task1(void) // Toggle LED #1
    { while (1) {
    if (systick_count & 0x100){GPIOE->BSRRL = LED1;} // Set LED 1
    else {GPIOE->BSRRH = LED1;} // Clear LED 1
    };
    }
    // ------------------------------------------------------------
    void task2(void) // Toggle LED #2
    { while (1) {
    if (systick_count & 0x200){GPIOE->BSRRL = LED2;} // Set LED 2
    else {GPIOE->BSRRH = LED2;} // Clear LED 2
    };
    }
    // ------------------------------------------------------------
    void task3(void) // Toggle LED #3
    { while (1) {
    if (systick_count & 0x400){GPIOE->BSRRL = LED3;} // Set LED 3
    else {GPIOE->BSRRH = LED3;} // Clear LED 3
    };
    }
    // ------------------------------------------------------------
    __asm void PendSV_Handler(void)
    { // Context switching code
    // Simple version - assume No floating point support
    // -------------------------
    // Save current context

      MRS R0, PSP // Get current process stack pointer value
      STMDB R0!,{R4-R11} // Save R4 to R11 in task stack (8 regs)
      LDR R1,=__cpp(&curr_task)
      LDR R2,[R1] // Get current task ID
      LDR R3,=__cpp(&PSP_array)
      STR R0,[R3, R2, LSL #2] // Save PSP value into PSP_array
      // -------------------------
      // Load next context
      LDR R4,=__cpp(&next_task)
      LDR R4,[R4] // Get next task ID
      STR R4,[R1] // Set curr_task = next_task
      LDR R0,[R3, R4, LSL #2] // Load PSP value from PSP_array
      LDMIA R0!,{R4-R11} // Load R4 to R11 from task   stack (8 regs)
      MSR PSP, R0 // Set PSP to next task
      BX LR // Return
      ALIGN 4
    }
    // ------------------------------------------------------------
    void SysTick_Handler(void) // 1KHz
    { // Increment systick counter for LED blinking
    systick_count++;
    // Simple task round robin scheduler
    switch(curr_task) {
    case(0): next_task=1; break;
    case(1): next_task=2; break;
    case(2): next_task=3; break;
    case(3): next_task=0; break;
    default: next_task=0;
    stop_cpu;
    break; // Should not be here
    }
    if (curr_task!=next_task){ // Context switching needed
    SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; // Set PendSV to pending
    }
    return;
    }
    // ------------------------------------------------------------
    void LED_initialize(void)
    {
    // Configure LED outputs
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOEEN; // Enable Port D clock
    // Set pin 12, 13, 14, 15 as general purpose output mode(pull-push)
    GPIOE->MODER |= (GPIO_MODER_MODER7_0 |
    GPIO_MODER_MODER8_0 |
    GPIO_MODER_MODER9_0 |
    GPIO_MODER_MODER10_0 ) ;
    // GPIOE->OTYPER |= 0; // No need to change - use pull-push output
    GPIOE->OSPEEDR |= (GPIO_OSPEEDER_OSPEEDR7 | // 100MHz operations
    GPIO_OSPEEDER_OSPEEDR8 |
    GPIO_OSPEEDER_OSPEEDR9 |
    GPIO_OSPEEDER_OSPEEDR10 );
    GPIOE->PUPDR = 0; // No pull up , no pull down
    return;
    }
    
respondido por el sedfy Elkebear

Lea otras preguntas en las etiquetas