|
2 | 2 |
|
3 | 3 | This is the portable code of MRTOS for the ARM Cortex M0+ platform. To use this
|
4 | 4 | platform, please see [the main mRTOS repository](https://github.com/jdoe95/mrtos).
|
| 5 | + |
| 6 | +The portable code uses the following interrupts: |
| 7 | + * SVCall, ``isr_svc``, used for loading the first thread |
| 8 | + * SysTick, ``isr_systick``, used for generating heart beat |
| 9 | + * PendSV, ``isr_pendsv``, implemented as the context switcher |
| 10 | + |
| 11 | +The portable code does not configure the SYSTICK timer. The configuration of |
| 12 | +SYSTICK must be set before os_start(), and __SYSTICK must be disabled__. When |
| 13 | +the operating system starts, it will enable the timer automatically. |
| 14 | + |
| 15 | +Do not use ``CPSID I`` and ``CPSIE I`` instructions in the application. |
| 16 | +Use the nested version provided by the operating system instead (``os_enter_critical()`` and ``os_exit_critical()``). Be sure to |
| 17 | +replace the macros in CMSIS, too, if it's being used. Manipulating interrupts directly in the application can really mess up the system's shared variable access locks. |
| 18 | + |
| 19 | +## Features |
| 20 | + * Low power mode (when idle) |
| 21 | + |
| 22 | +## Settings |
| 23 | + |
| 24 | +| Setting | Value | |
| 25 | +|---|---| |
| 26 | +|SYSTICK interrupt frequency| 100 Hz (recommended)| |
| 27 | +|SYSTICK priority| highest (recommended) | |
| 28 | +|SVC priority | highest (required) | |
| 29 | +|PendSV priority| lowest (recommended) | |
| 30 | + |
| 31 | +## Code example |
| 32 | + |
| 33 | + |
| 34 | +```C |
| 35 | +/* |
| 36 | + * These variables are defined by the linker as |
| 37 | + * instructed by the linker script. |
| 38 | + * |
| 39 | + * Example linker script output section (GCC), place |
| 40 | + * it after all other RAM sections. |
| 41 | + * |
| 42 | + * .blank_ram : ALIGN(4) { |
| 43 | + * PROVIDE( _l_blank_ram_start = . ); |
| 44 | + * // automatically adjust the size of the hole |
| 45 | + * // to use all remaining RAM |
| 46 | + * . = ORIGIN(INT_SRAM) + LENGTH(INT_SRAM); |
| 47 | + * PROVIDE( _l_blank_ram_end = . ); |
| 48 | + * } >INT_SRAM |
| 49 | + * |
| 50 | + */ |
| 51 | +extern int _l_blank_ram_end; |
| 52 | +extern int _l_blank_ram_start; |
| 53 | + |
| 54 | +int main(void) |
| 55 | +{ |
| 56 | + // initialize hardware, configure SYSTICK, enable SYSTICK interrupt, |
| 57 | + // but do not enable counting. |
| 58 | + // P.S. the CMSIS function will enable SYSTICK immediately. You can |
| 59 | + // either modify it or write your own. |
| 60 | + |
| 61 | + // SYSTICK has two input clocks, the CPU clock HCLK, or an external clock |
| 62 | + systick_config( SYSTICK_CLOCK_SOURCE_CPU, CPU_CLOCK_FREQ/100); |
| 63 | + |
| 64 | + // set exception priorities |
| 65 | + scb_set_svcall_prio(IRQ_PRIO_0); |
| 66 | + scb_set_systick_prio(IRQ_PRIO_0); |
| 67 | + scb_set_pendsv_prio(IRQ_PRIO_3); |
| 68 | + |
| 69 | + // ... |
| 70 | + |
| 71 | + // Initialize the operating system |
| 72 | + |
| 73 | + os_config_t os_config; |
| 74 | + |
| 75 | + os_config.p_pool_mem = &_l_blank_ram_start; |
| 76 | + os_config.pool_size = (uint8_t*)&_l_blank_ram_end - (uint8_t*)&_l_blank_ram_start; |
| 77 | + |
| 78 | + os_init( &os_config ); |
| 79 | + |
| 80 | + // create some operating system objects here: threads, semaphores, etc. |
| 81 | + |
| 82 | + // ... |
| 83 | + |
| 84 | + |
| 85 | + // start the operating system, run the highest |
| 86 | + // priority thread |
| 87 | + os_start(); |
| 88 | + |
| 89 | + // reaches the point of no return. The execution |
| 90 | + // should never get here. If it does, something |
| 91 | + // went wrong. |
| 92 | + |
| 93 | + for( ; ; ) |
| 94 | + ; |
| 95 | + |
| 96 | + return 0; |
| 97 | +} |
| 98 | + |
| 99 | +``` |
0 commit comments