Click here to Skip to main content
15,881,882 members
Home / Discussions / C / C++ / MFC
   

C / C++ / MFC

 
QuestionInitInstance() implimentation. Pin
Member 1271142610-Jun-18 20:17
Member 1271142610-Jun-18 20:17 
AnswerRe: InitInstance() implimentation. Pin
Jochen Arndt10-Jun-18 21:24
professionalJochen Arndt10-Jun-18 21:24 
QuestionAdvice on designing a simple task scheduler in embedded C, that can handle asynchronuous tasks? Pin
arnold_w9-Jun-18 10:37
arnold_w9-Jun-18 10:37 
AnswerRe: Advice on designing a simple task scheduler in embedded C, that can handle asynchronuous tasks? Pin
leon de boer10-Jun-18 17:27
leon de boer10-Jun-18 17:27 
GeneralRe: Advice on designing a simple task scheduler in embedded C, that can handle asynchronuous tasks? Pin
arnold_w10-Jun-18 20:16
arnold_w10-Jun-18 20:16 
GeneralRe: Advice on designing a simple task scheduler in embedded C, that can handle asynchronuous tasks? Pin
leon de boer11-Jun-18 2:52
leon de boer11-Jun-18 2:52 
GeneralRe: Advice on designing a simple task scheduler in embedded C, that can handle asynchronuous tasks? Pin
arnold_w11-Jun-18 3:13
arnold_w11-Jun-18 3:13 
GeneralRe: Advice on designing a simple task scheduler in embedded C, that can handle asynchronuous tasks? Pin
leon de boer11-Jun-18 4:04
leon de boer11-Jun-18 4:04 
You can't reach your goals without some switcher, I believe you already worked that our yourself it gets more and more complex.

There is actually less code in writing the switcher it's a couple hundred lines of code and it's faster as your CPU is designed to context switch Smile | :)

From "The Definitive Guide to ARM Cortex M3 and Cortex-M4" that is a 4 task round robin switcher in 150 lines of code.
You just need to change the scheduler (SysTick_Handler) to a priority based one .. you will find dozens on the net
You can extend the number of task etc, the code is very very obvious and easier than your current scheme you have reached.
#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;
    }

In vino veritas


modified 11-Jun-18 10:49am.

GeneralRe: Advice on designing a simple task scheduler in embedded C, that can handle asynchronuous tasks? Pin
arnold_w11-Jun-18 9:38
arnold_w11-Jun-18 9:38 
AnswerRe: Advice on designing a simple task scheduler in embedded C, that can handle asynchronuous tasks? Pin
supercat920-Jun-18 12:22
supercat920-Jun-18 12:22 
QuestionC# combo box text color change Pin
czaar9998-Jun-18 7:18
czaar9998-Jun-18 7:18 
AnswerRe: C# combo box text color change Pin
Richard Andrew x648-Jun-18 10:54
professionalRichard Andrew x648-Jun-18 10:54 
Questionusing dynamic_cast with template classes. Pin
Tarun Jha5-Jun-18 1:48
Tarun Jha5-Jun-18 1:48 
AnswerRe: using dynamic_cast with template classes. Pin
Richard MacCutchan5-Jun-18 3:20
mveRichard MacCutchan5-Jun-18 3:20 
GeneralRe: using dynamic_cast with template classes. Pin
Tarun Jha5-Jun-18 8:31
Tarun Jha5-Jun-18 8:31 
GeneralRe: using dynamic_cast with template classes. Pin
Richard MacCutchan5-Jun-18 21:00
mveRichard MacCutchan5-Jun-18 21:00 
AnswerRe: using dynamic_cast with template classes. Pin
CPallini5-Jun-18 11:03
mveCPallini5-Jun-18 11:03 
GeneralRe: using dynamic_cast with template classes. Pin
Tarun Jha5-Jun-18 18:45
Tarun Jha5-Jun-18 18:45 
GeneralRe: using dynamic_cast with template classes. Pin
CPallini5-Jun-18 21:22
mveCPallini5-Jun-18 21:22 
GeneralRe: using dynamic_cast with template classes. Pin
Tarun Jha6-Jun-18 3:11
Tarun Jha6-Jun-18 3:11 
GeneralRe: using dynamic_cast with template classes. Pin
CPallini6-Jun-18 22:26
mveCPallini6-Jun-18 22:26 
QuestionDevice manager in windows. Pin
Member 138414544-Jun-18 9:14
Member 138414544-Jun-18 9:14 
SuggestionRe: Device manager in windows. Pin
David Crow4-Jun-18 10:09
David Crow4-Jun-18 10:09 
GeneralTiniest portable executable Pin
DaviFN4-Jun-18 6:25
DaviFN4-Jun-18 6:25 
GeneralRe: Tiniest portable executable Pin
leon de boer4-Jun-18 20:17
leon de boer4-Jun-18 20:17 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.