mbed-rtos
Fork of mbed-rtos by
Revision 49:77c8e4604045, committed 2014-11-06
- Comitter:
- mbed_official
- Date:
- Thu Nov 06 13:00:11 2014 +0000
- Parent:
- 48:e9a2c7cb57a4
- Child:
- 50:64a5202c3676
- Commit message:
- Synchronized with git revision 7b90c2ba137baaf9769219e0e8a7b8e8d1299c4f
Full URL: https://github.com/mbedmicro/mbed/commit/7b90c2ba137baaf9769219e0e8a7b8e8d1299c4f/
This target is not yet tested, so it can't be released as part of the official
SDK build for now.
Changed in this revision
--- a/rtx/HAL_CM.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,170 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: HAL_CM.C - * Purpose: Hardware Abstraction Layer for Cortex-M - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Conf.h" -#include "rt_HAL_CM.h" - - -/*---------------------------------------------------------------------------- - * Global Variables - *---------------------------------------------------------------------------*/ - -#ifdef DBG_MSG -BIT dbg_msg; -#endif - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_init_stack ---------------------------------*/ - -void rt_init_stack (P_TCB p_TCB, FUNCP task_body) { - /* Prepare TCB and saved context for a first time start of a task. */ - U32 *stk,i,size; - - /* Prepare a complete interrupt frame for first task start */ - size = p_TCB->priv_stack >> 2; - - /* Write to the top of stack. */ - stk = &p_TCB->stack[size]; - - /* Auto correct to 8-byte ARM stack alignment. */ - if ((U32)stk & 0x04) { - stk--; - } - - stk -= 16; - - /* Default xPSR and initial PC */ - stk[15] = INITIAL_xPSR; - stk[14] = (U32)task_body; - - /* Clear R4-R11,R0-R3,R12,LR registers. */ - for (i = 0; i < 14; i++) { - stk[i] = 0; - } - - /* Assign a void pointer to R0. */ - stk[8] = (U32)p_TCB->msg; - - /* Initial Task stack pointer. */ - p_TCB->tsk_stack = (U32)stk; - - /* Task entry point. */ - p_TCB->ptask = task_body; - - /* Set a magic word for checking of stack overflow. - For the main thread (ID: 0x01) the stack is in a memory area shared with the - heap, therefore the last word of the stack is a moving target. - We want to do stack/heap collision detection instead. - */ - if (p_TCB->task_id != 0x01) - p_TCB->stack[0] = MAGIC_WORD; -} - - -/*--------------------------- rt_ret_val ----------------------------------*/ - -static __inline U32 *rt_ret_regs (P_TCB p_TCB) { - /* Get pointer to task return value registers (R0..R3) in Stack */ -#if (__TARGET_FPU_VFP) - if (p_TCB->stack_frame) { - /* Extended Stack Frame: R4-R11,S16-S31,R0-R3,R12,LR,PC,xPSR,S0-S15,FPSCR */ - return (U32 *)(p_TCB->tsk_stack + 8*4 + 16*4); - } else { - /* Basic Stack Frame: R4-R11,R0-R3,R12,LR,PC,xPSR */ - return (U32 *)(p_TCB->tsk_stack + 8*4); - } -#else - /* Stack Frame: R4-R11,R0-R3,R12,LR,PC,xPSR */ - return (U32 *)(p_TCB->tsk_stack + 8*4); -#endif -} - -void rt_ret_val (P_TCB p_TCB, U32 v0) { - U32 *ret; - - ret = rt_ret_regs(p_TCB); - ret[0] = v0; -} - -void rt_ret_val2(P_TCB p_TCB, U32 v0, U32 v1) { - U32 *ret; - - ret = rt_ret_regs(p_TCB); - ret[0] = v0; - ret[1] = v1; -} - - -/*--------------------------- dbg_init --------------------------------------*/ - -#ifdef DBG_MSG -void dbg_init (void) { - if ((DEMCR & DEMCR_TRCENA) && - (ITM_CONTROL & ITM_ITMENA) && - (ITM_ENABLE & (1UL << 31))) { - dbg_msg = __TRUE; - } -} -#endif - -/*--------------------------- dbg_task_notify -------------------------------*/ - -#ifdef DBG_MSG -void dbg_task_notify (P_TCB p_tcb, BOOL create) { - while (ITM_PORT31_U32 == 0); - ITM_PORT31_U32 = (U32)p_tcb->ptask; - while (ITM_PORT31_U32 == 0); - ITM_PORT31_U16 = (create << 8) | p_tcb->task_id; -} -#endif - -/*--------------------------- dbg_task_switch -------------------------------*/ - -#ifdef DBG_MSG -void dbg_task_switch (U32 task_id) { - while (ITM_PORT31_U32 == 0); - ITM_PORT31_U8 = task_id; -} -#endif - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx/RTX_CM_lib.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,453 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RTX_CM_LIB.H - * Purpose: RTX Kernel System Configuration - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ -#include "mbed_error.h" - -#if defined (__CC_ARM) -#pragma O3 -#define __USED __attribute__((used)) -#elif defined (__GNUC__) -#pragma GCC optimize ("O3") -#define __USED __attribute__((used)) -#elif defined (__ICCARM__) -#define __USED __root -#endif - - -/*---------------------------------------------------------------------------- - * Definitions - *---------------------------------------------------------------------------*/ - -#define _declare_box(pool,size,cnt) uint32_t pool[(((size)+3)/4)*(cnt) + 3] -#define _declare_box8(pool,size,cnt) uint64_t pool[(((size)+7)/8)*(cnt) + 2] - -#define OS_TCB_SIZE 48 -#define OS_TMR_SIZE 8 - -#if defined (__CC_ARM) && !defined (__MICROLIB) - -typedef void *OS_ID; -typedef uint32_t OS_TID; -typedef uint32_t OS_MUT[3]; -typedef uint32_t OS_RESULT; - -#define runtask_id() rt_tsk_self() -#define mutex_init(m) rt_mut_init(m) -#define mutex_wait(m) os_mut_wait(m,0xFFFF) -#define mutex_rel(m) os_mut_release(m) - -extern OS_TID rt_tsk_self (void); -extern void rt_mut_init (OS_ID mutex); -extern OS_RESULT rt_mut_release (OS_ID mutex); -extern OS_RESULT rt_mut_wait (OS_ID mutex, uint16_t timeout); - -#define os_mut_wait(mutex,timeout) _os_mut_wait((uint32_t)rt_mut_wait,mutex,timeout) -#define os_mut_release(mutex) _os_mut_release((uint32_t)rt_mut_release,mutex) - -OS_RESULT _os_mut_release (uint32_t p, OS_ID mutex) __svc_indirect(0); -OS_RESULT _os_mut_wait (uint32_t p, OS_ID mutex, uint16_t timeout) __svc_indirect(0); - -#endif - - -/*---------------------------------------------------------------------------- - * Global Variables - *---------------------------------------------------------------------------*/ - -#if (OS_TIMERS != 0) -#define OS_TASK_CNT (OS_TASKCNT + 1) -#else -#define OS_TASK_CNT OS_TASKCNT -#endif - -uint16_t const os_maxtaskrun = OS_TASK_CNT; -uint32_t const os_rrobin = (OS_ROBIN << 16) | OS_ROBINTOUT; -uint32_t const os_trv = OS_TRV; -uint8_t const os_flags = OS_RUNPRIV; - -/* Export following defines to uVision debugger. */ -__USED uint32_t const os_clockrate = OS_TICK; -__USED uint32_t const os_timernum = 0; - -/* Stack for the os_idle_demon */ -unsigned int idle_task_stack[OS_IDLESTKSIZE]; -unsigned short const idle_task_stack_size = OS_IDLESTKSIZE; - -#ifndef OS_FIFOSZ - #define OS_FIFOSZ 16 -#endif - -/* Fifo Queue buffer for ISR requests.*/ -uint32_t os_fifo[OS_FIFOSZ*2+1]; -uint8_t const os_fifo_size = OS_FIFOSZ; - -/* An array of Active task pointers. */ -void *os_active_TCB[OS_TASK_CNT]; - -/* User Timers Resources */ -#if (OS_TIMERS != 0) -extern void osTimerThread (void const *argument); -osThreadDef(osTimerThread, (osPriority)(OS_TIMERPRIO-3), 4*OS_TIMERSTKSZ); -osThreadId osThreadId_osTimerThread; -osMessageQDef(osTimerMessageQ, OS_TIMERCBQS, void *); -osMessageQId osMessageQId_osTimerMessageQ; -#else -osThreadDef_t os_thread_def_osTimerThread = { NULL }; -osThreadId osThreadId_osTimerThread; -osMessageQDef(osTimerMessageQ, 0, void *); -osMessageQId osMessageQId_osTimerMessageQ; -#endif - - -/*---------------------------------------------------------------------------- - * RTX Optimizations (empty functions) - *---------------------------------------------------------------------------*/ - -#if OS_ROBIN == 0 - void rt_init_robin (void) {;} - void rt_chk_robin (void) {;} -#endif - -#if OS_STKCHECK == 0 - void rt_stk_check (void) {;} -#endif - - -/*---------------------------------------------------------------------------- - * Standard Library multithreading interface - *---------------------------------------------------------------------------*/ - -#if defined (__CC_ARM) && !defined (__MICROLIB) - static OS_MUT std_libmutex[OS_MUTEXCNT]; - static uint32_t nr_mutex; - - /*--------------------------- _mutex_initialize -----------------------------*/ - -int _mutex_initialize (OS_ID *mutex) { - /* Allocate and initialize a system mutex. */ - - if (nr_mutex >= OS_MUTEXCNT) { - /* If you are here, you need to increase the number OS_MUTEXCNT. */ - error("Not enough stdlib mutexes\n"); - } - *mutex = &std_libmutex[nr_mutex++]; - mutex_init (*mutex); - return (1); -} - - -/*--------------------------- _mutex_acquire --------------------------------*/ - -__attribute__((used)) void _mutex_acquire (OS_ID *mutex) { - /* Acquire a system mutex, lock stdlib resources. */ - if (runtask_id ()) { - /* RTX running, acquire a mutex. */ - mutex_wait (*mutex); - } -} - - -/*--------------------------- _mutex_release --------------------------------*/ - -__attribute__((used)) void _mutex_release (OS_ID *mutex) { - /* Release a system mutex, unlock stdlib resources. */ - if (runtask_id ()) { - /* RTX running, release a mutex. */ - mutex_rel (*mutex); - } -} - -#endif - - -/*---------------------------------------------------------------------------- - * RTX Startup - *---------------------------------------------------------------------------*/ - -/* Main Thread definition */ -extern int main (void); -osThreadDef_t os_thread_def_main = {(os_pthread)main, osPriorityNormal, 0, NULL}; - -// This define should be probably moved to the CMSIS layer -#if defined(TARGET_LPC1768) -#define INITIAL_SP (0x10008000UL) - -#elif defined(TARGET_LPC11U24) -#define INITIAL_SP (0x10002000UL) - -#elif defined(TARGET_LPC11U35_401) || defined(TARGET_LPC11U35_501) || defined(TARGET_LPCCAPPUCCINO) -#define INITIAL_SP (0x10002000UL) - -#elif defined(TARGET_LPC1114) -#define INITIAL_SP (0x10001000UL) - -#elif defined(TARGET_LPC812) -#define INITIAL_SP (0x10001000UL) - -#elif defined(TARGET_LPC824) -#define INITIAL_SP (0x10002000UL) - -#elif defined(TARGET_KL25Z) -#define INITIAL_SP (0x20003000UL) - -#elif defined(TARGET_K64F) -#define INITIAL_SP (0x20030000UL) - -#elif defined(TARGET_KL46Z) -#define INITIAL_SP (0x20006000UL) - -#elif defined(TARGET_KL43Z) -#define INITIAL_SP (0x20006000UL) - -#elif defined(TARGET_KL05Z) -#define INITIAL_SP (0x20000C00UL) - -#elif defined(TARGET_LPC4088) -#define INITIAL_SP (0x10010000UL) - -#elif defined(TARGET_LPC4337) -#define INITIAL_SP (0x10008000UL) - -#elif defined(TARGET_LPC1347) -#define INITIAL_SP (0x10002000UL) - -#elif defined(TARGET_STM32F100RB) || defined(TARGET_STM32F051R8) -#define INITIAL_SP (0x20002000UL) - -#elif defined(TARGET_DISCO_F303VC) -#define INITIAL_SP (0x2000A000UL) - -#elif defined(TARGET_STM32F407) || defined(TARGET_F407VG) -#define INITIAL_SP (0x20020000UL) - -#elif defined(TARGET_STM32F401RE) -#define INITIAL_SP (0x20018000UL) - -#elif defined(TARGET_LPC1549) -#define INITIAL_SP (0x02009000UL) - -#elif defined(TARGET_LPC11U68) -#define INITIAL_SP (0x10004000UL) - -#elif defined(TARGET_NRF51822) -#define INITIAL_SP (0x20004000UL) - -#elif defined(TARGET_STM32F411RE) -#define INITIAL_SP (0x20020000UL) - -#elif defined(TARGET_STM32F103RB) -#define INITIAL_SP (0x20005000UL) - -#elif defined(TARGET_STM32F302R8) -#define INITIAL_SP (0x20004000UL) - -#elif defined(TARGET_STM32F334R8) -#define INITIAL_SP (0x20003000UL) - -#elif defined(TARGET_STM32F334C8) -#define INITIAL_SP (0x20003000UL) - -#else -#error "no target defined" - -#endif - -#ifdef __CC_ARM -extern unsigned char Image$$RW_IRAM1$$ZI$$Limit[]; -#define HEAP_START (Image$$RW_IRAM1$$ZI$$Limit) -#elif defined(__GNUC__) -extern unsigned char __end__[]; -#define HEAP_START (__end__) -#endif - -void set_main_stack(void) { - // That is the bottom of the main stack block: no collision detection - os_thread_def_main.stack_pointer = HEAP_START; - - // Leave OS_SCHEDULERSTKSIZE words for the scheduler and interrupts - os_thread_def_main.stacksize = (INITIAL_SP - (unsigned int)HEAP_START) - (OS_SCHEDULERSTKSIZE * 4); -} - -#if defined (__CC_ARM) -#ifdef __MICROLIB -void _main_init (void) __attribute__((section(".ARM.Collect$$$$000000FF"))); -void _main_init (void) { - osKernelInitialize(); - set_main_stack(); - osThreadCreate(&os_thread_def_main, NULL); - osKernelStart(); - for (;;); -} -#else - -/* The single memory model is checking for stack collision at run time, verifing - that the heap pointer is underneath the stack pointer. - - With the RTOS there is not only one stack above the heap, there are multiple - stacks and some of them are underneath the heap pointer. -*/ -#pragma import(__use_two_region_memory) - -__asm void __rt_entry (void) { - - IMPORT __user_setup_stackheap - IMPORT __rt_lib_init - IMPORT os_thread_def_main - IMPORT osKernelInitialize - IMPORT set_main_stack - IMPORT osKernelStart - IMPORT osThreadCreate - IMPORT exit - - BL __user_setup_stackheap - MOV R1,R2 - BL __rt_lib_init - BL osKernelInitialize - BL set_main_stack - LDR R0,=os_thread_def_main - MOVS R1,#0 - BL osThreadCreate - BL osKernelStart - BL exit - - ALIGN -} -#endif - -#elif defined (__GNUC__) - -#ifdef __CS3__ - -/* CS3 start_c routine. - * - * Copyright (c) 2006, 2007 CodeSourcery Inc - * - * The authors hereby grant permission to use, copy, modify, distribute, - * and license this software and its documentation for any purpose, provided - * that existing copyright notices are retained in all copies and that this - * notice is included verbatim in any distributions. No written agreement, - * license, or royalty fee is required for any of the authorized uses. - * Modifications to this software may be copyrighted by their authors - * and need not follow the licensing terms described here, provided that - * the new terms are clearly indicated on the first page of each file where - * they apply. - */ - -#include "cs3.h" - -extern void __libc_init_array (void); - -__attribute ((noreturn)) void __cs3_start_c (void){ - unsigned regions = __cs3_region_num; - const struct __cs3_region *rptr = __cs3_regions; - - /* Initialize memory */ - for (regions = __cs3_region_num, rptr = __cs3_regions; regions--; rptr++) { - long long *src = (long long *)rptr->init; - long long *dst = (long long *)rptr->data; - unsigned limit = rptr->init_size; - unsigned count; - - if (src != dst) - for (count = 0; count != limit; count += sizeof (long long)) - *dst++ = *src++; - else - dst = (long long *)((char *)dst + limit); - limit = rptr->zero_size; - for (count = 0; count != limit; count += sizeof (long long)) - *dst++ = 0; - } - - /* Run initializers. */ - __libc_init_array (); - - osKernelInitialize(); - set_main_stack(); - osThreadCreate(&os_thread_def_main, NULL); - osKernelStart(); - for (;;); -} - -#else - -__attribute__((naked)) void software_init_hook (void) { - __asm ( - ".syntax unified\n" - ".thumb\n" - "movs r0,#0\n" - "movs r1,#0\n" - "mov r4,r0\n" - "mov r5,r1\n" - "ldr r0,= __libc_fini_array\n" - "bl atexit\n" - "bl __libc_init_array\n" - "mov r0,r4\n" - "mov r1,r5\n" - "bl osKernelInitialize\n" - "bl set_main_stack\n" - "ldr r0,=os_thread_def_main\n" - "movs r1,#0\n" - "bl osThreadCreate\n" - "bl osKernelStart\n" - "bl exit\n" - ); -} - -#endif - -#elif defined (__ICCARM__) - -extern int __low_level_init(void); -extern void __iar_data_init3(void); -extern void exit(int arg); - -__noreturn __stackless void __cmain(void) { - int a; - - if (__low_level_init() != 0) { - __iar_data_init3(); - } - osKernelInitialize(); - osThreadCreate(&os_thread_def_main, NULL); - a = osKernelStart(); - exit(a); -} - -#endif - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ - -
--- a/rtx/RTX_Conf.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RTX_CONFIG.H - * Purpose: Exported functions of RTX_Config.c - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - - -/* Error Codes */ -#define OS_ERR_STK_OVF 1 -#define OS_ERR_FIFO_OVF 2 -#define OS_ERR_MBX_OVF 3 - -/* Definitions */ -#define BOX_ALIGN_8 0x80000000 -#define _declare_box(pool,size,cnt) U32 pool[(((size)+3)/4)*(cnt) + 3] -#define _declare_box8(pool,size,cnt) U64 pool[(((size)+7)/8)*(cnt) + 2] -#define _init_box8(pool,size,bsize) _init_box (pool,size,(bsize) | BOX_ALIGN_8) - -/* Variables */ -extern U32 idle_task_stack[]; -extern U32 os_fifo[]; -extern void *os_active_TCB[]; - -/* Constants */ -extern U16 const os_maxtaskrun; -extern U32 const os_trv; -extern U8 const os_flags; -extern U32 const os_rrobin; -extern U32 const os_clockrate; -extern U32 const os_timernum; -extern U16 const idle_task_stack_size; - -extern U8 const os_fifo_size; - -/* Functions */ -extern void os_idle_demon (void); -extern int os_tick_init (void); -extern void os_tick_irqack (void); -extern void os_tmr_call (U16 info); -extern void os_error (U32 err_code); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/rtx/RTX_Conf_CM.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,289 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RTX_Conf_CM.C - * Purpose: Configuration of CMSIS RTX Kernel for Cortex-M - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "cmsis_os.h" - - -/*---------------------------------------------------------------------------- - * RTX User configuration part BEGIN - *---------------------------------------------------------------------------*/ - -//-------- <<< Use Configuration Wizard in Context Menu >>> ----------------- -// -// <h>Thread Configuration -// ======================= -// -// <o>Number of concurrent running threads <0-250> -// <i> Defines max. number of threads that will run at the same time. -// counting "main", but not counting "osTimerThread" -// <i> Default: 6 -#ifndef OS_TASKCNT -# if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088) || defined(TARGET_LPC4337) || defined(TARGET_LPC1347) || defined(TARGET_K64F) || defined(TARGET_STM32F401RE)\ - || defined(TARGET_KL46Z) || defined(TARGET_KL43Z) || defined(TARGET_STM32F407) || defined(TARGET_F407VG) || defined(TARGET_STM32F303VC) || defined(TARGET_LPC1549) || defined(TARGET_LPC11U68) || defined(TARGET_NRF51822) || defined(TARGET_STM32F411RE) -# define OS_TASKCNT 14 -# elif defined(TARGET_LPC11U24) || defined(TARGET_LPC11U35_401) || defined(TARGET_LPC11U35_501) || defined(TARGET_LPCCAPPUCCINO) || defined(TARGET_LPC1114) \ - || defined(TARGET_LPC812) || defined(TARGET_KL25Z) || defined(TARGET_KL05Z) || defined(TARGET_STM32F100RB) || defined(TARGET_STM32F051R8) \ - || defined(TARGET_STM32F103RB) || defined(TARGET_LPC824) || defined(TARGET_STM32F302R8) || defined(TARGET_STM32F334R8) || defined(TARGET_STM32F334C8) -# define OS_TASKCNT 6 -# else -# error "no target defined" -# endif -#endif - -// <o>Scheduler (+ interrupts) stack size [bytes] <64-4096:8><#/4> -#ifndef OS_SCHEDULERSTKSIZE -# if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088) || defined(TARGET_LPC4337) || defined(TARGET_LPC1347) || defined(TARGET_K64F) || defined(TARGET_STM32F401RE)\ - || defined(TARGET_KL46Z) || defined(TARGET_KL43Z) || defined(TARGET_STM32F407) || defined(TARGET_F407VG) || defined(TARGET_STM32F303VC) || defined(TARGET_LPC1549) || defined(TARGET_LPC11U68) || defined(TARGET_NRF51822) || defined(TARGET_STM32F411RE) -# define OS_SCHEDULERSTKSIZE 256 -# elif defined(TARGET_LPC11U24) || defined(TARGET_LPC11U35_401) || defined(TARGET_LPC11U35_501) || defined(TARGET_LPCCAPPUCCINO) || defined(TARGET_LPC1114) \ - || defined(TARGET_LPC812) || defined(TARGET_KL25Z) || defined(TARGET_KL05Z) || defined(TARGET_STM32F100RB) || defined(TARGET_STM32F051R8) \ - || defined(TARGET_STM32F103RB) || defined(TARGET_LPC824) || defined(TARGET_STM32F302R8) || defined(TARGET_STM32F334R8) || defined(TARGET_STM32F334C8) -# define OS_SCHEDULERSTKSIZE 128 -# else -# error "no target defined" -# endif -#endif - -// <o>Idle stack size [bytes] <64-4096:8><#/4> -// <i> Defines default stack size for the Idle thread. -#ifndef OS_IDLESTKSIZE - #define OS_IDLESTKSIZE 128 -#endif - -// <o>Timer Thread stack size [bytes] <64-4096:8><#/4> -// <i> Defines stack size for Timer thread. -// <i> Default: 200 -#ifndef OS_TIMERSTKSZ - #define OS_TIMERSTKSZ WORDS_STACK_SIZE -#endif - -// <q>Check for stack overflow -// <i> Includes the stack checking code for stack overflow. -// <i> Note that additional code reduces the Kernel performance. -#ifndef OS_STKCHECK - #define OS_STKCHECK 1 -#endif - -// <o>Processor mode for thread execution -// <0=> Unprivileged mode -// <1=> Privileged mode -// <i> Default: Privileged mode -#ifndef OS_RUNPRIV - #define OS_RUNPRIV 1 -#endif - -// </h> -// <h>SysTick Timer Configuration -// ============================== -// -// <o>Timer clock value [Hz] <1-1000000000> -// <i> Defines the timer clock value. -// <i> Default: 6000000 (6MHz) -#ifndef OS_CLOCK -# if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) -# define OS_CLOCK 96000000 - -# elif defined(TARGET_LPC1347) || defined(TARGET_STM32F303VC) || defined(TARGET_LPC1549) || defined(TARGET_STM32F302R8) || defined(TARGET_STM32F334R8) || defined(TARGET_STM32F334C8) -# define OS_CLOCK 72000000 - -# elif defined(TARGET_LPC11U24) || defined(TARGET_LPC11U35_401) || defined(TARGET_LPC11U35_501) || defined(TARGET_LPCCAPPUCCINO) || defined(TARGET_LPC1114) || defined(TARGET_KL25Z) || defined(TARGET_KL05Z) || defined(TARGET_KL46Z) || defined(TARGET_KL43Z) || defined(TARGET_STM32F051R8) || defined(TARGET_LPC11U68) -# define OS_CLOCK 48000000 - -# elif defined(TARGET_LPC812) -# define OS_CLOCK 36000000 - -# elif defined(TARGET_LPC824) -# define OS_CLOCK 30000000 - -# elif defined(TARGET_STM32F100RB) -# define OS_CLOCK 24000000 - -# elif defined(TARGET_LPC4088) || defined(TARGET_K64F) -# define OS_CLOCK 120000000 - -# elif defined(TARGET_LPC4337) -# define OS_CLOCK 204000000 - -# elif defined(TARGET_STM32F407) || defined(TARGET_F407VG) -# define OS_CLOCK 168000000 - -# elif defined(TARGET_NRF51822) -# define OS_CLOCK 16000000 - -# elif defined(TARGET_STM32F401RE) -# define OS_CLOCK 84000000 - -# elif defined(TARGET_STM32F411RE) -# define OS_CLOCK 100000000 - -#elif defined(TARGET_STM32F103RB) -# define OS_CLOCK 72000000 - -# else -# error "no target defined" -# endif -#endif - -// <o>Timer tick value [us] <1-1000000> -// <i> Defines the timer tick value. -// <i> Default: 1000 (1ms) -#ifndef OS_TICK - #define OS_TICK 1000 -#endif - -// </h> - -// <h>System Configuration -// ======================= -// -// <e>Round-Robin Thread switching -// =============================== -// -// <i> Enables Round-Robin Thread switching. -#ifndef OS_ROBIN - #define OS_ROBIN 1 -#endif - -// <o>Round-Robin Timeout [ticks] <1-1000> -// <i> Defines how long a thread will execute before a thread switch. -// <i> Default: 5 -#ifndef OS_ROBINTOUT - #define OS_ROBINTOUT 5 -#endif - -// </e> - -// <e>User Timers -// ============== -// <i> Enables user Timers -#ifndef OS_TIMERS - #define OS_TIMERS 1 -#endif - -// <o>Timer Thread Priority -// <1=> Low -// <2=> Below Normal -// <3=> Normal -// <4=> Above Normal -// <5=> High -// <6=> Realtime (highest) -// <i> Defines priority for Timer Thread -// <i> Default: High -#ifndef OS_TIMERPRIO - #define OS_TIMERPRIO 5 -#endif - -// <o>Timer Callback Queue size <1-32> -// <i> Number of concurrent active timer callback functions. -// <i> Default: 4 -#ifndef OS_TIMERCBQSZ - #define OS_TIMERCBQS 4 -#endif - -// </e> - -// <o>ISR FIFO Queue size<4=> 4 entries <8=> 8 entries -// <12=> 12 entries <16=> 16 entries -// <24=> 24 entries <32=> 32 entries -// <48=> 48 entries <64=> 64 entries -// <96=> 96 entries -// <i> ISR functions store requests to this buffer, -// <i> when they are called from the interrupt handler. -// <i> Default: 16 entries -#ifndef OS_FIFOSZ - #define OS_FIFOSZ 16 -#endif - -// </h> - -//------------- <<< end of configuration section >>> ----------------------- - -// Standard library system mutexes -// =============================== -// Define max. number system mutexes that are used to protect -// the arm standard runtime library. For microlib they are not used. -#ifndef OS_MUTEXCNT - #define OS_MUTEXCNT 12 -#endif - -/*---------------------------------------------------------------------------- - * RTX User configuration part END - *---------------------------------------------------------------------------*/ - -#define OS_TRV ((uint32_t)(((double)OS_CLOCK*(double)OS_TICK)/1E6)-1) - - -/*---------------------------------------------------------------------------- - * OS Idle daemon - *---------------------------------------------------------------------------*/ -void os_idle_demon (void) { - /* The idle demon is a system thread, running when no other thread is */ - /* ready to run. */ - - /* Sleep: ideally, we should put the chip to sleep. - Unfortunately, this usually requires disconnecting the interface chip (debugger). - This can be done, but it would break the local file system. - */ - for (;;) { - // sleep(); - } -} - -/*---------------------------------------------------------------------------- - * RTX Errors - *---------------------------------------------------------------------------*/ -extern void mbed_die(void); - -void os_error (uint32_t err_code) { - /* This function is called when a runtime error is detected. Parameter */ - /* 'err_code' holds the runtime error code (defined in RTX_Conf.h). */ - mbed_die(); -} - -void sysThreadError(osStatus status) { - if (status != osOK) { - mbed_die(); - } -} - -/*---------------------------------------------------------------------------- - * RTX Configuration Functions - *---------------------------------------------------------------------------*/ - -#include "RTX_CM_lib.h" - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/ARM/HAL_CA9.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,416 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: HAL_CA9.c + * Purpose: Hardware Abstraction Layer for Cortex-A9 + * Rev.: 3 Sept 2013 + *---------------------------------------------------------------------------- + * + * Copyright (c) 2012 - 2013 ARM Limited + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "RTX_Config.h" +#include "rt_System.h" +#include "rt_Task.h" +#include "rt_List.h" +#include "rt_MemBox.h" +#include "rt_HAL_CA.h" + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + +//For A-class, set USR/SYS stack +__asm void rt_set_PSP (U32 stack) { + ARM + + MRS R1, CPSR + CPS #MODE_SYS ;no effect in USR mode + ISB + MOV SP, R0 + MSR CPSR_c, R1 ;no effect in USR mode + ISB + BX LR + +} + +//For A-class, get USR/SYS stack +__asm U32 rt_get_PSP (void) { + ARM + + MRS R1, CPSR + CPS #MODE_SYS ;no effect in USR mode + ISB + MOV R0, SP + MSR CPSR_c, R1 ;no effect in USR mode + ISB + BX LR +} + +/*--------------------------- _alloc_box ------------------------------------*/ +__asm void *_alloc_box (void *box_mem) { + /* Function wrapper for Unprivileged/Privileged mode. */ + ARM + + LDR R12,=__cpp(rt_alloc_box) + MRS R2, CPSR + LSLS R2, #28 + BXNE R12 + SVC 0 + BX LR +} + + +/*--------------------------- _free_box -------------------------------------*/ +__asm int _free_box (void *box_mem, void *box) { + /* Function wrapper for Unprivileged/Privileged mode. */ + ARM + + LDR R12,=__cpp(rt_free_box) + MRS R2, CPSR + LSLS R2, #28 + BXNE R12 + SVC 0 + BX LR + +} + +/*-------------------------- SVC_Handler -----------------------------------*/ + +#pragma push +#pragma arm +__asm void SVC_Handler (void) { + PRESERVE8 + ARM + + IMPORT rt_tsk_lock + IMPORT rt_tsk_unlock + IMPORT SVC_Count + IMPORT SVC_Table + IMPORT rt_stk_check + IMPORT FPUEnable + +Mode_SVC EQU 0x13 + + SRSFD SP!, #Mode_SVC ; Push LR_SVC and SPRS_SVC onto SVC mode stack + PUSH {R4} ; Push R4 so we can use it as a temp + + MRS R4,SPSR ; Get SPSR + TST R4,#CPSR_T_BIT ; Check Thumb Bit + LDRNEH R4,[LR,#-2] ; Thumb: Load Halfword + BICNE R4,R4,#0xFF00 ; Extract SVC Number + LDREQ R4,[LR,#-4] ; ARM: Load Word + BICEQ R4,R4,#0xFF000000 ; Extract SVC Number + + /* Lock out systick and re-enable interrupts */ + PUSH {R0-R3,R12,LR} + + AND R12, SP, #4 ; Ensure stack is 8-byte aligned + SUB SP, SP, R12 ; Adjust stack + PUSH {R12, LR} ; Store stack adjustment and dummy LR to SVC stack + + BLX rt_tsk_lock + CPSIE i + + POP {R12, LR} ; Get stack adjustment & discard dummy LR + ADD SP, SP, R12 ; Unadjust stack + + POP {R0-R3,R12,LR} + + CMP R4,#0 + BNE SVC_User + + MRS R4,SPSR + PUSH {R4} ; Push R4 so we can use it as a temp + AND R4, SP, #4 ; Ensure stack is 8-byte aligned + SUB SP, SP, R4 ; Adjust stack + PUSH {R4, LR} ; Store stack adjustment and dummy LR + BLX R12 + POP {R4, LR} ; Get stack adjustment & discard dummy LR + ADD SP, SP, R4 ; Unadjust stack + POP {R4} ; Restore R4 + MSR SPSR_CXSF,R4 + + /* Here we will be in SVC mode (even if coming in from PendSV_Handler or OS_Tick_Handler) */ +Sys_Switch + LDR LR,=__cpp(&os_tsk) + LDM LR,{R4,LR} ; os_tsk.run, os_tsk.new + CMP R4,LR + BNE switching + + PUSH {R0-R3,R12,LR} + + AND R12, SP, #4 ; Ensure stack is 8-byte aligned + SUB SP, SP, R12 ; Adjust stack + PUSH {R12, LR} ; Store stack adjustment and dummy LR to SVC stack + + CPSID i + BLX rt_tsk_unlock + + POP {R12, LR} ; Get stack adjustment & discard dummy LR + ADD SP, SP, R12 ; Unadjust stack + + POP {R0-R3,R12,LR} + POP {R4} + RFEFD SP! ; Return from exception, no task switch + +switching + CLREX + CMP R4,#0 + ADDEQ SP,SP,#12 ; Original R4, LR & SPSR do not need to be popped when we are paging in a different task + BEQ SVC_Next ; Runtask deleted? + + + PUSH {R8-R11} //R4 and LR already stacked + MOV R10,R4 ; Preserve os_tsk.run + MOV R11,LR ; Preserve os_tsk.new + + ADD R8,SP,#16 ; Unstack R4,LR + LDMIA R8,{R4,LR} + + SUB SP,SP,#4 ; Make space on the stack for the next instn + STMIA SP,{SP}^ ; Put User SP onto stack + POP {R8} ; Pop User SP into R8 + + MRS R9,SPSR + STMDB R8!,{R9} ; User CPSR + STMDB R8!,{LR} ; User PC + STMDB R8,{LR}^ ; User LR + SUB R8,R8,#4 ; No writeback for store of User LR + STMDB R8!,{R0-R3,R12} ; User R0-R3,R12 + MOV R3,R10 ; os_tsk.run + MOV LR,R11 ; os_tsk.new + POP {R9-R12} + ADD SP,SP,#12 ; Fix up SP for unstack of R4, LR & SPSR + STMDB R8!,{R4-R7,R9-R12} ; User R4-R11 + + //If applicable, stack VFP state + MRC p15,0,R1,c1,c0,2 ; VFP/NEON access enabled? (CPACR) + AND R2,R1,#0x00F00000 + CMP R2,#0x00F00000 + BNE no_outgoing_vfp + VMRS R2,FPSCR + STMDB R8!,{R2,R4} ; Push FPSCR, maintain 8-byte alignment + VSTMDB R8!,{S0-S31} + LDRB R2,[R3,#TCB_STACKF] ; Record in TCB that VFP state is stacked + ORR R2,#2 + STRB R2,[R3,#TCB_STACKF] + +no_outgoing_vfp + STR R8,[R3,#TCB_TSTACK] + MOV R4,LR + + PUSH {R4} ; Push R4 so we can use it as a temp + AND R4, SP, #4 ; Ensure stack is 8-byte aligned + SUB SP, SP, R4 ; Adjust stack + PUSH {R4, LR} ; Store stack adjustment and dummy LR to SVC stack + + BLX rt_stk_check + + POP {R4, LR} ; Get stack adjustment & discard dummy LR + ADD SP, SP, R4 ; Unadjust stack + POP {R4} ; Restore R4 + + MOV LR,R4 + +SVC_Next //R4 == os_tsk.run, LR == os_tsk.new, R0-R3, R5-R12 corruptible + LDR R1,=__cpp(&os_tsk) ; os_tsk.run = os_tsk.new + STR LR,[R1] + LDRB R1,[LR,#TCB_TID] ; os_tsk.run->task_id + LSL R1,#8 ; Store PROCID + MCR p15,0,R1,c13,c0,1 ; Write CONTEXTIDR + + LDR R0,[LR,#TCB_TSTACK] ; os_tsk.run->tsk_stack + + //Does incoming task have VFP state in stack? + LDRB R3,[LR,#TCB_STACKF] + TST R3,#0x2 + MRC p15,0,R1,c1,c0,2 ; Read CPACR + ANDEQ R1,R1,#0xFF0FFFFF ; Disable VFP access if incoming task does not have stacked VFP state + ORRNE R1,R1,#0x00F00000 ; Enable VFP access if incoming task does have stacked VFP state + MCR p15,0,R1,c1,c0,2 ; Write CPACR + BEQ no_incoming_vfp + ISB ; We only need the sync if we enabled, otherwise we will context switch before next VFP instruction anyway + VLDMIA R0!,{S0-S31} + LDR R2,[R0] + VMSR FPSCR,R2 + ADD R0,R0,#8 + +no_incoming_vfp + LDR R1,[R0,#60] ; Restore User CPSR + MSR SPSR_CXSF,R1 + LDMIA R0!,{R4-R11} ; Restore User R4-R11 + ADD R0,R0,#4 ; Restore User R1-R3,R12 + LDMIA R0!,{R1-R3,R12} + LDMIA R0,{LR}^ ; Restore User LR + ADD R0,R0,#4 ; No writeback for load to user LR + LDMIA R0!,{LR} ; Restore User PC + ADD R0,R0,#4 ; Correct User SP for unstacked user CPSR + + PUSH {R0} ; Push R0 onto stack + LDMIA SP,{SP}^ ; Get R0 off stack into User SP + ADD SP,SP,#4 ; Put SP back + + LDR R0,[R0,#-32] ; Restore R0 + + PUSH {R0-R3,R12,LR} + + AND R12, SP, #4 ; Ensure stack is 8-byte aligned + SUB SP, SP, R12 ; Adjust stack + PUSH {R12, LR} ; Store stack adjustment and dummy LR to SVC stack + + CPSID i + BLX rt_tsk_unlock + + POP {R12, LR} ; Get stack adjustment & discard dummy LR + ADD SP, SP, R12 ; Unadjust stack + + POP {R0-R3,R12,LR} + + MOVS PC,LR ; Return from exception + + + /*------------------- User SVC -------------------------------*/ + +SVC_User + LDR R12,=SVC_Count + LDR R12,[R12] + CMP R4,R12 ; Check for overflow + BHI SVC_Done + + LDR R12,=SVC_Table-4 + LDR R12,[R12,R4,LSL #2] ; Load SVC Function Address + MRS R4,SPSR ; Save SPSR + PUSH {R4} ; Push R4 so we can use it as a temp + AND R4, SP, #4 ; Ensure stack is 8-byte aligned + SUB SP, SP, R4 ; Adjust stack + PUSH {R4, LR} ; Store stack adjustment and dummy LR + BLX R12 ; Call SVC Function + POP {R4, LR} ; Get stack adjustment & discard dummy LR + ADD SP, SP, R4 ; Unadjust stack + POP {R4} ; Restore R4 + MSR SPSR_CXSF,R4 ; Restore SPSR + +SVC_Done + PUSH {R0-R3,R12,LR} + + PUSH {R4} ; Push R4 so we can use it as a temp + AND R4, SP, #4 ; Ensure stack is 8-byte aligned + SUB SP, SP, R4 ; Adjust stack + PUSH {R4, LR} ; Store stack adjustment and dummy LR + + CPSID i + BLX rt_tsk_unlock + + POP {R4, LR} ; Get stack adjustment & discard dummy LR + ADD SP, SP, R4 ; Unadjust stack + POP {R4} ; Restore R4 + + POP {R0-R3,R12,LR} + POP {R4} + RFEFD SP! ; Return from exception +} +#pragma pop + +#pragma push +#pragma arm +__asm void PendSV_Handler (U32 IRQn) { + ARM + + IMPORT rt_tsk_lock + IMPORT IRQNestLevel + + ADD SP,SP,#8 //fix up stack pointer (R0 has been pushed and will never be popped, R1 was pushed for stack alignment) + + //Disable systick interrupts, then write EOIR. We want interrupts disabled before we enter the context switcher. + PUSH {R0, R1} + BLX rt_tsk_lock + POP {R0, R1} + LDR R1, =__cpp(&GICInterface_BASE) + LDR R1, [R1, #0] + STR R0, [R1, #0x10] + + LDR R0, =IRQNestLevel ; Get address of nesting counter + LDR R1, [R0] + SUB R1, R1, #1 ; Decrement nesting counter + STR R1, [R0] + + BLX __cpp(rt_pop_req) + + POP {R1, LR} ; Get stack adjustment & discard dummy LR + ADD SP, SP, R1 ; Unadjust stack + + LDR R0,[SP,#24] + MSR SPSR_CXSF,R0 + POP {R0-R3,R12} ; Leave SPSR & LR on the stack + PUSH {R4} + B Sys_Switch +} +#pragma pop + + +#pragma push +#pragma arm +__asm void OS_Tick_Handler (U32 IRQn) { + ARM + + IMPORT rt_tsk_lock + IMPORT IRQNestLevel + + ADD SP,SP,#8 //fix up stack pointer (R0 has been pushed and will never be popped, R1 was pushed for stack alignment) + + PUSH {R0, R1} + BLX rt_tsk_lock + POP {R0, R1} + LDR R1, =__cpp(&GICInterface_BASE) + LDR R1, [R1, #0] + STR R0, [R1, #0x10] + + LDR R0, =IRQNestLevel ; Get address of nesting counter + LDR R1, [R0] + SUB R1, R1, #1 ; Decrement nesting counter + STR R1, [R0] + + BLX __cpp(os_tick_irqack) + BLX __cpp(rt_systick) + + POP {R1, LR} ; Get stack adjustment & discard dummy LR + ADD SP, SP, R1 ; Unadjust stack + + LDR R0,[SP,#24] + MSR SPSR_CXSF,R0 + POP {R0-R3,R12} ; Leave SPSR & LR on the stack + PUSH {R4} + B Sys_Switch +} +#pragma pop + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/ARM/SVC_Table.s Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,57 @@ +;/*---------------------------------------------------------------------------- +; * RL-ARM - RTX +; *---------------------------------------------------------------------------- +; * Name: SVC_TABLE.S +; * Purpose: Pre-defined SVC Table for Cortex-M +; * Rev.: V4.60 +; *---------------------------------------------------------------------------- +; * +; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH +; * All rights reserved. +; * Redistribution and use in source and binary forms, with or without +; * modification, are permitted provided that the following conditions are met: +; * - Redistributions of source code must retain the above copyright +; * notice, this list of conditions and the following disclaimer. +; * - Redistributions in binary form must reproduce the above copyright +; * notice, this list of conditions and the following disclaimer in the +; * documentation and/or other materials provided with the distribution. +; * - Neither the name of ARM nor the names of its contributors may be used +; * to endorse or promote products derived from this software without +; * specific prior written permission. +; * +; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE +; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; * POSSIBILITY OF SUCH DAMAGE. +; *---------------------------------------------------------------------------*/ + + + AREA SVC_TABLE, CODE, READONLY + + EXPORT SVC_Count + +SVC_Cnt EQU (SVC_End-SVC_Table)/4 +SVC_Count DCD SVC_Cnt + +; Import user SVC functions here. +; IMPORT __SVC_1 + + EXPORT SVC_Table +SVC_Table +; Insert user SVC functions here. SVC 0 used by RTL Kernel. +; DCD __SVC_1 ; InitMemorySubsystem + +SVC_End + + END + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/HAL_CA.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,126 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: HAL_CA.C + * Purpose: Hardware Abstraction Layer for Cortex-A + * Rev.: + *---------------------------------------------------------------------------- + * + * Copyright (c) 2012 ARM Limited + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "RTX_Config.h" +#include "rt_HAL_CA.h" + +/*--------------------------- os_init_context -------------------------------*/ + +void rt_init_stack (P_TCB p_TCB, FUNCP task_body) { + /* Prepare TCB and saved context for a first time start of a task. */ + U32 *stk,i,size; + + /* Prepare a complete interrupt frame for first task start */ + size = p_TCB->priv_stack >> 2; + if (size == 0) { + size = (U16)os_stackinfo >> 2; + } + /* Write to the top of stack. */ + stk = &p_TCB->stack[size]; + + /* Auto correct to 8-byte ARM stack alignment. */ + if ((U32)stk & 0x04) { + stk--; + } + + stk -= 16; + + /* Initial PC and default CPSR */ + stk[14] = (U32)task_body; + /* Task run mode is inherited from the startup file. */ + /* (non-privileged USER or privileged SYSTEM mode) */ + stk[15] = (os_flags & 1) ? INIT_CPSR_SYS : INIT_CPSR_USER; + /* Set T-bit if task function in Thumb mode. */ + if ((U32)task_body & 1) { + stk[15] |= CPSR_T_BIT; + } + /* Assign a void pointer to R0. */ + stk[8] = (U32)p_TCB->msg; + /* Clear R1-R12,LR registers. */ + for (i = 0; i < 8; i++) { + stk[i] = 0; + } + for (i = 9; i < 14; i++) { + stk[i] = 0; + } + + /* Initial Task stack pointer. */ + p_TCB->tsk_stack = (U32)stk; + + /* Task entry point. */ + p_TCB->ptask = task_body; + + /* Set a magic word for checking of stack overflow. */ + p_TCB->stack[0] = MAGIC_WORD; +} + + +/*--------------------------- rt_ret_val ----------------------------------*/ + +static __inline U32 *rt_ret_regs (P_TCB p_TCB) { + /* Get pointer to task return value registers (R0..R3) in Stack */ +#if (__TARGET_FPU_VFP) + if (p_TCB->stack_frame & 0x2) { + /* Extended Stack Frame: S0-31,FPSCR,Reserved,R4-R11,R0-R3,R12,LR,PC,xPSR */ + return (U32 *)(p_TCB->tsk_stack + 8*4 + 34*4); + } else { + /* Basic Stack Frame: R4-R11,R0-R3,R12,LR,PC,xPSR */ + return (U32 *)(p_TCB->tsk_stack + 8*4); + } +#else + /* Stack Frame: R4-R11,R0-R3,R12,LR,PC,xPSR */ + return (U32 *)(p_TCB->tsk_stack + 8*4); +#endif +} + +void rt_ret_val (P_TCB p_TCB, U32 v0) { + U32 *ret; + + ret = rt_ret_regs(p_TCB); + ret[0] = v0; +} + +void rt_ret_val2(P_TCB p_TCB, U32 v0, U32 v1) { + U32 *ret; + + ret = rt_ret_regs(p_TCB); + ret[0] = v0; + ret[1] = v1; +} + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/HAL_CM.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,168 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: HAL_CM.C + * Purpose: Hardware Abstraction Layer for Cortex-M + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "RTX_Config.h" +#include "rt_HAL_CM.h" + + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +#ifdef DBG_MSG +BIT dbg_msg; +#endif + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_init_stack ---------------------------------*/ + +void rt_init_stack (P_TCB p_TCB, FUNCP task_body) { + /* Prepare TCB and saved context for a first time start of a task. */ + U32 *stk,i,size; + + /* Prepare a complete interrupt frame for first task start */ + size = p_TCB->priv_stack >> 2; + if (size == 0) { + size = (U16)os_stackinfo >> 2; + } + + /* Write to the top of stack. */ + stk = &p_TCB->stack[size]; + + /* Auto correct to 8-byte ARM stack alignment. */ + if ((U32)stk & 0x04) { + stk--; + } + + stk -= 16; + + /* Default xPSR and initial PC */ + stk[15] = INITIAL_xPSR; + stk[14] = (U32)task_body; + + /* Clear R4-R11,R0-R3,R12,LR registers. */ + for (i = 0; i < 14; i++) { + stk[i] = 0; + } + + /* Assign a void pointer to R0. */ + stk[8] = (U32)p_TCB->msg; + + /* Initial Task stack pointer. */ + p_TCB->tsk_stack = (U32)stk; + + /* Task entry point. */ + p_TCB->ptask = task_body; + + /* Set a magic word for checking of stack overflow. */ + p_TCB->stack[0] = MAGIC_WORD; +} + + +/*--------------------------- rt_ret_val ----------------------------------*/ + +static __inline U32 *rt_ret_regs (P_TCB p_TCB) { + /* Get pointer to task return value registers (R0..R3) in Stack */ +#if (__TARGET_FPU_VFP) + if (p_TCB->stack_frame) { + /* Extended Stack Frame: R4-R11,S16-S31,R0-R3,R12,LR,PC,xPSR,S0-S15,FPSCR */ + return (U32 *)(p_TCB->tsk_stack + 8*4 + 16*4); + } else { + /* Basic Stack Frame: R4-R11,R0-R3,R12,LR,PC,xPSR */ + return (U32 *)(p_TCB->tsk_stack + 8*4); + } +#else + /* Stack Frame: R4-R11,R0-R3,R12,LR,PC,xPSR */ + return (U32 *)(p_TCB->tsk_stack + 8*4); +#endif +} + +void rt_ret_val (P_TCB p_TCB, U32 v0) { + U32 *ret; + + ret = rt_ret_regs(p_TCB); + ret[0] = v0; +} + +void rt_ret_val2(P_TCB p_TCB, U32 v0, U32 v1) { + U32 *ret; + + ret = rt_ret_regs(p_TCB); + ret[0] = v0; + ret[1] = v1; +} + + +/*--------------------------- dbg_init --------------------------------------*/ + +#ifdef DBG_MSG +void dbg_init (void) { + if ((DEMCR & DEMCR_TRCENA) && + (ITM_CONTROL & ITM_ITMENA) && + (ITM_ENABLE & (1UL << 31))) { + dbg_msg = __TRUE; + } +} +#endif + +/*--------------------------- dbg_task_notify -------------------------------*/ + +#ifdef DBG_MSG +void dbg_task_notify (P_TCB p_tcb, BOOL create) { + while (ITM_PORT31_U32 == 0); + ITM_PORT31_U32 = (U32)p_tcb->ptask; + while (ITM_PORT31_U32 == 0); + ITM_PORT31_U16 = (create << 8) | p_tcb->task_id; +} +#endif + +/*--------------------------- dbg_task_switch -------------------------------*/ + +#ifdef DBG_MSG +void dbg_task_switch (U32 task_id) { + while (ITM_PORT31_U32 == 0); + ITM_PORT31_U8 = task_id; +} +#endif + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/RTX_CM_lib.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,423 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RTX_CM_LIB.H + * Purpose: RTX Kernel System Configuration + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#if defined (__CC_ARM) +#pragma O3 +#define __USED __attribute__((used)) +#elif defined (__GNUC__) +#pragma GCC optimize ("O3") +#define __USED __attribute__((used)) +#elif defined (__ICCARM__) +#define __USED __root +#endif + + +/*---------------------------------------------------------------------------- + * Definitions + *---------------------------------------------------------------------------*/ + +#define _declare_box(pool,size,cnt) uint32_t pool[(((size)+3)/4)*(cnt) + 3] +#define _declare_box8(pool,size,cnt) uint64_t pool[(((size)+7)/8)*(cnt) + 2] + +#define OS_TCB_SIZE 48 +#define OS_TMR_SIZE 8 + +#if defined (__CC_ARM) && !defined (__MICROLIB) + +typedef void *OS_ID; +typedef uint32_t OS_TID; +typedef uint32_t OS_MUT[3]; +typedef uint32_t OS_RESULT; + +#define runtask_id() rt_tsk_self() +#define mutex_init(m) rt_mut_init(m) +#define mutex_wait(m) os_mut_wait(m,0xFFFF) +#define mutex_rel(m) os_mut_release(m) + +extern OS_TID rt_tsk_self (void); +extern void rt_mut_init (OS_ID mutex); +extern OS_RESULT rt_mut_release (OS_ID mutex); +extern OS_RESULT rt_mut_wait (OS_ID mutex, uint16_t timeout); + +#define os_mut_wait(mutex,timeout) _os_mut_wait((uint32_t)rt_mut_wait,mutex,timeout) +#define os_mut_release(mutex) _os_mut_release((uint32_t)rt_mut_release,mutex) + +OS_RESULT _os_mut_release (uint32_t p, OS_ID mutex) __svc_indirect(0); +OS_RESULT _os_mut_wait (uint32_t p, OS_ID mutex, uint16_t timeout) __svc_indirect(0); + +#endif + + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +#if (OS_TIMERS != 0) +#define OS_TASK_CNT (OS_TASKCNT + 1) +#define OS_PRIV_CNT (OS_PRIVCNT + 2) +#define OS_STACK_SZ (4*(OS_PRIVSTKSIZE+OS_MAINSTKSIZE+OS_TIMERSTKSZ)) +#else +#define OS_TASK_CNT OS_TASKCNT +#define OS_PRIV_CNT (OS_PRIVCNT + 1) +#define OS_STACK_SZ (4*(OS_PRIVSTKSIZE+OS_MAINSTKSIZE)) +#endif + +uint16_t const os_maxtaskrun = OS_TASK_CNT; +uint32_t const os_stackinfo = (OS_STKCHECK<<24)| (OS_PRIV_CNT<<16) | (OS_STKSIZE*4); +uint32_t const os_rrobin = (OS_ROBIN << 16) | OS_ROBINTOUT; +uint32_t const os_trv = OS_TRV; +uint8_t const os_flags = OS_RUNPRIV; + +/* Export following defines to uVision debugger. */ +__USED uint32_t const os_clockrate = OS_TICK; +__USED uint32_t const os_timernum = 0; + +/* Memory pool for TCB allocation */ +_declare_box (mp_tcb, OS_TCB_SIZE, OS_TASK_CNT); +uint16_t const mp_tcb_size = sizeof(mp_tcb); + +/* Memory pool for System stack allocation (+os_idle_demon). */ +_declare_box8 (mp_stk, OS_STKSIZE*4, OS_TASK_CNT-OS_PRIV_CNT+1); +uint32_t const mp_stk_size = sizeof(mp_stk); + +/* Memory pool for user specified stack allocation (+main, +timer) */ +uint64_t os_stack_mem[2+OS_PRIV_CNT+(OS_STACK_SZ/8)]; +uint32_t const os_stack_sz = sizeof(os_stack_mem); + +#ifndef OS_FIFOSZ + #define OS_FIFOSZ 16 +#endif + +/* Fifo Queue buffer for ISR requests.*/ +uint32_t os_fifo[OS_FIFOSZ*2+1]; +uint8_t const os_fifo_size = OS_FIFOSZ; + +/* An array of Active task pointers. */ +void *os_active_TCB[OS_TASK_CNT]; + +/* User Timers Resources */ +#if (OS_TIMERS != 0) +extern void osTimerThread (void const *argument); +#if defined (__MBED_CMSIS_RTOS_CA9) +osThreadDef(osTimerThread, (osPriority)(OS_TIMERPRIO-3), 4*OS_TIMERSTKSZ); +#else +osThreadDef(osTimerThread, (osPriority)(OS_TIMERPRIO-3), 1, 4*OS_TIMERSTKSZ); +#endif +osThreadId osThreadId_osTimerThread; +osMessageQDef(osTimerMessageQ, OS_TIMERCBQS, void *); +osMessageQId osMessageQId_osTimerMessageQ; +#else +osThreadDef_t os_thread_def_osTimerThread = { NULL }; +osThreadId osThreadId_osTimerThread; +osMessageQDef(osTimerMessageQ, 0, void *); +osMessageQId osMessageQId_osTimerMessageQ; +#endif + +/* Legacy RTX User Timers not used */ +uint32_t os_tmr = 0; +uint32_t const *m_tmr = NULL; +uint16_t const mp_tmr_size = 0; + +#if defined (__CC_ARM) && !defined (__MICROLIB) + /* A memory space for arm standard library. */ + static uint32_t std_libspace[OS_TASK_CNT][96/4]; + static OS_MUT std_libmutex[OS_MUTEXCNT]; + static uint32_t nr_mutex; + extern void *__libspace_start; +#endif + + +/*---------------------------------------------------------------------------- + * RTX Optimizations (empty functions) + *---------------------------------------------------------------------------*/ + +#if OS_ROBIN == 0 + void rt_init_robin (void) {;} + void rt_chk_robin (void) {;} +#endif + +#if OS_STKCHECK == 0 + void rt_stk_check (void) {;} +#endif + + +/*---------------------------------------------------------------------------- + * Standard Library multithreading interface + *---------------------------------------------------------------------------*/ + +#if defined (__CC_ARM) && !defined (__MICROLIB) + +/*--------------------------- __user_perthread_libspace ---------------------*/ + +void *__user_perthread_libspace (void) { + /* Provide a separate libspace for each task. */ + uint32_t idx; + + idx = runtask_id (); + if (idx == 0) { + /* RTX not running yet. */ + return (&__libspace_start); + } + return ((void *)&std_libspace[idx-1]); +} + +/*--------------------------- _mutex_initialize -----------------------------*/ + +int _mutex_initialize (OS_ID *mutex) { + /* Allocate and initialize a system mutex. */ + + if (nr_mutex >= OS_MUTEXCNT) { + /* If you are here, you need to increase the number OS_MUTEXCNT. */ + for (;;); + } + *mutex = &std_libmutex[nr_mutex++]; + mutex_init (*mutex); + return (1); +} + + +/*--------------------------- _mutex_acquire --------------------------------*/ + +__attribute__((used)) void _mutex_acquire (OS_ID *mutex) { + /* Acquire a system mutex, lock stdlib resources. */ + if (runtask_id ()) { + /* RTX running, acquire a mutex. */ + mutex_wait (*mutex); + } +} + + +/*--------------------------- _mutex_release --------------------------------*/ + +__attribute__((used)) void _mutex_release (OS_ID *mutex) { + /* Release a system mutex, unlock stdlib resources. */ + if (runtask_id ()) { + /* RTX running, release a mutex. */ + mutex_rel (*mutex); + } +} + +#endif + + +/*---------------------------------------------------------------------------- + * RTX Startup + *---------------------------------------------------------------------------*/ + +/* Main Thread definition */ +extern int main (void); +osThreadDef_t os_thread_def_main = {(os_pthread)main, osPriorityNormal, 1, 4*OS_MAINSTKSIZE }; + + +#if defined (__CC_ARM) + +#ifdef __MICROLIB +void _main_init (void) __attribute__((section(".ARM.Collect$$$$000000FF"))); +#if __TARGET_ARCH_ARM +#pragma push +#pragma arm +#endif +void _main_init (void) { + osKernelInitialize(); + osThreadCreate(&os_thread_def_main, NULL); + osKernelStart(); + for (;;); +} +#if __TARGET_ARCH_ARM +#pragma pop +#endif +#else +#if 0 +//#ifdef __MBED_CMSIS_RTOS_CA9 +__asm void __rt_entry (void) { + + IMPORT __user_setup_stackheap + IMPORT __rt_lib_init + IMPORT os_thread_def_main + IMPORT osKernelInitialize + IMPORT osKernelStart + IMPORT osThreadCreate + IMPORT InterruptHandlerRegister + IMPORT PendSV_Handler + IMPORT OS_Tick_Handler + IMPORT exit + + BL __user_setup_stackheap + MOV R1,R2 + BL __rt_lib_init + BL osKernelInitialize + LDR R0,=os_thread_def_main + MOVS R1,#0 + BL osThreadCreate + BL osKernelStart + MOVS R0,#0 + LDR R1,=PendSV_Handler + BL InterruptHandlerRegister + MOVS R0,#134 + LDR R1,=OS_Tick_Handler + BL InterruptHandlerRegister + BL exit + + ALIGN +} +#else +__asm void __rt_entry (void) { + + IMPORT __user_setup_stackheap + IMPORT __rt_lib_init + IMPORT os_thread_def_main + IMPORT osKernelInitialize + IMPORT osKernelStart + IMPORT osThreadCreate + IMPORT exit + + BL __user_setup_stackheap + MOV R1,R2 + BL __rt_lib_init + BL osKernelInitialize + LDR R0,=os_thread_def_main + MOVS R1,#0 + BL osThreadCreate + BL osKernelStart + BL exit + + ALIGN +} +#endif +#endif + +#elif defined (__GNUC__) + +#ifdef __CS3__ + +/* CS3 start_c routine. + * + * Copyright (c) 2006, 2007 CodeSourcery Inc + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +#include "cs3.h" + +extern void __libc_init_array (void); + +__attribute ((noreturn)) void __cs3_start_c (void){ + unsigned regions = __cs3_region_num; + const struct __cs3_region *rptr = __cs3_regions; + + /* Initialize memory */ + for (regions = __cs3_region_num, rptr = __cs3_regions; regions--; rptr++) { + long long *src = (long long *)rptr->init; + long long *dst = (long long *)rptr->data; + unsigned limit = rptr->init_size; + unsigned count; + + if (src != dst) + for (count = 0; count != limit; count += sizeof (long long)) + *dst++ = *src++; + else + dst = (long long *)((char *)dst + limit); + limit = rptr->zero_size; + for (count = 0; count != limit; count += sizeof (long long)) + *dst++ = 0; + } + + /* Run initializers. */ + __libc_init_array (); + + osKernelInitialize(); + osThreadCreate(&os_thread_def_main, NULL); + osKernelStart(); + for (;;); +} + +#else + +__attribute__((naked)) void software_init_hook (void) { + __asm ( + ".syntax unified\n" + ".thumb\n" + "movs r0,#0\n" + "movs r1,#0\n" + "mov r4,r0\n" + "mov r5,r1\n" + "ldr r0,= __libc_fini_array\n" + "bl atexit\n" + "bl __libc_init_array\n" + "mov r0,r4\n" + "mov r1,r5\n" + "bl osKernelInitialize\n" + "ldr r0,=os_thread_def_main\n" + "movs r1,#0\n" + "bl osThreadCreate\n" + "bl osKernelStart\n" + "bl exit\n" + ); +} + +#endif + +#elif defined (__ICCARM__) + +extern int __low_level_init(void); +extern void __iar_data_init3(void); +extern void exit(int arg); + +__noreturn __stackless void __cmain(void) { + int a; + + if (__low_level_init() != 0) { + __iar_data_init3(); + } + osKernelInitialize(); + osThreadCreate(&os_thread_def_main, NULL); + a = osKernelStart(); + exit(a); +} + +#endif + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/RTX_Conf_CA.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,319 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RTX_Conf_CM.C + * Purpose: Configuration of CMSIS RTX Kernel + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "cmsis_os.h" + +/*---------------------------------------------------------------------------- + * RTX User configuration part BEGIN + *---------------------------------------------------------------------------*/ + +//-------- <<< Use Configuration Wizard in Context Menu >>> ----------------- +// +// <h>Thread Configuration +// ======================= +// +// <o>Number of concurrent running threads <0-250> +// <i> Defines max. number of threads that will run at the same time. +// <i> Default: 6 +#ifndef OS_TASKCNT + #define OS_TASKCNT 25 +#endif + +// <o>Default Thread stack size [bytes] <64-4096:8><#/4> +// <i> Defines default stack size for threads with osThreadDef stacksz = 0 +// <i> Default: 200 +#ifndef OS_STKSIZE + #define OS_STKSIZE 200 +#endif + +// <o>Main Thread stack size [bytes] <64-4096:8><#/4> +// <i> Defines stack size for main thread. +// <i> Default: 200 +#ifndef OS_MAINSTKSIZE + #define OS_MAINSTKSIZE 512 +#endif + +// <o>Number of threads with user-provided stack size <0-250> +// <i> Defines the number of threads with user-provided stack size. +// <i> Default: 0 +#ifndef OS_PRIVCNT + #define OS_PRIVCNT 8 +#endif + +// <o>Total stack size [bytes] for threads with user-provided stack size <0-4096:8><#/4> +// <i> Defines the combined stack size for threads with user-provided stack size. +// <i> Default: 0 +#ifndef OS_PRIVSTKSIZE + #define OS_PRIVSTKSIZE 4096 +#endif + +// <q>Check for stack overflow +// <i> Includes the stack checking code for stack overflow. +// <i> Note that additional code reduces the Kernel performance. +#ifndef OS_STKCHECK + #define OS_STKCHECK 1 +#endif + +// <o>Processor mode for thread execution +// <0=> Unprivileged mode +// <1=> Privileged mode +// <i> Default: Privileged mode +#ifndef OS_RUNPRIV + #define OS_RUNPRIV 0 +#endif + +// </h> + +// <h>RTX Kernel Timer Tick Configuration +// ====================================== +// <q> Use Cortex-M SysTick timer as RTX Kernel Timer +// <i> Use the Cortex-M SysTick timer as a time-base for RTX. +#ifndef OS_SYSTICK + #define OS_SYSTICK 0 +#endif +// +// <o>Timer clock value [Hz] <1-1000000000> +// <i> Defines the timer clock value. +// <i> Default: 12000000 (12MHz) +#ifndef OS_CLOCK + #define OS_CLOCK 12000000 +#endif + +// <o>Timer tick value [us] <1-1000000> +// <i> Defines the timer tick value. +// <i> Default: 1000 (1ms) +#ifndef OS_TICK + #define OS_TICK 1000 +#endif + +// </h> + +// <h>System Configuration +// ======================= +// +// <e>Round-Robin Thread switching +// =============================== +// +// <i> Enables Round-Robin Thread switching. +#ifndef OS_ROBIN + #define OS_ROBIN 1 +#endif + +// <o>Round-Robin Timeout [ticks] <1-1000> +// <i> Defines how long a thread will execute before a thread switch. +// <i> Default: 5 +#ifndef OS_ROBINTOUT + #define OS_ROBINTOUT 5 +#endif + +// </e> + +// <e>User Timers +// ============== +// <i> Enables user Timers +#ifndef OS_TIMERS + #define OS_TIMERS 1 +#endif + +// <o>Timer Thread Priority +// <1=> Low +// <2=> Below Normal <3=> Normal <4=> Above Normal +// <5=> High +// <6=> Realtime (highest) +// <i> Defines priority for Timer Thread +// <i> Default: High +#ifndef OS_TIMERPRIO + #define OS_TIMERPRIO 5 +#endif + +// <o>Timer Thread stack size [bytes] <64-4096:8><#/4> +// <i> Defines stack size for Timer thread. +// <i> Default: 200 +#ifndef OS_TIMERSTKSZ + #define OS_TIMERSTKSZ 400 +#endif + +// <o>Timer Callback Queue size <1-32> +// <i> Number of concurrent active timer callback functions. +// <i> Default: 4 +#ifndef OS_TIMERCBQS + #define OS_TIMERCBQS 4 +#endif + +// </e> + +// <o>ISR FIFO Queue size<4=> 4 entries <8=> 8 entries +// <12=> 12 entries <16=> 16 entries +// <24=> 24 entries <32=> 32 entries +// <48=> 48 entries <64=> 64 entries +// <96=> 96 entries +// <i> ISR functions store requests to this buffer, +// <i> when they are called from the interrupt handler. +// <i> Default: 16 entries +#ifndef OS_FIFOSZ + #define OS_FIFOSZ 16 +#endif + +// </h> + +//------------- <<< end of configuration section >>> ----------------------- + +// Standard library system mutexes +// =============================== +// Define max. number system mutexes that are used to protect +// the arm standard runtime library. For microlib they are not used. +#ifndef OS_MUTEXCNT + #define OS_MUTEXCNT 8 +#endif + +/*---------------------------------------------------------------------------- + * RTX User configuration part END + *---------------------------------------------------------------------------*/ + +#define OS_TRV ((uint32_t)(((double)OS_CLOCK*(double)OS_TICK)/1E6)-1) + + +/*---------------------------------------------------------------------------- + * Global Functions + *---------------------------------------------------------------------------*/ + +/*--------------------------- os_idle_demon ---------------------------------*/ + +void os_idle_demon (void) { + /* The idle demon is a system thread, running when no other thread is */ + /* ready to run. */ + + for (;;) { + /* HERE: include optional user code to be executed when no thread runs.*/ +#if 0 + __DSB(); + __WFI(); +#endif + } +} + +#if (OS_SYSTICK == 0) // Functions for alternative timer as RTX kernel timer + +/*--------------------------- os_tick_init ----------------------------------*/ +#ifdef TARGET_RZ_A1H +#define OSTM0 (0xFCFEC000uL) /* OSTM0 */ +#define OSTM1 (0xFCFEC400uL) /* OSTM1 */ +#define CPG (0xFCFE0410uL) /* CPG */ + +#define CPGSTBCR5 (*((volatile unsigned char*)(CPG + 0x00000018uL))) + +#define OSTM0CMP (*((volatile unsigned long*)(OSTM0 + 0x00000000uL))) +#define OSTM0CNT (*((volatile unsigned long*)(OSTM0 + 0x00000004uL))) +#define OSTM0TE (*((volatile unsigned char*)(OSTM0 + 0x00000010uL))) +#define OSTM0TS (*((volatile unsigned char*)(OSTM0 + 0x00000014uL))) +#define OSTM0TT (*((volatile unsigned char*)(OSTM0 + 0x00000018uL))) +#define OSTM0CTL (*((volatile unsigned char*)(OSTM0 + 0x00000020uL))) + +#define OSTM1CMP (*((volatile unsigned long*)(OSTM1 + 0x00000000uL))) +#define OSTM1CNT (*((volatile unsigned long*)(OSTM1 + 0x00000004uL))) +#define OSTM1TE (*((volatile unsigned char*)(OSTM1 + 0x00000010uL))) +#define OSTM1TS (*((volatile unsigned char*)(OSTM1 + 0x00000014uL))) +#define OSTM1TT (*((volatile unsigned char*)(OSTM1 + 0x00000018uL))) +#define OSTM1CTL (*((volatile unsigned char*)(OSTM1 + 0x00000020uL))) + +#define CPG_STBCR5_BIT_MSTP51 (0x02u) /* OSTM0 */ +#define CM1_RENESAS_RZ_A1_P0_CLK ( 32000000u) +#define CM0_RENESAS_RZ_A1_P0_CLK ( 33333333u) + +typedef enum +{ + IRQ_SGI0 = 0, + IRQ_OSTMI0TINT = 134 +} IRQn_Type; + +typedef void(*IRQHandler)(); + +extern void PendSV_Handler(uint32_t); +extern void OS_Tick_Handler(uint32_t); +extern uint32_t InterruptHandlerRegister (IRQn_Type irq, IRQHandler handler); +#endif + +// Initialize alternative hardware timer as RTX kernel timer +// Return: IRQ number of the alternative hardware timer +int os_tick_init (void) { +#ifdef TARGET_RZ_A1H + CPGSTBCR5 &= ~(CPG_STBCR5_BIT_MSTP51); /* enable OSTM0 clock */ + + OSTM0TT = 0x1; /* Stop the counter and clears the OSTM0TE bit. */ + OSTM0CTL = 0x1; /* Interval timer mode. Interrupt enabled */ + + OSTM0CMP = (uint32_t)(((double)CM0_RENESAS_RZ_A1_P0_CLK*(double)OS_TICK)/1E6); + + OSTM0TS = 0x1; /* Start the counter and sets the OSTM0TE bit. */ + + InterruptHandlerRegister(IRQ_SGI0 , (IRQHandler)PendSV_Handler); + InterruptHandlerRegister(IRQ_OSTMI0TINT, (IRQHandler)OS_Tick_Handler); + + + return IRQ_OSTMI0TINT; /* Return IRQ number of timer (0..239) */ + /* RTX will set and configure the interrupt */ +#endif +} + +/*--------------------------- os_tick_irqack --------------------------------*/ + +// Acknowledge alternative hardware timer interrupt +void os_tick_irqack (void) { + /* ... */ +} + +#endif // (OS_SYSTICK == 0) + +/*--------------------------- os_error --------------------------------------*/ +extern void mbed_die(void); + +void os_error (uint32_t err_code) { + /* This function is called when a runtime error is detected. Parameter */ + /* 'err_code' holds the runtime error code (defined in RTL.H). */ + mbed_die(); + + /* HERE: include optional code to be executed on runtime error. */ + for (;;); +} + + +/*---------------------------------------------------------------------------- + * RTX Configuration Functions + *---------------------------------------------------------------------------*/ + +#include "RTX_CM_lib.h" + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/RTX_Config.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,76 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RTX_CONFIG.H + * Purpose: Exported functions of RTX_Config.c + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + + +/* Error Codes */ +#define OS_ERR_STK_OVF 1 +#define OS_ERR_FIFO_OVF 2 +#define OS_ERR_MBX_OVF 3 + +/* Definitions */ +#define BOX_ALIGN_8 0x80000000 +#define _declare_box(pool,size,cnt) U32 pool[(((size)+3)/4)*(cnt) + 3] +#define _declare_box8(pool,size,cnt) U64 pool[(((size)+7)/8)*(cnt) + 2] +#define _init_box8(pool,size,bsize) _init_box (pool,size,(bsize) | BOX_ALIGN_8) + +/* Variables */ +extern U32 mp_tcb[]; +extern U64 mp_stk[]; +extern U32 os_fifo[]; +extern void *os_active_TCB[]; + +/* Constants */ +extern U16 const os_maxtaskrun; +extern U32 const os_trv; +extern U8 const os_flags; +extern U32 const os_stackinfo; +extern U32 const os_rrobin; +extern U32 const os_clockrate; +extern U32 const os_timernum; +extern U16 const mp_tcb_size; +extern U32 const mp_stk_size; +extern U32 const *m_tmr; +extern U16 const mp_tmr_size; +extern U8 const os_fifo_size; + +/* Functions */ +extern void os_idle_demon (void); +extern int os_tick_init (void); +extern void os_tick_irqack (void); +extern void os_tmr_call (U16 info); +extern void os_error (U32 err_code); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/cmsis_os.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,803 @@ +/* ---------------------------------------------------------------------- + * $Date: 5. June 2012 + * $Revision: V1.01 + * + * Project: CMSIS-RTOS API + * Title: cmsis_os.h RTX header file + * + * Version 0.02 + * Initial Proposal Phase + * Version 0.03 + * osKernelStart added, optional feature: main started as thread + * osSemaphores have standard behavior + * osTimerCreate does not start the timer, added osTimerStart + * osThreadPass is renamed to osThreadYield + * Version 1.01 + * Support for C++ interface + * - const attribute removed from the osXxxxDef_t typedef's + * - const attribute added to the osXxxxDef macros + * Added: osTimerDelete, osMutexDelete, osSemaphoreDelete + * Added: osKernelInitialize + *---------------------------------------------------------------------------- + * + * Copyright (c) 2012 ARM LIMITED + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +/** +\page cmsis_os_h Header File Template: cmsis_os.h + +The file \b cmsis_os.h is a template header file for a CMSIS-RTOS compliant Real-Time Operating System (RTOS). +Each RTOS that is compliant with CMSIS-RTOS shall provide a specific \b cmsis_os.h header file that represents +its implementation. + +The file cmsis_os.h contains: + - CMSIS-RTOS API function definitions + - struct definitions for parameters and return types + - status and priority values used by CMSIS-RTOS API functions + - macros for defining threads and other kernel objects + + +<b>Name conventions and header file modifications</b> + +All definitions are prefixed with \b os to give an unique name space for CMSIS-RTOS functions. +Definitions that are prefixed \b os_ are not used in the application code but local to this header file. +All definitions and functions that belong to a module are grouped and have a common prefix, i.e. \b osThread. + +Definitions that are marked with <b>CAN BE CHANGED</b> can be adapted towards the needs of the actual CMSIS-RTOS implementation. +These definitions can be specific to the underlying RTOS kernel. + +Definitions that are marked with <b>MUST REMAIN UNCHANGED</b> cannot be altered. Otherwise the CMSIS-RTOS implementation is no longer +compliant to the standard. Note that some functions are optional and need not to be provided by every CMSIS-RTOS implementation. + + +<b>Function calls from interrupt service routines</b> + +The following CMSIS-RTOS functions can be called from threads and interrupt service routines (ISR): + - \ref osSignalSet + - \ref osSemaphoreRelease + - \ref osPoolAlloc, \ref osPoolCAlloc, \ref osPoolFree + - \ref osMessagePut, \ref osMessageGet + - \ref osMailAlloc, \ref osMailCAlloc, \ref osMailGet, \ref osMailPut, \ref osMailFree + +Functions that cannot be called from an ISR are verifying the interrupt status and return in case that they are called +from an ISR context the status code \b osErrorISR. In some implementations this condition might be caught using the HARD FAULT vector. + +Some CMSIS-RTOS implementations support CMSIS-RTOS function calls from multiple ISR at the same time. +If this is impossible, the CMSIS-RTOS rejects calls by nested ISR functions with the status code \b osErrorISRRecursive. + + +<b>Define and reference object definitions</b> + +With <b>\#define osObjectsExternal</b> objects are defined as external symbols. This allows to create a consistent header file +that is used throughout a project as shown below: + +<i>Header File</i> +\code +#include <cmsis_os.h> // CMSIS RTOS header file + +// Thread definition +extern void thread_sample (void const *argument); // function prototype +osThreadDef (thread_sample, osPriorityBelowNormal, 1, 100); + +// Pool definition +osPoolDef(MyPool, 10, long); +\endcode + + +This header file defines all objects when included in a C/C++ source file. When <b>\#define osObjectsExternal</b> is +present before the header file, the objects are defined as external symbols. A single consistent header file can therefore be +used throughout the whole project. + +<i>Example</i> +\code +#include "osObjects.h" // Definition of the CMSIS-RTOS objects +\endcode + +\code +#define osObjectExternal // Objects will be defined as external symbols +#include "osObjects.h" // Reference to the CMSIS-RTOS objects +\endcode + +*/ + +#ifndef _CMSIS_OS_H +#define _CMSIS_OS_H + +/// \note MUST REMAIN UNCHANGED: \b osCMSIS identifies the CMSIS-RTOS API version. +#define osCMSIS 0x10001 ///< API version (main [31:16] .sub [15:0]) + +/// \note CAN BE CHANGED: \b osCMSIS_KERNEL identifies the underlying RTOS kernel and version number. +#define osCMSIS_RTX ((4<<16)|61) ///< RTOS identification and version (main [31:16] .sub [15:0]) + +/// \note MUST REMAIN UNCHANGED: \b osKernelSystemId shall be consistent in every CMSIS-RTOS. +#define osKernelSystemId "RTX V4.61" ///< RTOS identification string + +#define CMSIS_OS_RTX +#define CMSIS_OS_RTX_CA /* new define for Coretex-A */ + +// The stack space occupied is mainly dependent on the underling C standard library +#if defined(TOOLCHAIN_GCC) || defined(TOOLCHAIN_ARM_STD) +# define WORDS_STACK_SIZE 512 +#elif defined(TOOLCHAIN_ARM_MICRO) +# define WORDS_STACK_SIZE 128 +#endif + +#define DEFAULT_STACK_SIZE (WORDS_STACK_SIZE*4) + +/// \note MUST REMAIN UNCHANGED: \b osFeature_xxx shall be consistent in every CMSIS-RTOS. +#define osFeature_MainThread 1 ///< main thread 1=main can be thread, 0=not available +#define osFeature_Pool 1 ///< Memory Pools: 1=available, 0=not available +#define osFeature_MailQ 1 ///< Mail Queues: 1=available, 0=not available +#define osFeature_MessageQ 1 ///< Message Queues: 1=available, 0=not available +#define osFeature_Signals 16 ///< maximum number of Signal Flags available per thread +#define osFeature_Semaphore 65535 ///< maximum count for \ref osSemaphoreCreate function +#define osFeature_Wait 0 ///< osWait function: 1=available, 0=not available + +#if defined (__CC_ARM) +#define os_InRegs __value_in_regs // Compiler specific: force struct in registers +#else +#define os_InRegs +#endif + +#include <stdint.h> +#include <stddef.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + +// ==== Enumeration, structures, defines ==== + +/// Priority used for thread control. +/// \note MUST REMAIN UNCHANGED: \b osPriority shall be consistent in every CMSIS-RTOS. +typedef enum { + osPriorityIdle = -3, ///< priority: idle (lowest) + osPriorityLow = -2, ///< priority: low + osPriorityBelowNormal = -1, ///< priority: below normal + osPriorityNormal = 0, ///< priority: normal (default) + osPriorityAboveNormal = +1, ///< priority: above normal + osPriorityHigh = +2, ///< priority: high + osPriorityRealtime = +3, ///< priority: realtime (highest) + osPriorityError = 0x84 ///< system cannot determine priority or thread has illegal priority +} osPriority; + +/// Timeout value. +/// \note MUST REMAIN UNCHANGED: \b osWaitForever shall be consistent in every CMSIS-RTOS. +#define osWaitForever 0xFFFFFFFF ///< wait forever timeout value + +/// Status code values returned by CMSIS-RTOS functions. +/// \note MUST REMAIN UNCHANGED: \b osStatus shall be consistent in every CMSIS-RTOS. +typedef enum { + osOK = 0, ///< function completed; no error or event occurred. + osEventSignal = 0x08, ///< function completed; signal event occurred. + osEventMessage = 0x10, ///< function completed; message event occurred. + osEventMail = 0x20, ///< function completed; mail event occurred. + osEventTimeout = 0x40, ///< function completed; timeout occurred. + osErrorParameter = 0x80, ///< parameter error: a mandatory parameter was missing or specified an incorrect object. + osErrorResource = 0x81, ///< resource not available: a specified resource was not available. + osErrorTimeoutResource = 0xC1, ///< resource not available within given time: a specified resource was not available within the timeout period. + osErrorISR = 0x82, ///< not allowed in ISR context: the function cannot be called from interrupt service routines. + osErrorISRRecursive = 0x83, ///< function called multiple times from ISR with same object. + osErrorPriority = 0x84, ///< system cannot determine priority or thread has illegal priority. + osErrorNoMemory = 0x85, ///< system is out of memory: it was impossible to allocate or reserve memory for the operation. + osErrorValue = 0x86, ///< value of a parameter is out of range. + osErrorOS = 0xFF, ///< unspecified RTOS error: run-time error but no other error message fits. + os_status_reserved = 0x7FFFFFFF ///< prevent from enum down-size compiler optimization. +} osStatus; + + +/// Timer type value for the timer definition. +/// \note MUST REMAIN UNCHANGED: \b os_timer_type shall be consistent in every CMSIS-RTOS. +typedef enum { + osTimerOnce = 0, ///< one-shot timer + osTimerPeriodic = 1 ///< repeating timer +} os_timer_type; + +/// Entry point of a thread. +/// \note MUST REMAIN UNCHANGED: \b os_pthread shall be consistent in every CMSIS-RTOS. +typedef void (*os_pthread) (void const *argument); + +/// Entry point of a timer call back function. +/// \note MUST REMAIN UNCHANGED: \b os_ptimer shall be consistent in every CMSIS-RTOS. +typedef void (*os_ptimer) (void const *argument); + +// >>> the following data type definitions may shall adapted towards a specific RTOS + +/// Thread ID identifies the thread (pointer to a thread control block). +/// \note CAN BE CHANGED: \b os_thread_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_thread_cb *osThreadId; + +/// Timer ID identifies the timer (pointer to a timer control block). +/// \note CAN BE CHANGED: \b os_timer_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_timer_cb *osTimerId; + +/// Mutex ID identifies the mutex (pointer to a mutex control block). +/// \note CAN BE CHANGED: \b os_mutex_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_mutex_cb *osMutexId; + +/// Semaphore ID identifies the semaphore (pointer to a semaphore control block). +/// \note CAN BE CHANGED: \b os_semaphore_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_semaphore_cb *osSemaphoreId; + +/// Pool ID identifies the memory pool (pointer to a memory pool control block). +/// \note CAN BE CHANGED: \b os_pool_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_pool_cb *osPoolId; + +/// Message ID identifies the message queue (pointer to a message queue control block). +/// \note CAN BE CHANGED: \b os_messageQ_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_messageQ_cb *osMessageQId; + +/// Mail ID identifies the mail queue (pointer to a mail queue control block). +/// \note CAN BE CHANGED: \b os_mailQ_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_mailQ_cb *osMailQId; + + +/// Thread Definition structure contains startup information of a thread. +/// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS. +typedef struct os_thread_def { + os_pthread pthread; ///< start address of thread function + osPriority tpriority; ///< initial thread priority + uint32_t instances; ///< maximum number of instances of that thread function + uint32_t stacksize; ///< stack size requirements in bytes; 0 is default stack size +} osThreadDef_t; + +/// Timer Definition structure contains timer parameters. +/// \note CAN BE CHANGED: \b os_timer_def is implementation specific in every CMSIS-RTOS. +typedef struct os_timer_def { + os_ptimer ptimer; ///< start address of a timer function + void *timer; ///< pointer to internal data +} osTimerDef_t; + +/// Mutex Definition structure contains setup information for a mutex. +/// \note CAN BE CHANGED: \b os_mutex_def is implementation specific in every CMSIS-RTOS. +typedef struct os_mutex_def { + void *mutex; ///< pointer to internal data +} osMutexDef_t; + +/// Semaphore Definition structure contains setup information for a semaphore. +/// \note CAN BE CHANGED: \b os_semaphore_def is implementation specific in every CMSIS-RTOS. +typedef struct os_semaphore_def { + void *semaphore; ///< pointer to internal data +} osSemaphoreDef_t; + +/// Definition structure for memory block allocation. +/// \note CAN BE CHANGED: \b os_pool_def is implementation specific in every CMSIS-RTOS. +typedef struct os_pool_def { + uint32_t pool_sz; ///< number of items (elements) in the pool + uint32_t item_sz; ///< size of an item + void *pool; ///< pointer to memory for pool +} osPoolDef_t; + +/// Definition structure for message queue. +/// \note CAN BE CHANGED: \b os_messageQ_def is implementation specific in every CMSIS-RTOS. +typedef struct os_messageQ_def { + uint32_t queue_sz; ///< number of elements in the queue + void *pool; ///< memory array for messages +} osMessageQDef_t; + +/// Definition structure for mail queue. +/// \note CAN BE CHANGED: \b os_mailQ_def is implementation specific in every CMSIS-RTOS. +typedef struct os_mailQ_def { + uint32_t queue_sz; ///< number of elements in the queue + uint32_t item_sz; ///< size of an item + void *pool; ///< memory array for mail +} osMailQDef_t; + +/// Event structure contains detailed information about an event. +/// \note MUST REMAIN UNCHANGED: \b os_event shall be consistent in every CMSIS-RTOS. +/// However the struct may be extended at the end. +typedef struct { + osStatus status; ///< status code: event or error information + union { + uint32_t v; ///< message as 32-bit value + void *p; ///< message or mail as void pointer + int32_t signals; ///< signal flags + } value; ///< event value + union { + osMailQId mail_id; ///< mail id obtained by \ref osMailCreate + osMessageQId message_id; ///< message id obtained by \ref osMessageCreate + } def; ///< event definition +} osEvent; + + +// ==== Kernel Control Functions ==== + +/// Initialize the RTOS Kernel for creating objects. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osKernelInitialize shall be consistent in every CMSIS-RTOS. +osStatus osKernelInitialize (void); + +/// Start the RTOS Kernel. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osKernelStart shall be consistent in every CMSIS-RTOS. +osStatus osKernelStart (void); + +/// Check if the RTOS kernel is already started. +/// \note MUST REMAIN UNCHANGED: \b osKernelRunning shall be consistent in every CMSIS-RTOS. +/// \return 0 RTOS is not started, 1 RTOS is started. +int32_t osKernelRunning(void); + + +// ==== Thread Management ==== + +/// Create a Thread Definition with function, priority, and stack requirements. +/// \param name name of the thread function. +/// \param priority initial priority of the thread function. +/// \param instances number of possible thread instances. +/// \param stacksz stack size (in bytes) requirements for the thread function. +/// \note CAN BE CHANGED: The parameters to \b osThreadDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osThreadDef(name, priority, instances, stacksz) \ +extern const osThreadDef_t os_thread_def_##name +#else // define the object +#if defined (__MBED_CMSIS_RTOS_CA9) +#define osThreadDef(name, priority, stacksz) \ +const osThreadDef_t os_thread_def_##name = \ +{ (name), (priority), 1, (stacksz) } +#else +#define osThreadDef(name, priority, instances, stacksz) \ +const osThreadDef_t os_thread_def_##name = \ +{ (name), (priority), (instances), (stacksz) } +#endif +#endif + +/// Access a Thread definition. +/// \param name name of the thread definition object. +/// \note CAN BE CHANGED: The parameter to \b osThread shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osThread(name) \ +&os_thread_def_##name + +/// Create a thread and add it to Active Threads and set it to state READY. +/// \param[in] thread_def thread definition referenced with \ref osThread. +/// \param[in] argument pointer that is passed to the thread function as start argument. +/// \return thread ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osThreadCreate shall be consistent in every CMSIS-RTOS. +osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument); + +/// Return the thread ID of the current running thread. +/// \return thread ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osThreadGetId shall be consistent in every CMSIS-RTOS. +osThreadId osThreadGetId (void); + +/// Terminate execution of a thread and remove it from Active Threads. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osThreadTerminate shall be consistent in every CMSIS-RTOS. +osStatus osThreadTerminate (osThreadId thread_id); + +/// Pass control to next thread that is in state \b READY. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osThreadYield shall be consistent in every CMSIS-RTOS. +osStatus osThreadYield (void); + +/// Change priority of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] priority new priority value for the thread function. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osThreadSetPriority shall be consistent in every CMSIS-RTOS. +osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority); + +/// Get current priority of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return current priority value of the thread function. +/// \note MUST REMAIN UNCHANGED: \b osThreadGetPriority shall be consistent in every CMSIS-RTOS. +osPriority osThreadGetPriority (osThreadId thread_id); + +#ifdef __MBED_CMSIS_RTOS_CA9 +/// Get current thread state. +uint8_t osThreadGetState (osThreadId thread_id); +#endif + +// ==== Generic Wait Functions ==== + +/// Wait for Timeout (Time Delay). +/// \param[in] millisec time delay value +/// \return status code that indicates the execution status of the function. +osStatus osDelay (uint32_t millisec); + +#if (defined (osFeature_Wait) && (osFeature_Wait != 0)) // Generic Wait available + +/// Wait for Signal, Message, Mail, or Timeout. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return event that contains signal, message, or mail information or error code. +/// \note MUST REMAIN UNCHANGED: \b osWait shall be consistent in every CMSIS-RTOS. +os_InRegs osEvent osWait (uint32_t millisec); + +#endif // Generic Wait available + + +// ==== Timer Management Functions ==== +/// Define a Timer object. +/// \param name name of the timer object. +/// \param function name of the timer call back function. +/// \note CAN BE CHANGED: The parameter to \b osTimerDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osTimerDef(name, function) \ +extern const osTimerDef_t os_timer_def_##name +#else // define the object +#define osTimerDef(name, function) \ +uint32_t os_timer_cb_##name[5]; \ +const osTimerDef_t os_timer_def_##name = \ +{ (function), (os_timer_cb_##name) } +#endif + +/// Access a Timer definition. +/// \param name name of the timer object. +/// \note CAN BE CHANGED: The parameter to \b osTimer shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osTimer(name) \ +&os_timer_def_##name + +/// Create a timer. +/// \param[in] timer_def timer object referenced with \ref osTimer. +/// \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior. +/// \param[in] argument argument to the timer call back function. +/// \return timer ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osTimerCreate shall be consistent in every CMSIS-RTOS. +osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument); + +/// Start or restart a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \param[in] millisec time delay value of the timer. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osTimerStart shall be consistent in every CMSIS-RTOS. +osStatus osTimerStart (osTimerId timer_id, uint32_t millisec); + +/// Stop the timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osTimerStop shall be consistent in every CMSIS-RTOS. +osStatus osTimerStop (osTimerId timer_id); + +/// Delete a timer that was created by \ref osTimerCreate. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osTimerDelete shall be consistent in every CMSIS-RTOS. +osStatus osTimerDelete (osTimerId timer_id); + + +// ==== Signal Management ==== + +/// Set the specified Signal Flags of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] signals specifies the signal flags of the thread that should be set. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSignalSet shall be consistent in every CMSIS-RTOS. +int32_t osSignalSet (osThreadId thread_id, int32_t signals); + +/// Clear the specified Signal Flags of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] signals specifies the signal flags of the thread that shall be cleared. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSignalClear shall be consistent in every CMSIS-RTOS. +int32_t osSignalClear (osThreadId thread_id, int32_t signals); + +/// Get Signal Flags status of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSignalGet shall be consistent in every CMSIS-RTOS. +int32_t osSignalGet (osThreadId thread_id); + +/// Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread. +/// \param[in] signals wait until all specified signal flags set or 0 for any single signal flag. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return event flag information or error code. +/// \note MUST REMAIN UNCHANGED: \b osSignalWait shall be consistent in every CMSIS-RTOS. +os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec); + + +// ==== Mutex Management ==== + +/// Define a Mutex. +/// \param name name of the mutex object. +/// \note CAN BE CHANGED: The parameter to \b osMutexDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMutexDef(name) \ +extern const osMutexDef_t os_mutex_def_##name +#else // define the object +#define osMutexDef(name) \ +uint32_t os_mutex_cb_##name[3]; \ +const osMutexDef_t os_mutex_def_##name = { (os_mutex_cb_##name) } +#endif + +/// Access a Mutex definition. +/// \param name name of the mutex object. +/// \note CAN BE CHANGED: The parameter to \b osMutex shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMutex(name) \ +&os_mutex_def_##name + +/// Create and Initialize a Mutex object. +/// \param[in] mutex_def mutex definition referenced with \ref osMutex. +/// \return mutex ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMutexCreate shall be consistent in every CMSIS-RTOS. +osMutexId osMutexCreate (const osMutexDef_t *mutex_def); + +/// Wait until a Mutex becomes available. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMutexWait shall be consistent in every CMSIS-RTOS. +osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec); + +/// Release a Mutex that was obtained by \ref osMutexWait. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMutexRelease shall be consistent in every CMSIS-RTOS. +osStatus osMutexRelease (osMutexId mutex_id); + +/// Delete a Mutex that was created by \ref osMutexCreate. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMutexDelete shall be consistent in every CMSIS-RTOS. +osStatus osMutexDelete (osMutexId mutex_id); + + +// ==== Semaphore Management Functions ==== + +#if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0)) // Semaphore available + +/// Define a Semaphore object. +/// \param name name of the semaphore object. +/// \note CAN BE CHANGED: The parameter to \b osSemaphoreDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osSemaphoreDef(name) \ +extern const osSemaphoreDef_t os_semaphore_def_##name +#else // define the object +#define osSemaphoreDef(name) \ +uint32_t os_semaphore_cb_##name[2]; \ +const osSemaphoreDef_t os_semaphore_def_##name = { (os_semaphore_cb_##name) } +#endif + +/// Access a Semaphore definition. +/// \param name name of the semaphore object. +/// \note CAN BE CHANGED: The parameter to \b osSemaphore shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osSemaphore(name) \ +&os_semaphore_def_##name + +/// Create and Initialize a Semaphore object used for managing resources. +/// \param[in] semaphore_def semaphore definition referenced with \ref osSemaphore. +/// \param[in] count number of available resources. +/// \return semaphore ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreCreate shall be consistent in every CMSIS-RTOS. +osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count); + +/// Wait until a Semaphore token becomes available. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return number of available tokens, or -1 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS. +int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec); + +/// Release a Semaphore token. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreRelease shall be consistent in every CMSIS-RTOS. +osStatus osSemaphoreRelease (osSemaphoreId semaphore_id); + +/// Delete a Semaphore that was created by \ref osSemaphoreCreate. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreDelete shall be consistent in every CMSIS-RTOS. +osStatus osSemaphoreDelete (osSemaphoreId semaphore_id); + +#endif // Semaphore available + + +// ==== Memory Pool Management Functions ==== + +#if (defined (osFeature_Pool) && (osFeature_Pool != 0)) // Memory Pool Management available + +/// \brief Define a Memory Pool. +/// \param name name of the memory pool. +/// \param no maximum number of blocks (objects) in the memory pool. +/// \param type data type of a single block (object). +/// \note CAN BE CHANGED: The parameter to \b osPoolDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osPoolDef(name, no, type) \ +extern const osPoolDef_t os_pool_def_##name +#else // define the object +#define osPoolDef(name, no, type) \ +uint32_t os_pool_m_##name[3+((sizeof(type)+3)/4)*(no)]; \ +const osPoolDef_t os_pool_def_##name = \ +{ (no), sizeof(type), (os_pool_m_##name) } +#endif + +/// \brief Access a Memory Pool definition. +/// \param name name of the memory pool +/// \note CAN BE CHANGED: The parameter to \b osPool shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osPool(name) \ +&os_pool_def_##name + +/// Create and Initialize a memory pool. +/// \param[in] pool_def memory pool definition referenced with \ref osPool. +/// \return memory pool ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osPoolCreate shall be consistent in every CMSIS-RTOS. +osPoolId osPoolCreate (const osPoolDef_t *pool_def); + +/// Allocate a memory block from a memory pool. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \return address of the allocated memory block or NULL in case of no memory available. +/// \note MUST REMAIN UNCHANGED: \b osPoolAlloc shall be consistent in every CMSIS-RTOS. +void *osPoolAlloc (osPoolId pool_id); + +/// Allocate a memory block from a memory pool and set memory block to zero. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \return address of the allocated memory block or NULL in case of no memory available. +/// \note MUST REMAIN UNCHANGED: \b osPoolCAlloc shall be consistent in every CMSIS-RTOS. +void *osPoolCAlloc (osPoolId pool_id); + +/// Return an allocated memory block back to a specific memory pool. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \param[in] block address of the allocated memory block that is returned to the memory pool. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osPoolFree shall be consistent in every CMSIS-RTOS. +osStatus osPoolFree (osPoolId pool_id, void *block); + +#endif // Memory Pool Management available + + +// ==== Message Queue Management Functions ==== + +#if (defined (osFeature_MessageQ) && (osFeature_MessageQ != 0)) // Message Queues available + +/// \brief Create a Message Queue Definition. +/// \param name name of the queue. +/// \param queue_sz maximum number of messages in the queue. +/// \param type data type of a single message element (for debugger). +/// \note CAN BE CHANGED: The parameter to \b osMessageQDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMessageQDef(name, queue_sz, type) \ +extern const osMessageQDef_t os_messageQ_def_##name +#else // define the object +#define osMessageQDef(name, queue_sz, type) \ +uint32_t os_messageQ_q_##name[4+(queue_sz)]; \ +const osMessageQDef_t os_messageQ_def_##name = \ +{ (queue_sz), (os_messageQ_q_##name) } +#endif + +/// \brief Access a Message Queue Definition. +/// \param name name of the queue +/// \note CAN BE CHANGED: The parameter to \b osMessageQ shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMessageQ(name) \ +&os_messageQ_def_##name + +/// Create and Initialize a Message Queue. +/// \param[in] queue_def queue definition referenced with \ref osMessageQ. +/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. +/// \return message queue ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMessageCreate shall be consistent in every CMSIS-RTOS. +osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id); + +/// Put a Message to a Queue. +/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. +/// \param[in] info message information. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMessagePut shall be consistent in every CMSIS-RTOS. +osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec); + +/// Get a Message or Wait for a Message from a Queue. +/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return event information that includes status code. +/// \note MUST REMAIN UNCHANGED: \b osMessageGet shall be consistent in every CMSIS-RTOS. +os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec); + +#endif // Message Queues available + + +// ==== Mail Queue Management Functions ==== + +#if (defined (osFeature_MailQ) && (osFeature_MailQ != 0)) // Mail Queues available + +/// \brief Create a Mail Queue Definition. +/// \param name name of the queue +/// \param queue_sz maximum number of messages in queue +/// \param type data type of a single message element +/// \note CAN BE CHANGED: The parameter to \b osMailQDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMailQDef(name, queue_sz, type) \ +extern const osMailQDef_t os_mailQ_def_##name +#else // define the object +#define osMailQDef(name, queue_sz, type) \ +uint32_t os_mailQ_q_##name[4+(queue_sz)]; \ +uint32_t os_mailQ_m_##name[3+((sizeof(type)+3)/4)*(queue_sz)]; \ +void * os_mailQ_p_##name[2] = { (os_mailQ_q_##name), os_mailQ_m_##name }; \ +const osMailQDef_t os_mailQ_def_##name = \ +{ (queue_sz), sizeof(type), (os_mailQ_p_##name) } +#endif + +/// \brief Access a Mail Queue Definition. +/// \param name name of the queue +/// \note CAN BE CHANGED: The parameter to \b osMailQ shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMailQ(name) \ +&os_mailQ_def_##name + +/// Create and Initialize mail queue. +/// \param[in] queue_def reference to the mail queue definition obtain with \ref osMailQ +/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. +/// \return mail queue ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMailCreate shall be consistent in every CMSIS-RTOS. +osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id); + +/// Allocate a memory block from a mail. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return pointer to memory block that can be filled with mail or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMailAlloc shall be consistent in every CMSIS-RTOS. +void *osMailAlloc (osMailQId queue_id, uint32_t millisec); + +/// Allocate a memory block from a mail and set memory block to zero. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return pointer to memory block that can be filled with mail or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMailCAlloc shall be consistent in every CMSIS-RTOS. +void *osMailCAlloc (osMailQId queue_id, uint32_t millisec); + +/// Put a mail to a queue. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] mail memory block previously allocated with \ref osMailAlloc or \ref osMailCAlloc. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMailPut shall be consistent in every CMSIS-RTOS. +osStatus osMailPut (osMailQId queue_id, void *mail); + +/// Get a mail from a queue. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return event that contains mail information or error code. +/// \note MUST REMAIN UNCHANGED: \b osMailGet shall be consistent in every CMSIS-RTOS. +os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec); + +/// Free a memory block from a mail. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] mail pointer to the memory block that was obtained with \ref osMailGet. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMailFree shall be consistent in every CMSIS-RTOS. +osStatus osMailFree (osMailQId queue_id, void *mail); + +#endif // Mail Queues available + + +#ifdef __cplusplus +} +#endif + +#endif // _CMSIS_OS_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/rt_CMSIS.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,1978 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: rt_CMSIS.c + * Purpose: CMSIS RTOS API + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#define __CMSIS_GENERIC + +#if defined (__CORTEX_M4) || defined (__CORTEX_M4F) + #include "core_cm4.h" +#elif defined (__CORTEX_M3) + #include "core_cm3.h" +#elif defined (__CORTEX_M0) + #include "core_cm0.h" +#elif defined (__CORTEX_A9) + #include "core_ca9.h" +#else + #error "Missing __CORTEX_xx definition" +#endif + +#include "rt_TypeDef.h" +#include "RTX_Config.h" +#include "rt_System.h" +#include "rt_Task.h" +#include "rt_Event.h" +#include "rt_List.h" +#include "rt_Time.h" +#include "rt_Mutex.h" +#include "rt_Semaphore.h" +#include "rt_Mailbox.h" +#include "rt_MemBox.h" +#include "rt_Memory.h" +#include "rt_HAL_CM.h" + +#define os_thread_cb OS_TCB + +#include "cmsis_os.h" + +#if (osFeature_Signals != 16) +#error Invalid "osFeature_Signals" value! +#endif +#if (osFeature_Semaphore > 65535) +#error Invalid "osFeature_Semaphore" value! +#endif +#if (osFeature_Wait != 0) +#error osWait not supported! +#endif + + +// ==== Enumeration, structures, defines ==== + +// Service Calls defines + +#if defined (__CC_ARM) /* ARM Compiler */ + +#define __NO_RETURN __declspec(noreturn) + +#define osEvent_type osEvent +#define osEvent_ret_status ret +#define osEvent_ret_value ret +#define osEvent_ret_msg ret +#define osEvent_ret_mail ret + +#define osCallback_type osCallback +#define osCallback_ret ret + +#define SVC_0_1(f,t,...) \ +__svc_indirect(0) t _##f (t(*)()); \ + t f (void); \ +__attribute__((always_inline)) \ +static __inline t __##f (void) { \ + return _##f(f); \ +} + +#define SVC_1_1(f,t,t1,...) \ +__svc_indirect(0) t _##f (t(*)(t1),t1); \ + t f (t1 a1); \ +__attribute__((always_inline)) \ +static __inline t __##f (t1 a1) { \ + return _##f(f,a1); \ +} + +#define SVC_2_1(f,t,t1,t2,...) \ +__svc_indirect(0) t _##f (t(*)(t1,t2),t1,t2); \ + t f (t1 a1, t2 a2); \ +__attribute__((always_inline)) \ +static __inline t __##f (t1 a1, t2 a2) { \ + return _##f(f,a1,a2); \ +} + +#define SVC_3_1(f,t,t1,t2,t3,...) \ +__svc_indirect(0) t _##f (t(*)(t1,t2,t3),t1,t2,t3); \ + t f (t1 a1, t2 a2, t3 a3); \ +__attribute__((always_inline)) \ +static __inline t __##f (t1 a1, t2 a2, t3 a3) { \ + return _##f(f,a1,a2,a3); \ +} + +#define SVC_4_1(f,t,t1,t2,t3,t4,...) \ +__svc_indirect(0) t _##f (t(*)(t1,t2,t3,t4),t1,t2,t3,t4); \ + t f (t1 a1, t2 a2, t3 a3, t4 a4); \ +__attribute__((always_inline)) \ +static __inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ + return _##f(f,a1,a2,a3,a4); \ +} + +#define SVC_1_2 SVC_1_1 +#define SVC_1_3 SVC_1_1 +#define SVC_2_3 SVC_2_1 + +#elif defined (__GNUC__) /* GNU Compiler */ + +#define __NO_RETURN __attribute__((noreturn)) + +typedef uint32_t __attribute__((vector_size(8))) ret64; +typedef uint32_t __attribute__((vector_size(16))) ret128; + +#define RET_pointer __r0 +#define RET_int32_t __r0 +#define RET_osStatus __r0 +#define RET_osPriority __r0 +#define RET_osEvent {(osStatus)__r0, {(uint32_t)__r1}, {(void *)__r2}} +#define RET_osCallback {(void *)__r0, (void *)__r1} + +#define osEvent_type ret128 +#define osEvent_ret_status (ret128){ret.status} +#define osEvent_ret_value (ret128){ret.status, ret.value.v} +#define osEvent_ret_msg (ret128){ret.status, ret.value.v, (uint32_t)ret.def.message_id} +#define osEvent_ret_mail (ret128){ret.status, ret.value.v, (uint32_t)ret.def.mail_id} + +#define osCallback_type ret64 +#define osCallback_ret (ret64) {(uint32_t)ret.fp, (uint32_t)ret.arg} + +#define SVC_ArgN(n) \ + register int __r##n __asm("r"#n); + +#define SVC_ArgR(n,t,a) \ + register t __r##n __asm("r"#n) = a; + +#define SVC_Arg0() \ + SVC_ArgN(0) \ + SVC_ArgN(1) \ + SVC_ArgN(2) \ + SVC_ArgN(3) + +#define SVC_Arg1(t1) \ + SVC_ArgR(0,t1,a1) \ + SVC_ArgN(1) \ + SVC_ArgN(2) \ + SVC_ArgN(3) + +#define SVC_Arg2(t1,t2) \ + SVC_ArgR(0,t1,a1) \ + SVC_ArgR(1,t2,a2) \ + SVC_ArgN(2) \ + SVC_ArgN(3) + +#define SVC_Arg3(t1,t2,t3) \ + SVC_ArgR(0,t1,a1) \ + SVC_ArgR(1,t2,a2) \ + SVC_ArgR(2,t3,a3) \ + SVC_ArgN(3) + +#define SVC_Arg4(t1,t2,t3,t4) \ + SVC_ArgR(0,t1,a1) \ + SVC_ArgR(1,t2,a2) \ + SVC_ArgR(2,t3,a3) \ + SVC_ArgR(3,t4,a4) + +#if (defined (__CORTEX_M0)) +#define SVC_Call(f) \ + __asm volatile \ + ( \ + "ldr r7,="#f"\n\t" \ + "mov r12,r7\n\t" \ + "svc 0" \ + : "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3) \ + : "r" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) \ + : "r7", "r12", "lr", "cc" \ + ); +#else +#define SVC_Call(f) \ + __asm volatile \ + ( \ + "ldr r12,="#f"\n\t" \ + "svc 0" \ + : "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3) \ + : "r" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) \ + : "r12", "lr", "cc" \ + ); +#endif + +#define SVC_0_1(f,t,rv) \ +__attribute__((always_inline)) \ +static inline t __##f (void) { \ + SVC_Arg0(); \ + SVC_Call(f); \ + return (t) rv; \ +} + +#define SVC_1_1(f,t,t1,rv) \ +__attribute__((always_inline)) \ +static inline t __##f (t1 a1) { \ + SVC_Arg1(t1); \ + SVC_Call(f); \ + return (t) rv; \ +} + +#define SVC_2_1(f,t,t1,t2,rv) \ +__attribute__((always_inline)) \ +static inline t __##f (t1 a1, t2 a2) { \ + SVC_Arg2(t1,t2); \ + SVC_Call(f); \ + return (t) rv; \ +} + +#define SVC_3_1(f,t,t1,t2,t3,rv) \ +__attribute__((always_inline)) \ +static inline t __##f (t1 a1, t2 a2, t3 a3) { \ + SVC_Arg3(t1,t2,t3); \ + SVC_Call(f); \ + return (t) rv; \ +} + +#define SVC_4_1(f,t,t1,t2,t3,t4,rv) \ +__attribute__((always_inline)) \ +static inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ + SVC_Arg4(t1,t2,t3,t4); \ + SVC_Call(f); \ + return (t) rv; \ +} + +#define SVC_1_2 SVC_1_1 +#define SVC_1_3 SVC_1_1 +#define SVC_2_3 SVC_2_1 + +#elif defined (__ICCARM__) /* IAR Compiler */ + +#define __NO_RETURN __noreturn + +#define RET_osEvent "=r"(ret.status), "=r"(ret.value), "=r"(ret.def) +#define RET_osCallback "=r"(ret.fp), "=r"(ret.arg) + +#define osEvent_type osEvent +#define osEvent_ret_status ret +#define osEvent_ret_value ret +#define osEvent_ret_msg ret +#define osEvent_ret_mail ret + +#define osCallback_type uint64_t +#define osCallback_ret ((uint64_t)ret.fp | ((uint64_t)ret.arg)<<32) + +#define SVC_Setup(f) \ + __asm( \ + "mov r12,%0\n" \ + :: "r"(&f): "r12" \ + ); + +#define SVC_Ret3() \ + __asm( \ + "ldr r0,[sp,#0]\n" \ + "ldr r1,[sp,#4]\n" \ + "ldr r2,[sp,#8]\n" \ + ); + +#define SVC_0_1(f,t,...) \ +t f (void); \ +_Pragma("swi_number=0") __swi t _##f (void); \ +static inline t __##f (void) { \ + SVC_Setup(f); \ + return _##f(); \ +} + +#define SVC_1_1(f,t,t1,...) \ +t f (t1 a1); \ +_Pragma("swi_number=0") __swi t _##f (t1 a1); \ +static inline t __##f (t1 a1) { \ + SVC_Setup(f); \ + return _##f(a1); \ +} + +#define SVC_2_1(f,t,t1,t2,...) \ +t f (t1 a1, t2 a2); \ +_Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2); \ +static inline t __##f (t1 a1, t2 a2) { \ + SVC_Setup(f); \ + return _##f(a1,a2); \ +} + +#define SVC_3_1(f,t,t1,t2,t3,...) \ +t f (t1 a1, t2 a2, t3 a3); \ +_Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2, t3 a3); \ +static inline t __##f (t1 a1, t2 a2, t3 a3) { \ + SVC_Setup(f); \ + return _##f(a1,a2,a3); \ +} + +#define SVC_4_1(f,t,t1,t2,t3,t4,...) \ +t f (t1 a1, t2 a2, t3 a3, t4 a4); \ +_Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2, t3 a3, t4 a4); \ +static inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ + SVC_Setup(f); \ + return _##f(a1,a2,a3,a4); \ +} + +#define SVC_1_2(f,t,t1,rr) \ +uint64_t f (t1 a1); \ +_Pragma("swi_number=0") __swi uint64_t _##f (t1 a1); \ +static inline t __##f (t1 a1) { \ + t ret; \ + SVC_Setup(f); \ + _##f(a1); \ + __asm("" : rr : :); \ + return ret; \ +} + +#define SVC_1_3(f,t,t1,rr) \ +t f (t1 a1); \ +void f##_ (t1 a1) { \ + f(a1); \ + SVC_Ret3(); \ +} \ +_Pragma("swi_number=0") __swi void _##f (t1 a1); \ +static inline t __##f (t1 a1) { \ + t ret; \ + SVC_Setup(f##_); \ + _##f(a1); \ + __asm("" : rr : :); \ + return ret; \ +} + +#define SVC_2_3(f,t,t1,t2,rr) \ +t f (t1 a1, t2 a2); \ +void f##_ (t1 a1, t2 a2) { \ + f(a1,a2); \ + SVC_Ret3(); \ +} \ +_Pragma("swi_number=0") __swi void _##f (t1 a1, t2 a2); \ +static inline t __##f (t1 a1, t2 a2) { \ + t ret; \ + SVC_Setup(f##_); \ + _##f(a1,a2); \ + __asm("" : rr : :); \ + return ret; \ +} + +#endif + + +// Callback structure +typedef struct { + void *fp; // Function pointer + void *arg; // Function argument +} osCallback; + + +// OS Section definitions +#ifdef OS_SECTIONS_LINK_INFO +extern const uint32_t os_section_id$$Base; +extern const uint32_t os_section_id$$Limit; +#endif + +// OS Stack Memory for Threads definitions +extern uint64_t os_stack_mem[]; +extern const uint32_t os_stack_sz; + +// OS Timers external resources +extern const osThreadDef_t os_thread_def_osTimerThread; +extern osThreadId osThreadId_osTimerThread; +extern const osMessageQDef_t os_messageQ_def_osTimerMessageQ; +extern osMessageQId osMessageQId_osTimerMessageQ; + +extern U32 IRQNestLevel; /* Indicates whether inside an ISR, and the depth of nesting. 0 = not in ISR. */ + + +// ==== Helper Functions ==== + +/// Convert timeout in millisec to system ticks +static uint32_t rt_ms2tick (uint32_t millisec) { + uint32_t tick; + + if (millisec == osWaitForever) return 0xFFFF; // Indefinite timeout + if (millisec > 4000000) return 0xFFFE; // Max ticks supported + + tick = ((1000 * millisec) + os_clockrate - 1) / os_clockrate; + if (tick > 0xFFFE) return 0xFFFE; + + return tick; +} + +/// Convert Thread ID to TCB pointer +static P_TCB rt_tid2ptcb (osThreadId thread_id) { + P_TCB ptcb; + + if (thread_id == NULL) return NULL; + + if ((uint32_t)thread_id & 3) return NULL; + +#ifdef OS_SECTIONS_LINK_INFO + if ((os_section_id$$Base != 0) && (os_section_id$$Limit != 0)) { + if (thread_id < (osThreadId)os_section_id$$Base) return NULL; + if (thread_id >= (osThreadId)os_section_id$$Limit) return NULL; + } +#endif + + ptcb = thread_id; + + if (ptcb->cb_type != TCB) return NULL; + + return ptcb; +} + +/// Convert ID pointer to Object pointer +static void *rt_id2obj (void *id) { + + if ((uint32_t)id & 3) return NULL; + +#ifdef OS_SECTIONS_LINK_INFO + if ((os_section_id$$Base != 0) && (os_section_id$$Limit != 0)) { + if (id < (void *)os_section_id$$Base) return NULL; + if (id >= (void *)os_section_id$$Limit) return NULL; + } +#endif + + return id; +} + +// === Helper functions for system call interface === + +static __inline char __get_mode(void) { + return (char)(__get_CPSR() & 0x1f); +} + +static __inline char __exceptional_mode(void) { + switch(__get_mode()) { + case MODE_USR: + case MODE_SYS: + return 0; + case MODE_SVC: + if (IRQNestLevel == 0) + return 0; /* handling a regular service call */ + else + return 1; /* handling an ISR in SVC mode */ + default: + return 1; + } +} + +// ==== Kernel Control ==== + +uint8_t os_initialized; // Kernel Initialized flag +uint8_t os_running; // Kernel Running flag + +// Kernel Control Service Calls declarations +SVC_0_1(svcKernelInitialize, osStatus, RET_osStatus) +SVC_0_1(svcKernelStart, osStatus, RET_osStatus) +SVC_0_1(svcKernelRunning, int32_t, RET_int32_t) + +static void sysThreadError (osStatus status); +osThreadId svcThreadCreate (const osThreadDef_t *thread_def, void *argument); +osMessageQId svcMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id); + +// Kernel Control Service Calls + +/// Initialize the RTOS Kernel for creating objects +osStatus svcKernelInitialize (void) { + int ret; + + if (!os_initialized) { + + // Init Thread Stack Memory (must be 8-byte aligned) + if ((uint32_t)os_stack_mem & 7) return osErrorNoMemory; + ret = rt_init_mem(os_stack_mem, os_stack_sz); + if (ret != 0) return osErrorNoMemory; + + rt_sys_init(); // RTX System Initialization + } + + os_tsk.run->prio = 255; // Highest priority + + if (!os_initialized) { + // Create OS Timers resources (Message Queue & Thread) + osMessageQId_osTimerMessageQ = svcMessageCreate (&os_messageQ_def_osTimerMessageQ, NULL); + osThreadId_osTimerThread = svcThreadCreate(&os_thread_def_osTimerThread, NULL); + } + + sysThreadError(osOK); + + os_initialized = 1; + + return osOK; +} + +/// Start the RTOS Kernel +osStatus svcKernelStart (void) { + + if (os_running) return osOK; + + rt_tsk_prio(0, 0); // Lowest priority + __set_PSP(os_tsk.run->tsk_stack + 8*4); // New context + os_tsk.run = NULL; // Force context switch + + rt_sys_start(); + + os_running = 1; + + return osOK; +} + +/// Check if the RTOS kernel is already started +int32_t svcKernelRunning(void) { + return os_running; +} + +// Kernel Control Public API + +/// Initialize the RTOS Kernel for creating objects +osStatus osKernelInitialize (void) { + if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR + if (__get_mode() != MODE_USR) { + return svcKernelInitialize(); + } else { + return __svcKernelInitialize(); + } +} + +/// Start the RTOS Kernel +osStatus osKernelStart (void) { + char mode = __get_mode(); + + switch(mode) { + case MODE_USR: + if (os_flags & 1) return osErrorOS; // Privileged Thread mode requested from Unprivileged + break; + case MODE_SYS: + if (!(os_flags & 1)) { + __set_CPS_USR(); + } + break; + default: + return osErrorISR; // Not allowed in ISR + } + return __svcKernelStart(); +} + +/// Check if the RTOS kernel is already started +int32_t osKernelRunning(void) { + if(__get_mode() != MODE_USR) { + return os_running; + } else { + return __svcKernelRunning(); + } +} + + +// ==== Thread Management ==== + +/// Set Thread Error (for Create functions which return IDs) +static void sysThreadError (osStatus status) { + // To Do +} + +__NO_RETURN void osThreadExit (void); + +// Thread Service Calls declarations +SVC_2_1(svcThreadCreate, osThreadId, const osThreadDef_t *, void *, RET_pointer) +SVC_0_1(svcThreadGetId, osThreadId, RET_pointer) +SVC_1_1(svcThreadTerminate, osStatus, osThreadId, RET_osStatus) +SVC_0_1(svcThreadYield, osStatus, RET_osStatus) +SVC_2_1(svcThreadSetPriority, osStatus, osThreadId, osPriority, RET_osStatus) +SVC_1_1(svcThreadGetPriority, osPriority, osThreadId, RET_osPriority) + +// Thread Service Calls + +/// Create a thread and add it to Active Threads and set it to state READY +osThreadId svcThreadCreate (const osThreadDef_t *thread_def, void *argument) { + P_TCB ptcb; + OS_TID tsk; + void *stk; + + if ((thread_def == NULL) || + (thread_def->pthread == NULL) || + (thread_def->tpriority < osPriorityIdle) || + (thread_def->tpriority > osPriorityRealtime)) { + sysThreadError(osErrorParameter); + return NULL; + } + + if (thread_def->stacksize != 0) { // Custom stack size + stk = rt_alloc_mem( // Allocate stack + os_stack_mem, + thread_def->stacksize + ); + if (stk == NULL) { + sysThreadError(osErrorNoMemory); // Out of memory + return NULL; + } + } else { // Default stack size + stk = NULL; + } + + tsk = rt_tsk_create( // Create task + (FUNCP)thread_def->pthread, // Task function pointer + (thread_def->tpriority-osPriorityIdle+1) | // Task priority + (thread_def->stacksize << 8), // Task stack size in bytes + stk, // Pointer to task's stack + argument // Argument to the task + ); + + if (tsk == 0) { // Invalid task ID + if (stk != NULL) { + rt_free_mem(os_stack_mem, stk); // Free allocated stack + } + sysThreadError(osErrorNoMemory); // Create task failed (Out of memory) + return NULL; + } + + ptcb = (P_TCB)os_active_TCB[tsk - 1]; // TCB pointer + + *((uint32_t *)ptcb->tsk_stack + 13) = (uint32_t)osThreadExit; + + return ptcb; +} + +/// Return the thread ID of the current running thread +osThreadId svcThreadGetId (void) { + OS_TID tsk; + + tsk = rt_tsk_self(); + if (tsk == 0) return NULL; + return (P_TCB)os_active_TCB[tsk - 1]; +} + +/// Terminate execution of a thread and remove it from ActiveThreads +osStatus svcThreadTerminate (osThreadId thread_id) { + OS_RESULT res; + P_TCB ptcb; + void *stk; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return osErrorParameter; + + stk = ptcb->priv_stack ? ptcb->stack : NULL; // Private stack + + res = rt_tsk_delete(ptcb->task_id); // Delete task + + if (res == OS_R_NOK) return osErrorResource; // Delete task failed + + if (stk != NULL) { + rt_free_mem(os_stack_mem, stk); // Free private stack + } + + return osOK; +} + +/// Pass control to next thread that is in state READY +osStatus svcThreadYield (void) { + rt_tsk_pass(); // Pass control to next task + return osOK; +} + +/// Change priority of an active thread +osStatus svcThreadSetPriority (osThreadId thread_id, osPriority priority) { + OS_RESULT res; + P_TCB ptcb; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return osErrorParameter; + + if ((priority < osPriorityIdle) || (priority > osPriorityRealtime)) { + return osErrorValue; + } + + res = rt_tsk_prio( // Change task priority + ptcb->task_id, // Task ID + priority - osPriorityIdle + 1 // New task priority + ); + + if (res == OS_R_NOK) return osErrorResource; // Change task priority failed + + return osOK; +} + +/// Get current priority of an active thread +osPriority svcThreadGetPriority (osThreadId thread_id) { + P_TCB ptcb; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return osPriorityError; + + return (osPriority)(ptcb->prio - 1 + osPriorityIdle); +} + + +// Thread Public API + +/// Create a thread and add it to Active Threads and set it to state READY +osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument) { + if (__exceptional_mode()) return NULL; // Not allowed in ISR + if ((__get_mode() != MODE_USR) && (os_running == 0)) { + // Privileged and not running + return svcThreadCreate(thread_def, argument); + } else { + return __svcThreadCreate(thread_def, argument); + } +} + +/// Return the thread ID of the current running thread +osThreadId osThreadGetId (void) { + if (__exceptional_mode()) return NULL; // Not allowed in ISR + return __svcThreadGetId(); +} + +/// Terminate execution of a thread and remove it from ActiveThreads +osStatus osThreadTerminate (osThreadId thread_id) { + if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR + return __svcThreadTerminate(thread_id); +} + +/// Pass control to next thread that is in state READY +osStatus osThreadYield (void) { + if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR + return __svcThreadYield(); +} + +/// Change priority of an active thread +osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority) { + if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR + return __svcThreadSetPriority(thread_id, priority); +} + +/// Get current priority of an active thread +osPriority osThreadGetPriority (osThreadId thread_id) { + if (__exceptional_mode()) return osPriorityError;// Not allowed in ISR + return __svcThreadGetPriority(thread_id); +} + +/// INTERNAL - Not Public +/// Auto Terminate Thread on exit (used implicitly when thread exists) +__NO_RETURN void osThreadExit (void) { + __svcThreadTerminate(__svcThreadGetId()); + for (;;); // Should never come here +} + +#ifdef __MBED_CMSIS_RTOS_CA9 +/// Get current thread state +uint8_t osThreadGetState (osThreadId thread_id) { + P_TCB ptcb; + + if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return osErrorParameter; + + return ptcb->state; +} +#endif + +// ==== Generic Wait Functions ==== + +// Generic Wait Service Calls declarations +SVC_1_1(svcDelay, osStatus, uint32_t, RET_osStatus) +#if osFeature_Wait != 0 +SVC_1_3(svcWait, os_InRegs osEvent, uint32_t, RET_osEvent) +#endif + +// Generic Wait Service Calls + +/// Wait for Timeout (Time Delay) +osStatus svcDelay (uint32_t millisec) { + if (millisec == 0) return osOK; + rt_dly_wait(rt_ms2tick(millisec)); + return osEventTimeout; +} + +/// Wait for Signal, Message, Mail, or Timeout +#if osFeature_Wait != 0 +os_InRegs osEvent_type svcWait (uint32_t millisec) { + osEvent ret; + + if (millisec == 0) { + ret.status = osOK; + return osEvent_ret_status; + } + + /* To Do: osEventSignal, osEventMessage, osEventMail */ + rt_dly_wait(rt_ms2tick(millisec)); + ret.status = osEventTimeout; + + return osEvent_ret_status; +} +#endif + + +// Generic Wait API + +/// Wait for Timeout (Time Delay) +osStatus osDelay (uint32_t millisec) { + if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR + return __svcDelay(millisec); +} + +/// Wait for Signal, Message, Mail, or Timeout +os_InRegs osEvent osWait (uint32_t millisec) { + osEvent ret; + +#if osFeature_Wait == 0 + ret.status = osErrorOS; + return ret; +#else + if (__exceptional_mode()) { // Not allowed in ISR + ret.status = osErrorISR; + return ret; + } + return __svcWait(millisec); +#endif +} + + +// ==== Timer Management ==== + +// Timer definitions +#define osTimerInvalid 0 +#define osTimerStopped 1 +#define osTimerRunning 2 + +// Timer structures + +typedef struct os_timer_cb_ { // Timer Control Block + struct os_timer_cb_ *next; // Pointer to next active Timer + uint8_t state; // Timer State + uint8_t type; // Timer Type (Periodic/One-shot) + uint16_t reserved; // Reserved + uint16_t tcnt; // Timer Delay Count + uint16_t icnt; // Timer Initial Count + void *arg; // Timer Function Argument + const osTimerDef_t *timer; // Pointer to Timer definition +} os_timer_cb; + +// Timer variables +os_timer_cb *os_timer_head; // Pointer to first active Timer + + +// Timer Helper Functions + +// Insert Timer into the list sorted by time +static void rt_timer_insert (os_timer_cb *pt, uint32_t tcnt) { + os_timer_cb *p, *prev; + + prev = NULL; + p = os_timer_head; + while (p != NULL) { + if (tcnt < p->tcnt) break; + tcnt -= p->tcnt; + prev = p; + p = p->next; + } + pt->next = p; + pt->tcnt = (uint16_t)tcnt; + if (p != NULL) { + p->tcnt -= pt->tcnt; + } + if (prev != NULL) { + prev->next = pt; + } else { + os_timer_head = pt; + } +} + +// Remove Timer from the list +static int rt_timer_remove (os_timer_cb *pt) { + os_timer_cb *p, *prev; + + prev = NULL; + p = os_timer_head; + while (p != NULL) { + if (p == pt) break; + prev = p; + p = p->next; + } + if (p == NULL) return -1; + if (prev != NULL) { + prev->next = pt->next; + } else { + os_timer_head = pt->next; + } + if (pt->next != NULL) { + pt->next->tcnt += pt->tcnt; + } + + return 0; +} + + +// Timer Service Calls declarations +SVC_3_1(svcTimerCreate, osTimerId, const osTimerDef_t *, os_timer_type, void *, RET_pointer) +SVC_2_1(svcTimerStart, osStatus, osTimerId, uint32_t, RET_osStatus) +SVC_1_1(svcTimerStop, osStatus, osTimerId, RET_osStatus) +SVC_1_1(svcTimerDelete, osStatus, osTimerId, RET_osStatus) +SVC_1_2(svcTimerCall, os_InRegs osCallback, osTimerId, RET_osCallback) + +// Timer Management Service Calls + +/// Create timer +osTimerId svcTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument) { + os_timer_cb *pt; + + if ((timer_def == NULL) || (timer_def->ptimer == NULL)) { + sysThreadError(osErrorParameter); + return NULL; + } + + pt = timer_def->timer; + if (pt == NULL) { + sysThreadError(osErrorParameter); + return NULL; + } + + if ((type != osTimerOnce) && (type != osTimerPeriodic)) { + sysThreadError(osErrorValue); + return NULL; + } + + if (osThreadId_osTimerThread == NULL) { + sysThreadError(osErrorResource); + return NULL; + } + + if (pt->state != osTimerInvalid){ + sysThreadError(osErrorResource); + return NULL; + } + + pt->state = osTimerStopped; + pt->type = (uint8_t)type; + pt->arg = argument; + pt->timer = timer_def; + + return (osTimerId)pt; +} + +/// Start or restart timer +osStatus svcTimerStart (osTimerId timer_id, uint32_t millisec) { + os_timer_cb *pt; + uint32_t tcnt; + + pt = rt_id2obj(timer_id); + if (pt == NULL) return osErrorParameter; + + tcnt = rt_ms2tick(millisec); + if (tcnt == 0) return osErrorValue; + + switch (pt->state) { + case osTimerRunning: + if (rt_timer_remove(pt) != 0) { + return osErrorResource; + } + break; + case osTimerStopped: + pt->state = osTimerRunning; + pt->icnt = (uint16_t)tcnt; + break; + default: + return osErrorResource; + } + + rt_timer_insert(pt, tcnt); + + return osOK; +} + +/// Stop timer +osStatus svcTimerStop (osTimerId timer_id) { + os_timer_cb *pt; + + pt = rt_id2obj(timer_id); + if (pt == NULL) return osErrorParameter; + + if (pt->state != osTimerRunning) return osErrorResource; + + pt->state = osTimerStopped; + + if (rt_timer_remove(pt) != 0) { + return osErrorResource; + } + + return osOK; +} + +/// Delete timer +osStatus svcTimerDelete (osTimerId timer_id) { + os_timer_cb *pt; + + pt = rt_id2obj(timer_id); + if (pt == NULL) return osErrorParameter; + + switch (pt->state) { + case osTimerRunning: + rt_timer_remove(pt); + break; + case osTimerStopped: + break; + default: + return osErrorResource; + } + + pt->state = osTimerInvalid; + + return osOK; +} + +/// Get timer callback parameters +os_InRegs osCallback_type svcTimerCall (osTimerId timer_id) { + os_timer_cb *pt; + osCallback ret; + + pt = rt_id2obj(timer_id); + if (pt == NULL) { + ret.fp = NULL; + ret.arg = NULL; + return osCallback_ret; + } + + ret.fp = (void *)pt->timer->ptimer; + ret.arg = pt->arg; + + return osCallback_ret; +} + +static __INLINE osStatus isrMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec); + +/// Timer Tick (called each SysTick) +void sysTimerTick (void) { + os_timer_cb *pt, *p; + + p = os_timer_head; + if (p == NULL) return; + + p->tcnt--; + while ((p != NULL) && (p->tcnt == 0)) { + pt = p; + p = p->next; + os_timer_head = p; + isrMessagePut(osMessageQId_osTimerMessageQ, (uint32_t)pt, 0); + if (pt->type == osTimerPeriodic) { + rt_timer_insert(pt, pt->icnt); + } else { + pt->state = osTimerStopped; + } + } +} + + +// Timer Management Public API + +/// Create timer +osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument) { + if (__exceptional_mode()) return NULL; // Not allowed in ISR + if ((__get_mode() != MODE_USR) && (os_running == 0)) { + // Privileged and not running + return svcTimerCreate(timer_def, type, argument); + } else { + return __svcTimerCreate(timer_def, type, argument); + } +} + +/// Start or restart timer +osStatus osTimerStart (osTimerId timer_id, uint32_t millisec) { + if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR + return __svcTimerStart(timer_id, millisec); +} + +/// Stop timer +osStatus osTimerStop (osTimerId timer_id) { + if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR + return __svcTimerStop(timer_id); +} + +/// Delete timer +osStatus osTimerDelete (osTimerId timer_id) { + if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR + return __svcTimerDelete(timer_id); +} + +/// INTERNAL - Not Public +/// Get timer callback parameters (used by OS Timer Thread) +os_InRegs osCallback osTimerCall (osTimerId timer_id) { + return __svcTimerCall(timer_id); +} + + +// Timer Thread +__NO_RETURN void osTimerThread (void const *argument) { + osCallback cb; + osEvent evt; + + for (;;) { + evt = osMessageGet(osMessageQId_osTimerMessageQ, osWaitForever); + if (evt.status == osEventMessage) { + cb = osTimerCall(evt.value.p); + if (cb.fp != NULL) { + (*(os_ptimer)cb.fp)(cb.arg); + } + } + } +} + + +// ==== Signal Management ==== + +// Signal Service Calls declarations +SVC_2_1(svcSignalSet, int32_t, osThreadId, int32_t, RET_int32_t) +SVC_2_1(svcSignalClear, int32_t, osThreadId, int32_t, RET_int32_t) +SVC_1_1(svcSignalGet, int32_t, osThreadId, RET_int32_t) +SVC_2_3(svcSignalWait, os_InRegs osEvent, int32_t, uint32_t, RET_osEvent) + +// Signal Service Calls + +/// Set the specified Signal Flags of an active thread +int32_t svcSignalSet (osThreadId thread_id, int32_t signals) { + P_TCB ptcb; + int32_t sig; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return 0x80000000; + + if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000; + + sig = ptcb->events; // Previous signal flags + + rt_evt_set(signals, ptcb->task_id); // Set event flags + + return sig; +} + +/// Clear the specified Signal Flags of an active thread +int32_t svcSignalClear (osThreadId thread_id, int32_t signals) { + P_TCB ptcb; + int32_t sig; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return 0x80000000; + + if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000; + + sig = ptcb->events; // Previous signal flags + + rt_evt_clr(signals, ptcb->task_id); // Clear event flags + + return sig; +} + +/// Get Signal Flags status of an active thread +int32_t svcSignalGet (osThreadId thread_id) { + P_TCB ptcb; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return 0x80000000; + + return ptcb->events; // Return event flags +} + +/// Wait for one or more Signal Flags to become signaled for the current RUNNING thread +os_InRegs osEvent_type svcSignalWait (int32_t signals, uint32_t millisec) { + OS_RESULT res; + osEvent ret; + + if (signals & (0xFFFFFFFF << osFeature_Signals)) { + ret.status = osErrorValue; + return osEvent_ret_status; + } + + if (signals != 0) { // Wait for all specified signals + res = rt_evt_wait(signals, rt_ms2tick(millisec), __TRUE); + } else { // Wait for any signal + res = rt_evt_wait(0xFFFF, rt_ms2tick(millisec), __FALSE); + } + + if (res == OS_R_EVT) { + ret.status = osEventSignal; + ret.value.signals = signals ? signals : os_tsk.run->waits; + } else { + ret.status = millisec ? osEventTimeout : osOK; + ret.value.signals = 0; + } + + return osEvent_ret_value; +} + + +// Signal ISR Calls + +/// Set the specified Signal Flags of an active thread +static __INLINE int32_t isrSignalSet (osThreadId thread_id, int32_t signals) { + P_TCB ptcb; + int32_t sig; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return 0x80000000; + + if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000; + + sig = ptcb->events; // Previous signal flags + + isr_evt_set(signals, ptcb->task_id); // Set event flags + + return sig; +} + + +// Signal Public API + +/// Set the specified Signal Flags of an active thread +int32_t osSignalSet (osThreadId thread_id, int32_t signals) { + if (__exceptional_mode()) { // in ISR + return isrSignalSet(thread_id, signals); + } else { // in Thread + return __svcSignalSet(thread_id, signals); + } +} + +/// Clear the specified Signal Flags of an active thread +int32_t osSignalClear (osThreadId thread_id, int32_t signals) { + if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR + return __svcSignalClear(thread_id, signals); +} + +/// Get Signal Flags status of an active thread +int32_t osSignalGet (osThreadId thread_id) { + if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR + return __svcSignalGet(thread_id); +} + +/// Wait for one or more Signal Flags to become signaled for the current RUNNING thread +os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec) { + osEvent ret; + + if (__exceptional_mode()) { // Not allowed in ISR + ret.status = osErrorISR; + return ret; + } + return __svcSignalWait(signals, millisec); +} + + +// ==== Mutex Management ==== + +// Mutex Service Calls declarations +SVC_1_1(svcMutexCreate, osMutexId, const osMutexDef_t *, RET_pointer) +SVC_2_1(svcMutexWait, osStatus, osMutexId, uint32_t, RET_osStatus) +SVC_1_1(svcMutexRelease, osStatus, osMutexId, RET_osStatus) +SVC_1_1(svcMutexDelete, osStatus, osMutexId, RET_osStatus) + +// Mutex Service Calls + +/// Create and Initialize a Mutex object +osMutexId svcMutexCreate (const osMutexDef_t *mutex_def) { + OS_ID mut; + + if (mutex_def == NULL) { + sysThreadError(osErrorParameter); + return NULL; + } + + mut = mutex_def->mutex; + if (mut == NULL) { + sysThreadError(osErrorParameter); + return NULL; + } + + if (((P_MUCB)mut)->cb_type != 0) { + sysThreadError(osErrorParameter); + return NULL; + } + + rt_mut_init(mut); // Initialize Mutex + + return mut; +} + +/// Wait until a Mutex becomes available +osStatus svcMutexWait (osMutexId mutex_id, uint32_t millisec) { + OS_ID mut; + OS_RESULT res; + + mut = rt_id2obj(mutex_id); + if (mut == NULL) return osErrorParameter; + + if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter; + + res = rt_mut_wait(mut, rt_ms2tick(millisec)); // Wait for Mutex + + if (res == OS_R_TMO) { + return (millisec ? osErrorTimeoutResource : osErrorResource); + } + + return osOK; +} + +/// Release a Mutex that was obtained with osMutexWait +osStatus svcMutexRelease (osMutexId mutex_id) { + OS_ID mut; + OS_RESULT res; + + mut = rt_id2obj(mutex_id); + if (mut == NULL) return osErrorParameter; + + if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter; + + res = rt_mut_release(mut); // Release Mutex + + if (res == OS_R_NOK) return osErrorResource; // Thread not owner or Zero Counter + + return osOK; +} + +/// Delete a Mutex that was created by osMutexCreate +osStatus svcMutexDelete (osMutexId mutex_id) { + OS_ID mut; + + mut = rt_id2obj(mutex_id); + if (mut == NULL) return osErrorParameter; + + if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter; + + rt_mut_delete(mut); // Release Mutex + + return osOK; +} + + +// Mutex Public API + +/// Create and Initialize a Mutex object +osMutexId osMutexCreate (const osMutexDef_t *mutex_def) { + if (__exceptional_mode()) return NULL; // Not allowed in ISR + if ((__get_mode() != MODE_USR) && (os_running == 0)) { + // Privileged and not running + return svcMutexCreate(mutex_def); + } else { + return __svcMutexCreate(mutex_def); + } +} + +/// Wait until a Mutex becomes available +osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec) { + if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR + return __svcMutexWait(mutex_id, millisec); +} + +/// Release a Mutex that was obtained with osMutexWait +osStatus osMutexRelease (osMutexId mutex_id) { + if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR + return __svcMutexRelease(mutex_id); +} + +/// Delete a Mutex that was created by osMutexCreate +osStatus osMutexDelete (osMutexId mutex_id) { + if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR + return __svcMutexDelete(mutex_id); +} + + +// ==== Semaphore Management ==== + +// Semaphore Service Calls declarations +SVC_2_1(svcSemaphoreCreate, osSemaphoreId, const osSemaphoreDef_t *, int32_t, RET_pointer) +SVC_2_1(svcSemaphoreWait, int32_t, osSemaphoreId, uint32_t, RET_int32_t) +SVC_1_1(svcSemaphoreRelease, osStatus, osSemaphoreId, RET_osStatus) +SVC_1_1(svcSemaphoreDelete, osStatus, osSemaphoreId, RET_osStatus) + +// Semaphore Service Calls + +/// Create and Initialize a Semaphore object +osSemaphoreId svcSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count) { + OS_ID sem; + + if (semaphore_def == NULL) { + sysThreadError(osErrorParameter); + return NULL; + } + + sem = semaphore_def->semaphore; + if (sem == NULL) { + sysThreadError(osErrorParameter); + return NULL; + } + + if (((P_SCB)sem)->cb_type != 0) { + sysThreadError(osErrorParameter); + return NULL; + } + + if (count > osFeature_Semaphore) { + sysThreadError(osErrorValue); + return NULL; + } + + rt_sem_init(sem, count); // Initialize Semaphore + + return sem; +} + +/// Wait until a Semaphore becomes available +int32_t svcSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) { + OS_ID sem; + OS_RESULT res; + + sem = rt_id2obj(semaphore_id); + if (sem == NULL) return -1; + + if (((P_SCB)sem)->cb_type != SCB) return -1; + + res = rt_sem_wait(sem, rt_ms2tick(millisec)); // Wait for Semaphore + + if (res == OS_R_TMO) return 0; // Timeout + + return (((P_SCB)sem)->tokens + 1); +} + +/// Release a Semaphore +osStatus svcSemaphoreRelease (osSemaphoreId semaphore_id) { + OS_ID sem; + + sem = rt_id2obj(semaphore_id); + if (sem == NULL) return osErrorParameter; + + if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter; + + if (((P_SCB)sem)->tokens == osFeature_Semaphore) return osErrorResource; + + rt_sem_send(sem); // Release Semaphore + + return osOK; +} + +/// Delete a Semaphore that was created by osSemaphoreCreate +osStatus svcSemaphoreDelete (osSemaphoreId semaphore_id) { + OS_ID sem; + + sem = rt_id2obj(semaphore_id); + if (sem == NULL) return osErrorParameter; + + if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter; + + rt_sem_delete(sem); // Delete Semaphore + + return osOK; +} + + +// Semaphore ISR Calls + +/// Release a Semaphore +static __INLINE osStatus isrSemaphoreRelease (osSemaphoreId semaphore_id) { + OS_ID sem; + + sem = rt_id2obj(semaphore_id); + if (sem == NULL) return osErrorParameter; + + if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter; + + if (((P_SCB)sem)->tokens == osFeature_Semaphore) return osErrorResource; + + isr_sem_send(sem); // Release Semaphore + + return osOK; +} + + +// Semaphore Public API + +/// Create and Initialize a Semaphore object +osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count) { + if (__exceptional_mode()) return NULL; // Not allowed in ISR + if ((__get_mode() != MODE_USR) && (os_running == 0)) { + // Privileged and not running + return svcSemaphoreCreate(semaphore_def, count); + } else { + return __svcSemaphoreCreate(semaphore_def, count); + } +} + +/// Wait until a Semaphore becomes available +int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) { + if (__exceptional_mode()) return -1; // Not allowed in ISR + return __svcSemaphoreWait(semaphore_id, millisec); +} + +/// Release a Semaphore +osStatus osSemaphoreRelease (osSemaphoreId semaphore_id) { + if (__exceptional_mode()) { // in ISR + return isrSemaphoreRelease(semaphore_id); + } else { // in Thread + return __svcSemaphoreRelease(semaphore_id); + } +} + +/// Delete a Semaphore that was created by osSemaphoreCreate +osStatus osSemaphoreDelete (osSemaphoreId semaphore_id) { + if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR + return __svcSemaphoreDelete(semaphore_id); +} + + +// ==== Memory Management Functions ==== + +// Memory Management Helper Functions + +// Clear Memory Box (Zero init) +static void rt_clr_box (void *box_mem, void *box) { + uint32_t *p, n; + + if (box) { + p = box; + for (n = ((P_BM)box_mem)->blk_size; n; n -= 4) { + *p++ = 0; + } + } +} + +// Memory Management Service Calls declarations +SVC_1_1(svcPoolCreate, osPoolId, const osPoolDef_t *, RET_pointer) +SVC_2_1(sysPoolAlloc, void *, osPoolId, uint32_t, RET_pointer) +SVC_2_1(sysPoolFree, osStatus, osPoolId, void *, RET_osStatus) + +// Memory Management Service & ISR Calls + +/// Create and Initialize memory pool +osPoolId svcPoolCreate (const osPoolDef_t *pool_def) { + uint32_t blk_sz; + + if ((pool_def == NULL) || + (pool_def->pool_sz == 0) || + (pool_def->item_sz == 0) || + (pool_def->pool == NULL)) { + sysThreadError(osErrorParameter); + return NULL; + } + + blk_sz = (pool_def->item_sz + 3) & ~3; + + _init_box(pool_def->pool, sizeof(struct OS_BM) + pool_def->pool_sz * blk_sz, blk_sz); + + return pool_def->pool; +} + +/// Allocate a memory block from a memory pool +void *sysPoolAlloc (osPoolId pool_id, uint32_t clr) { + void *ptr; + + if (pool_id == NULL) return NULL; + + ptr = rt_alloc_box(pool_id); + if (clr) { + rt_clr_box(pool_id, ptr); + } + + return ptr; +} + +/// Return an allocated memory block back to a specific memory pool +osStatus sysPoolFree (osPoolId pool_id, void *block) { + int32_t res; + + if (pool_id == NULL) return osErrorParameter; + + res = rt_free_box(pool_id, block); + if (res != 0) return osErrorValue; + + return osOK; +} + + +// Memory Management Public API + +/// Create and Initialize memory pool +osPoolId osPoolCreate (const osPoolDef_t *pool_def) { + if (__exceptional_mode()) return NULL; // Not allowed in ISR + if ((__get_mode() != MODE_USR) && (os_running == 0)) { + // Privileged and not running + return svcPoolCreate(pool_def); + } else { + return __svcPoolCreate(pool_def); + } +} + +/// Allocate a memory block from a memory pool +void *osPoolAlloc (osPoolId pool_id) { + if (__get_mode() != MODE_USR) { // in ISR or Privileged + return sysPoolAlloc(pool_id, 0); + } else { // in Thread + return __sysPoolAlloc(pool_id, 0); + } +} + +/// Allocate a memory block from a memory pool and set memory block to zero +void *osPoolCAlloc (osPoolId pool_id) { + if (__get_mode() != MODE_USR) { // in ISR or Privileged + return sysPoolAlloc(pool_id, 1); + } else { // in Thread + return __sysPoolAlloc(pool_id, 1); + } +} + +/// Return an allocated memory block back to a specific memory pool +osStatus osPoolFree (osPoolId pool_id, void *block) { + if (__get_mode() != MODE_USR) { // in ISR or Privileged + return sysPoolFree(pool_id, block); + } else { // in Thread + return __sysPoolFree(pool_id, block); + } +} + + +// ==== Message Queue Management Functions ==== + +// Message Queue Management Service Calls declarations +SVC_2_1(svcMessageCreate, osMessageQId, const osMessageQDef_t *, osThreadId, RET_pointer) +SVC_3_1(svcMessagePut, osStatus, osMessageQId, uint32_t, uint32_t, RET_osStatus) +SVC_2_3(svcMessageGet, os_InRegs osEvent, osMessageQId, uint32_t, RET_osEvent) + +// Message Queue Service Calls + +/// Create and Initialize Message Queue +osMessageQId svcMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id) { + + if ((queue_def == NULL) || + (queue_def->queue_sz == 0) || + (queue_def->pool == NULL)) { + sysThreadError(osErrorParameter); + return NULL; + } + + if (((P_MCB)queue_def->pool)->cb_type != 0) { + sysThreadError(osErrorParameter); + return NULL; + } + + rt_mbx_init(queue_def->pool, 4*(queue_def->queue_sz + 4)); + + return queue_def->pool; +} + +/// Put a Message to a Queue +osStatus svcMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { + OS_RESULT res; + + if (queue_id == NULL) return osErrorParameter; + + if (((P_MCB)queue_id)->cb_type != MCB) return osErrorParameter; + + res = rt_mbx_send(queue_id, (void *)info, rt_ms2tick(millisec)); + + if (res == OS_R_TMO) { + return (millisec ? osErrorTimeoutResource : osErrorResource); + } + + return osOK; +} + +/// Get a Message or Wait for a Message from a Queue +os_InRegs osEvent_type svcMessageGet (osMessageQId queue_id, uint32_t millisec) { + OS_RESULT res; + osEvent ret; + + if (queue_id == NULL) { + ret.status = osErrorParameter; + return osEvent_ret_status; + } + + if (((P_MCB)queue_id)->cb_type != MCB) { + ret.status = osErrorParameter; + return osEvent_ret_status; + } + + res = rt_mbx_wait(queue_id, &ret.value.p, rt_ms2tick(millisec)); + + if (res == OS_R_TMO) { + ret.status = millisec ? osEventTimeout : osOK; + return osEvent_ret_value; + } + + ret.status = osEventMessage; + + return osEvent_ret_value; +} + + +// Message Queue ISR Calls + +/// Put a Message to a Queue +static __INLINE osStatus isrMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { + + if ((queue_id == NULL) || (millisec != 0)) { + return osErrorParameter; + } + + if (((P_MCB)queue_id)->cb_type != MCB) return osErrorParameter; + + if (rt_mbx_check(queue_id) == 0) { // Check if Queue is full + return osErrorResource; + } + + isr_mbx_send(queue_id, (void *)info); + + return osOK; +} + +/// Get a Message or Wait for a Message from a Queue +static __INLINE os_InRegs osEvent isrMessageGet (osMessageQId queue_id, uint32_t millisec) { + OS_RESULT res; + osEvent ret; + + if ((queue_id == NULL) || (millisec != 0)) { + ret.status = osErrorParameter; + return ret; + } + + if (((P_MCB)queue_id)->cb_type != MCB) { + ret.status = osErrorParameter; + return ret; + } + + res = isr_mbx_receive(queue_id, &ret.value.p); + + if (res != OS_R_MBX) { + ret.status = osOK; + return ret; + } + + ret.status = osEventMessage; + + return ret; +} + + +// Message Queue Management Public API + +/// Create and Initialize Message Queue +osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id) { + if (__exceptional_mode()) return NULL; // Not allowed in ISR + if ((__get_mode() != MODE_USR) && (os_running == 0)) { + // Privileged and not running + return svcMessageCreate(queue_def, thread_id); + } else { + return __svcMessageCreate(queue_def, thread_id); + } +} + +/// Put a Message to a Queue +osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { + if (__exceptional_mode()) { // in ISR + return isrMessagePut(queue_id, info, millisec); + } else { // in Thread + return __svcMessagePut(queue_id, info, millisec); + } +} + +/// Get a Message or Wait for a Message from a Queue +os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec) { + if (__exceptional_mode()) { // in ISR + return isrMessageGet(queue_id, millisec); + } else { // in Thread + return __svcMessageGet(queue_id, millisec); + } +} + + +// ==== Mail Queue Management Functions ==== + +// Mail Queue Management Service Calls declarations +SVC_2_1(svcMailCreate, osMailQId, const osMailQDef_t *, osThreadId, RET_pointer) +SVC_4_1(sysMailAlloc, void *, osMailQId, uint32_t, uint32_t, uint32_t, RET_pointer) +SVC_3_1(sysMailFree, osStatus, osMailQId, void *, uint32_t, RET_osStatus) + +// Mail Queue Management Service & ISR Calls + +/// Create and Initialize mail queue +osMailQId svcMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id) { + uint32_t blk_sz; + P_MCB pmcb; + void *pool; + + if ((queue_def == NULL) || + (queue_def->queue_sz == 0) || + (queue_def->item_sz == 0) || + (queue_def->pool == NULL)) { + sysThreadError(osErrorParameter); + return NULL; + } + + pmcb = *(((void **)queue_def->pool) + 0); + pool = *(((void **)queue_def->pool) + 1); + + if ((pool == NULL) || (pmcb == NULL) || (pmcb->cb_type != 0)) { + sysThreadError(osErrorParameter); + return NULL; + } + + blk_sz = (queue_def->item_sz + 3) & ~3; + + _init_box(pool, sizeof(struct OS_BM) + queue_def->queue_sz * blk_sz, blk_sz); + + rt_mbx_init(pmcb, 4*(queue_def->queue_sz + 4)); + + + return queue_def->pool; +} + +/// Allocate a memory block from a mail +void *sysMailAlloc (osMailQId queue_id, uint32_t millisec, uint32_t isr, uint32_t clr) { + P_MCB pmcb; + void *pool; + void *mem; + + if (queue_id == NULL) return NULL; + + pmcb = *(((void **)queue_id) + 0); + pool = *(((void **)queue_id) + 1); + + if ((pool == NULL) || (pmcb == NULL)) return NULL; + + if (isr && (millisec != 0)) return NULL; + + mem = rt_alloc_box(pool); + if (clr) { + rt_clr_box(pool, mem); + } + + if ((mem == NULL) && (millisec != 0)) { + // Put Task to sleep when Memory not available + if (pmcb->p_lnk != NULL) { + rt_put_prio((P_XCB)pmcb, os_tsk.run); + } else { + pmcb->p_lnk = os_tsk.run; + os_tsk.run->p_lnk = NULL; + os_tsk.run->p_rlnk = (P_TCB)pmcb; + // Task is waiting to allocate a message + pmcb->state = 3; + } + rt_block(rt_ms2tick(millisec), WAIT_MBX); + } + + return mem; +} + +/// Free a memory block from a mail +osStatus sysMailFree (osMailQId queue_id, void *mail, uint32_t isr) { + P_MCB pmcb; + P_TCB ptcb; + void *pool; + void *mem; + int32_t res; + + if (queue_id == NULL) return osErrorParameter; + + pmcb = *(((void **)queue_id) + 0); + pool = *(((void **)queue_id) + 1); + + if ((pmcb == NULL) || (pool == NULL)) return osErrorParameter; + + res = rt_free_box(pool, mail); + + if (res != 0) return osErrorValue; + + if (pmcb->state == 3) { + // Task is waiting to allocate a message + if (isr) { + rt_psq_enq (pmcb, (U32)pool); + rt_psh_req (); + } else { + mem = rt_alloc_box(pool); + if (mem != NULL) { + ptcb = rt_get_first((P_XCB)pmcb); + if (pmcb->p_lnk == NULL) { + pmcb->state = 0; + } + rt_ret_val(ptcb, (U32)mem); + rt_rmv_dly(ptcb); + rt_dispatch(ptcb); + } + } + } + + return osOK; +} + + +// Mail Queue Management Public API + +/// Create and Initialize mail queue +osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id) { + if (__exceptional_mode()) return NULL; // Not allowed in ISR + if ((__get_mode() != MODE_USR) && (os_running == 0)) { + // Privileged and not running + return svcMailCreate(queue_def, thread_id); + } else { + return __svcMailCreate(queue_def, thread_id); + } +} + +/// Allocate a memory block from a mail +void *osMailAlloc (osMailQId queue_id, uint32_t millisec) { + if (__exceptional_mode()) { // in ISR + return sysMailAlloc(queue_id, millisec, 1, 0); + } else { // in Thread + return __sysMailAlloc(queue_id, millisec, 0, 0); + } +} + +/// Allocate a memory block from a mail and set memory block to zero +void *osMailCAlloc (osMailQId queue_id, uint32_t millisec) { + if (__exceptional_mode()) { // in ISR + return sysMailAlloc(queue_id, millisec, 1, 1); + } else { // in Thread + return __sysMailAlloc(queue_id, millisec, 0, 1); + } +} + +/// Free a memory block from a mail +osStatus osMailFree (osMailQId queue_id, void *mail) { + if (__exceptional_mode()) { // in ISR + return sysMailFree(queue_id, mail, 1); + } else { // in Thread + return __sysMailFree(queue_id, mail, 0); + } +} + +/// Put a mail to a queue +osStatus osMailPut (osMailQId queue_id, void *mail) { + if (queue_id == NULL) return osErrorParameter; + if (mail == NULL) return osErrorValue; + return osMessagePut(*((void **)queue_id), (uint32_t)mail, 0); +} + +/// Get a mail from a queue +os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec) { + osEvent ret; + + if (queue_id == NULL) { + ret.status = osErrorParameter; + return ret; + } + + ret = osMessageGet(*((void **)queue_id), millisec); + if (ret.status == osEventMessage) ret.status = osEventMail; + + return ret; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/rt_Event.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,194 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_EVENT.C + * Purpose: Implements waits and wake-ups for event flags + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "RTX_Config.h" +#include "rt_System.h" +#include "rt_Event.h" +#include "rt_List.h" +#include "rt_Task.h" +#ifdef __CORTEX_A9 +#include "rt_HAL_CA.h" +#else +#include "rt_HAL_CM.h" +#endif + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_evt_wait -----------------------------------*/ + +OS_RESULT rt_evt_wait (U16 wait_flags, U16 timeout, BOOL and_wait) { + /* Wait for one or more event flags with optional time-out. */ + /* "wait_flags" identifies the flags to wait for. */ + /* "timeout" is the time-out limit in system ticks (0xffff if no time-out) */ + /* "and_wait" specifies the AND-ing of "wait_flags" as condition to be met */ + /* to complete the wait. (OR-ing if set to 0). */ + U32 block_state; + + if (and_wait) { + /* Check for AND-connected events */ + if ((os_tsk.run->events & wait_flags) == wait_flags) { + os_tsk.run->events &= ~wait_flags; + return (OS_R_EVT); + } + block_state = WAIT_AND; + } + else { + /* Check for OR-connected events */ + if (os_tsk.run->events & wait_flags) { + os_tsk.run->waits = os_tsk.run->events & wait_flags; + os_tsk.run->events &= ~wait_flags; + return (OS_R_EVT); + } + block_state = WAIT_OR; + } + /* Task has to wait */ + os_tsk.run->waits = wait_flags; + rt_block (timeout, (U8)block_state); + return (OS_R_TMO); +} + + +/*--------------------------- rt_evt_set ------------------------------------*/ + +void rt_evt_set (U16 event_flags, OS_TID task_id) { + /* Set one or more event flags of a selectable task. */ + P_TCB p_tcb; + + p_tcb = os_active_TCB[task_id-1]; + if (p_tcb == NULL) { + return; + } + p_tcb->events |= event_flags; + event_flags = p_tcb->waits; + /* If the task is not waiting for an event, it should not be put */ + /* to ready state. */ + if (p_tcb->state == WAIT_AND) { + /* Check for AND-connected events */ + if ((p_tcb->events & event_flags) == event_flags) { + goto wkup; + } + } + if (p_tcb->state == WAIT_OR) { + /* Check for OR-connected events */ + if (p_tcb->events & event_flags) { + p_tcb->waits &= p_tcb->events; +wkup: p_tcb->events &= ~event_flags; + rt_rmv_dly (p_tcb); + p_tcb->state = READY; +#ifdef __CMSIS_RTOS + rt_ret_val2(p_tcb, 0x08/*osEventSignal*/, p_tcb->waits); +#else + rt_ret_val (p_tcb, OS_R_EVT); +#endif + rt_dispatch (p_tcb); + } + } +} + + +/*--------------------------- rt_evt_clr ------------------------------------*/ + +void rt_evt_clr (U16 clear_flags, OS_TID task_id) { + /* Clear one or more event flags (identified by "clear_flags") of a */ + /* selectable task (identified by "task"). */ + P_TCB task = os_active_TCB[task_id-1]; + + if (task == NULL) { + return; + } + task->events &= ~clear_flags; +} + + +/*--------------------------- isr_evt_set -----------------------------------*/ + +void isr_evt_set (U16 event_flags, OS_TID task_id) { + /* Same function as "os_evt_set", but to be called by ISRs. */ + P_TCB p_tcb = os_active_TCB[task_id-1]; + + if (p_tcb == NULL) { + return; + } + rt_psq_enq (p_tcb, event_flags); + rt_psh_req (); +} + + +/*--------------------------- rt_evt_get ------------------------------------*/ + +U16 rt_evt_get (void) { + /* Get events of a running task after waiting for OR connected events. */ + return (os_tsk.run->waits); +} + + +/*--------------------------- rt_evt_psh ------------------------------------*/ + +void rt_evt_psh (P_TCB p_CB, U16 set_flags) { + /* Check if task has to be waken up */ + U16 event_flags; + + p_CB->events |= set_flags; + event_flags = p_CB->waits; + if (p_CB->state == WAIT_AND) { + /* Check for AND-connected events */ + if ((p_CB->events & event_flags) == event_flags) { + goto rdy; + } + } + if (p_CB->state == WAIT_OR) { + /* Check for OR-connected events */ + if (p_CB->events & event_flags) { + p_CB->waits &= p_CB->events; +rdy: p_CB->events &= ~event_flags; + rt_rmv_dly (p_CB); + p_CB->state = READY; +#ifdef __CMSIS_RTOS + rt_ret_val2(p_CB, 0x08/*osEventSignal*/, p_CB->waits); +#else + rt_ret_val (p_CB, OS_R_EVT); +#endif + rt_put_prio (&os_rdy, p_CB); + } + } +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/rt_Event.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,46 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_EVENT.H + * Purpose: Implements waits and wake-ups for event flags + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +/* Functions */ +extern OS_RESULT rt_evt_wait (U16 wait_flags, U16 timeout, BOOL and_wait); +extern void rt_evt_set (U16 event_flags, OS_TID task_id); +extern void rt_evt_clr (U16 clear_flags, OS_TID task_id); +extern void isr_evt_set (U16 event_flags, OS_TID task_id); +extern U16 rt_evt_get (void); +extern void rt_evt_psh (P_TCB p_CB, U16 set_flags); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/rt_HAL_CA.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,199 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_HAL_CM.H + * Purpose: Hardware Abstraction Layer for Cortex-A definitions + * Rev.: 21 Aug 2013 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +/* Definitions */ +#define INIT_CPSR_SYS 0x4000001F +#define INIT_CPSR_USER 0x40000010 + +#define CPSR_T_BIT 0x20 +#define CPSR_I_BIT 0x80 +#define CPSR_F_BIT 0x40 + +#define MODE_USR 0x10 +#define MODE_FIQ 0x11 +#define MODE_IRQ 0x12 +#define MODE_SVC 0x13 +#define MODE_ABT 0x17 +#define MODE_UND 0x1B +#define MODE_SYS 0x1F + +#define MAGIC_WORD 0xE25A2EA5 + +#include "core_ca9.h" + +#if defined (__CC_ARM) /* ARM Compiler */ + +#if ((__TARGET_ARCH_7_M || __TARGET_ARCH_7E_M || __TARGET_ARCH_7_A) && !NO_EXCLUSIVE_ACCESS) + #define __USE_EXCLUSIVE_ACCESS +#else + #undef __USE_EXCLUSIVE_ACCESS +#endif + +#elif defined (__GNUC__) /* GNU Compiler */ + +#error GNU Compiler support not implemented for Cortex-A + +#elif defined (__ICCARM__) /* IAR Compiler */ + +#error IAR Compiler support not implemented for Cortex-A + +#endif + +static U8 priority = 0xff; + +extern const U32 GICDistributor_BASE; +extern const U32 GICInterface_BASE; + +/* GIC registers - Distributor */ +#define GICD_ICDICER0 (*((volatile U32 *)(GICDistributor_BASE + 0x180))) /* - RW - Interrupt Clear-Enable Registers */ +#define GICD_ICDISER0 (*((volatile U32 *)(GICDistributor_BASE + 0x100))) /* - RW - Interrupt Set-Enable Registers */ +#define GICD_ICDIPR0 (*((volatile U32 *)(GICDistributor_BASE + 0x400))) /* - RW - Interrupt Priority Registers */ +#define GICD_ICDSGIR (*((volatile U32 *)(GICDistributor_BASE + 0xf00))) /* - RW - Interrupt Software Interrupt Register */ +#define GICD_ICDICERx(irq) *(volatile U32 *)(&GICD_ICDICER0 + irq/32) +#define GICD_ICDISERx(irq) *(volatile U32 *)(&GICD_ICDISER0 + irq/32) + +/* GIC register - CPU Interface */ +#define GICI_ICCPMR (*((volatile U32 *)(GICInterface_BASE + 0x004))) /* - RW - Interrupt Priority Mask Register */ + +#define SGI_PENDSV 0 /* SGI0 */ +#define SGI_PENDSV_BIT ((U32)(1 << (SGI_PENDSV & 0xf))) + +//Increase priority filter to prevent timer and PendSV interrupts signaling. Guarantees that interrupts will not be forwarded. +#define OS_LOCK() int irq_dis = __disable_irq();\ + priority = GICI_ICCPMR; \ + GICI_ICCPMR = 0xff; \ + GICI_ICCPMR = GICI_ICCPMR - 1; \ + while(GICI_ICCPMR > priority);\ + __DSB();\ + if(!irq_dis) __enable_irq(); \ + +//Restore priority filter. Re-enable timer and PendSV signaling +#define OS_UNLOCK() __DSB(); \ + GICI_ICCPMR = priority; \ + +#define OS_PEND_IRQ() GICD_ICDSGIR = 0x0010000 | SGI_PENDSV +#define OS_PEND(fl,p) if(p) OS_PEND_IRQ(); +#define OS_UNPEND(fl) + +/* HW initialization needs to be done in os_tick_init (void) -RTX_Conf_CM.c- + * OS_X_INIT enables the IRQ n in the GIC */ +#define OS_X_INIT(n) char *reg; \ + reg = (char *)(&GICD_ICDIPR0 + n / 4); \ + reg += n % 4; \ + *reg = (char)0xff; \ + *reg = *reg - 1; \ + GICD_ICDISERx(n) = (U32)(1 << n % 32); +#define OS_X_LOCK(n) OS_LOCK() +#define OS_X_UNLOCK(n) OS_UNLOCK() +#define OS_X_PEND_IRQ() OS_PEND_IRQ() +#define OS_X_PEND(fl,p) if(p) OS_X_PEND_IRQ(); +#define OS_X_UNPEND(fl) + + +/* Functions */ +#ifdef __USE_EXCLUSIVE_ACCESS + #define rt_inc(p) while(__strex((__ldrex(p)+1),p)) + #define rt_dec(p) while(__strex((__ldrex(p)-1),p)) +#else + #define rt_inc(p) { int irq_dis = __disable_irq();(*p)++;if(!irq_dis) __enable_irq(); } + #define rt_dec(p) { int irq_dis = __disable_irq();(*p)--;if(!irq_dis) __enable_irq(); } +#endif + +__inline static U32 rt_inc_qi (U32 size, U8 *count, U8 *first) { + U32 cnt,c2; +#ifdef __USE_EXCLUSIVE_ACCESS + do { + if ((cnt = __ldrex(count)) == size) { + __clrex(); + return (cnt); } + } while (__strex(cnt+1, count)); + do { + c2 = (cnt = __ldrex(first)) + 1; + if (c2 == size) c2 = 0; + } while (__strex(c2, first)); +#else + int irq_dis; + irq_dis = __disable_irq(); + if ((cnt = *count) < size) { + *count = cnt+1; + c2 = (cnt = *first) + 1; + if (c2 == size) c2 = 0; + *first = c2; + } + if(!irq_dis) __enable_irq (); +#endif + return (cnt); +} + +__inline static void rt_systick_init (void) { + /* Cortex-A doesn't have a Systick. User needs to provide an alternative timer using RTX_Conf_CM configuration */ + /* HW initialization needs to be done in os_tick_init (void) -RTX_Conf_CM.c- */ +} + +__inline static void rt_svc_init (void) { + /* Register pendSV - through SGI */ + char *reg; + + reg = (char *)(&GICD_ICDIPR0 + SGI_PENDSV/4); + reg += SGI_PENDSV % 4; + /* Write 0xff to read priority level */ + *reg = (char)0xff; + /* Read priority level and set the lowest possible*/ + *reg = *reg - 1; + + GICD_ICDISERx(SGI_PENDSV) = (U32)SGI_PENDSV_BIT; +} + +extern void rt_set_PSP (U32 stack); +extern U32 rt_get_PSP (void); +extern void os_set_env (P_TCB p_TCB); +extern void *_alloc_box (void *box_mem); +extern int _free_box (void *box_mem, void *box); + +extern void rt_init_stack (P_TCB p_TCB, FUNCP task_body); +extern void rt_ret_val (P_TCB p_TCB, U32 v0); +extern void rt_ret_val2 (P_TCB p_TCB, U32 v0, U32 v1); + +extern void dbg_init (void); +extern void dbg_task_notify (P_TCB p_tcb, BOOL create); +extern void dbg_task_switch (U32 task_id); + +#define DBG_INIT() +#define DBG_TASK_NOTIFY(p_tcb,create) +#define DBG_TASK_SWITCH(task_id) + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/rt_HAL_CM.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,276 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_HAL_CM.H + * Purpose: Hardware Abstraction Layer for Cortex-M definitions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +/* Definitions */ +#define INITIAL_xPSR 0x01000000 +#define DEMCR_TRCENA 0x01000000 +#define ITM_ITMENA 0x00000001 +#define MAGIC_WORD 0xE25A2EA5 + +#if defined (__CC_ARM) /* ARM Compiler */ + +#if ((__TARGET_ARCH_7_M || __TARGET_ARCH_7E_M) && !NO_EXCLUSIVE_ACCESS) + #define __USE_EXCLUSIVE_ACCESS +#else + #undef __USE_EXCLUSIVE_ACCESS +#endif + +#elif defined (__GNUC__) /* GNU Compiler */ + +#undef __USE_EXCLUSIVE_ACCESS + +#if defined (__CORTEX_M0) +#define __TARGET_ARCH_6S_M 1 +#else +#define __TARGET_ARCH_6S_M 0 +#endif + +#if defined (__VFP_FP__) && !defined(__SOFTFP__) +#define __TARGET_FPU_VFP 1 +#else +#define __TARGET_FPU_VFP 0 +#endif + +#define __inline inline +#define __weak __attribute__((weak)) + +#ifndef __CMSIS_GENERIC + +__attribute__((always_inline)) static inline void __enable_irq(void) +{ + __asm volatile ("cpsie i"); +} + +__attribute__((always_inline)) static inline U32 __disable_irq(void) +{ + U32 result; + + __asm volatile ("mrs %0, primask" : "=r" (result)); + __asm volatile ("cpsid i"); + return(result & 1); +} + +#endif + +__attribute__(( always_inline)) static inline U8 __clz(U32 value) +{ + U8 result; + + __asm volatile ("clz %0, %1" : "=r" (result) : "r" (value)); + return(result); +} + +#elif defined (__ICCARM__) /* IAR Compiler */ + +#undef __USE_EXCLUSIVE_ACCESS + +#if (__CORE__ == __ARM6M__) +#define __TARGET_ARCH_6S_M 1 +#else +#define __TARGET_ARCH_6S_M 0 +#endif + +#if defined __ARMVFP__ +#define __TARGET_FPU_VFP 1 +#else +#define __TARGET_FPU_VFP 0 +#endif + +#define __inline inline + +#ifndef __CMSIS_GENERIC + +static inline void __enable_irq(void) +{ + __asm volatile ("cpsie i"); +} + +static inline U32 __disable_irq(void) +{ + U32 result; + + __asm volatile ("mrs %0, primask" : "=r" (result)); + __asm volatile ("cpsid i"); + return(result & 1); +} + +#endif + +static inline U8 __clz(U32 value) +{ + U8 result; + + __asm volatile ("clz %0, %1" : "=r" (result) : "r" (value)); + return(result); +} + +#endif + +/* NVIC registers */ +#define NVIC_ST_CTRL (*((volatile U32 *)0xE000E010)) +#define NVIC_ST_RELOAD (*((volatile U32 *)0xE000E014)) +#define NVIC_ST_CURRENT (*((volatile U32 *)0xE000E018)) +#define NVIC_ISER ((volatile U32 *)0xE000E100) +#define NVIC_ICER ((volatile U32 *)0xE000E180) +#if (__TARGET_ARCH_6S_M) +#define NVIC_IP ((volatile U32 *)0xE000E400) +#else +#define NVIC_IP ((volatile U8 *)0xE000E400) +#endif +#define NVIC_INT_CTRL (*((volatile U32 *)0xE000ED04)) +#define NVIC_AIR_CTRL (*((volatile U32 *)0xE000ED0C)) +#define NVIC_SYS_PRI2 (*((volatile U32 *)0xE000ED1C)) +#define NVIC_SYS_PRI3 (*((volatile U32 *)0xE000ED20)) + +#define OS_PEND_IRQ() NVIC_INT_CTRL = (1<<28) +#define OS_PENDING ((NVIC_INT_CTRL >> 26) & (1<<2 | 1)) +#define OS_UNPEND(fl) NVIC_INT_CTRL = (*fl = OS_PENDING) << 25 +#define OS_PEND(fl,p) NVIC_INT_CTRL = (fl | p<<2) << 26 +#define OS_LOCK() NVIC_ST_CTRL = 0x0005 +#define OS_UNLOCK() NVIC_ST_CTRL = 0x0007 + +#define OS_X_PENDING ((NVIC_INT_CTRL >> 28) & 1) +#define OS_X_UNPEND(fl) NVIC_INT_CTRL = (*fl = OS_X_PENDING) << 27 +#define OS_X_PEND(fl,p) NVIC_INT_CTRL = (fl | p) << 28 +#if (__TARGET_ARCH_6S_M) +#define OS_X_INIT(n) NVIC_IP[n>>2] |= 0xFF << (8*(n & 0x03)); \ + NVIC_ISER[n>>5] = 1 << (n & 0x1F) +#else +#define OS_X_INIT(n) NVIC_IP[n] = 0xFF; \ + NVIC_ISER[n>>5] = 1 << (n & 0x1F) +#endif +#define OS_X_LOCK(n) NVIC_ICER[n>>5] = 1 << (n & 0x1F) +#define OS_X_UNLOCK(n) NVIC_ISER[n>>5] = 1 << (n & 0x1F) + +/* Core Debug registers */ +#define DEMCR (*((volatile U32 *)0xE000EDFC)) + +/* ITM registers */ +#define ITM_CONTROL (*((volatile U32 *)0xE0000E80)) +#define ITM_ENABLE (*((volatile U32 *)0xE0000E00)) +#define ITM_PORT30_U32 (*((volatile U32 *)0xE0000078)) +#define ITM_PORT31_U32 (*((volatile U32 *)0xE000007C)) +#define ITM_PORT31_U16 (*((volatile U16 *)0xE000007C)) +#define ITM_PORT31_U8 (*((volatile U8 *)0xE000007C)) + +/* Variables */ +extern BIT dbg_msg; + +/* Functions */ +#ifdef __USE_EXCLUSIVE_ACCESS + #define rt_inc(p) while(__strex((__ldrex(p)+1),p)) + #define rt_dec(p) while(__strex((__ldrex(p)-1),p)) +#else + #define rt_inc(p) __disable_irq();(*p)++;__enable_irq(); + #define rt_dec(p) __disable_irq();(*p)--;__enable_irq(); +#endif + +__inline static U32 rt_inc_qi (U32 size, U8 *count, U8 *first) { + U32 cnt,c2; +#ifdef __USE_EXCLUSIVE_ACCESS + do { + if ((cnt = __ldrex(count)) == size) { + __clrex(); + return (cnt); } + } while (__strex(cnt+1, count)); + do { + c2 = (cnt = __ldrex(first)) + 1; + if (c2 == size) c2 = 0; + } while (__strex(c2, first)); +#else + __disable_irq(); + if ((cnt = *count) < size) { + *count = cnt+1; + c2 = (cnt = *first) + 1; + if (c2 == size) c2 = 0; + *first = c2; + } + __enable_irq (); +#endif + return (cnt); +} + +__inline static void rt_systick_init (void) { + NVIC_ST_RELOAD = os_trv; + NVIC_ST_CURRENT = 0; + NVIC_ST_CTRL = 0x0007; + NVIC_SYS_PRI3 |= 0xFF000000; +} + +__inline static void rt_svc_init (void) { +#if !(__TARGET_ARCH_6S_M) + int sh,prigroup; +#endif + NVIC_SYS_PRI3 |= 0x00FF0000; +#if (__TARGET_ARCH_6S_M) + NVIC_SYS_PRI2 |= (NVIC_SYS_PRI3<<(8+1)) & 0xFC000000; +#else + sh = 8 - __clz (~((NVIC_SYS_PRI3 << 8) & 0xFF000000)); + prigroup = ((NVIC_AIR_CTRL >> 8) & 0x07); + if (prigroup >= sh) { + sh = prigroup + 1; + } + NVIC_SYS_PRI2 = ((0xFEFFFFFF << sh) & 0xFF000000) | (NVIC_SYS_PRI2 & 0x00FFFFFF); +#endif +} + +extern void rt_set_PSP (U32 stack); +extern U32 rt_get_PSP (void); +extern void os_set_env (void); +extern void *_alloc_box (void *box_mem); +extern int _free_box (void *box_mem, void *box); + +extern void rt_init_stack (P_TCB p_TCB, FUNCP task_body); +extern void rt_ret_val (P_TCB p_TCB, U32 v0); +extern void rt_ret_val2 (P_TCB p_TCB, U32 v0, U32 v1); + +extern void dbg_init (void); +extern void dbg_task_notify (P_TCB p_tcb, BOOL create); +extern void dbg_task_switch (U32 task_id); + +#ifdef DBG_MSG +#define DBG_INIT() dbg_init() +#define DBG_TASK_NOTIFY(p_tcb,create) if (dbg_msg) dbg_task_notify(p_tcb,create) +#define DBG_TASK_SWITCH(task_id) if (dbg_msg && (os_tsk.new!=os_tsk.run)) \ + dbg_task_switch(task_id) +#else +#define DBG_INIT() +#define DBG_TASK_NOTIFY(p_tcb,create) +#define DBG_TASK_SWITCH(task_id) +#endif + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/rt_List.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,324 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_LIST.C + * Purpose: Functions for the management of different lists + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "RTX_Config.h" +#include "rt_System.h" +#include "rt_List.h" +#include "rt_Task.h" +#include "rt_Time.h" +#ifdef __CORTEX_A9 +#include "rt_HAL_CA.h" +#else +#include "rt_HAL_CM.h" +#endif + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +/* List head of chained ready tasks */ +struct OS_XCB os_rdy; +/* List head of chained delay tasks */ +struct OS_XCB os_dly; + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_put_prio -----------------------------------*/ + +void rt_put_prio (P_XCB p_CB, P_TCB p_task) { + /* Put task identified with "p_task" into list ordered by priority. */ + /* "p_CB" points to head of list; list has always an element at end with */ + /* a priority less than "p_task->prio". */ + P_TCB p_CB2; + U32 prio; + BOOL sem_mbx = __FALSE; + + if (p_CB->cb_type == SCB || p_CB->cb_type == MCB || p_CB->cb_type == MUCB) { + sem_mbx = __TRUE; + } + prio = p_task->prio; + p_CB2 = p_CB->p_lnk; + /* Search for an entry in the list */ + while (p_CB2 != NULL && prio <= p_CB2->prio) { + p_CB = (P_XCB)p_CB2; + p_CB2 = p_CB2->p_lnk; + } + /* Entry found, insert the task into the list */ + p_task->p_lnk = p_CB2; + p_CB->p_lnk = p_task; + if (sem_mbx) { + if (p_CB2 != NULL) { + p_CB2->p_rlnk = p_task; + } + p_task->p_rlnk = (P_TCB)p_CB; + } + else { + p_task->p_rlnk = NULL; + } +} + + +/*--------------------------- rt_get_first ----------------------------------*/ + +P_TCB rt_get_first (P_XCB p_CB) { + /* Get task at head of list: it is the task with highest priority. */ + /* "p_CB" points to head of list. */ + P_TCB p_first; + + p_first = p_CB->p_lnk; + p_CB->p_lnk = p_first->p_lnk; + if (p_CB->cb_type == SCB || p_CB->cb_type == MCB || p_CB->cb_type == MUCB) { + if (p_first->p_lnk != NULL) { + p_first->p_lnk->p_rlnk = (P_TCB)p_CB; + p_first->p_lnk = NULL; + } + p_first->p_rlnk = NULL; + } + else { + p_first->p_lnk = NULL; + } + return (p_first); +} + + +/*--------------------------- rt_put_rdy_first ------------------------------*/ + +void rt_put_rdy_first (P_TCB p_task) { + /* Put task identified with "p_task" at the head of the ready list. The */ + /* task must have at least a priority equal to highest priority in list. */ + p_task->p_lnk = os_rdy.p_lnk; + p_task->p_rlnk = NULL; + os_rdy.p_lnk = p_task; +} + + +/*--------------------------- rt_get_same_rdy_prio --------------------------*/ + +P_TCB rt_get_same_rdy_prio (void) { + /* Remove a task of same priority from ready list if any exists. Other- */ + /* wise return NULL. */ + P_TCB p_first; + + p_first = os_rdy.p_lnk; + if (p_first->prio == os_tsk.run->prio) { + os_rdy.p_lnk = os_rdy.p_lnk->p_lnk; + return (p_first); + } + return (NULL); +} + + +/*--------------------------- rt_resort_prio --------------------------------*/ + +void rt_resort_prio (P_TCB p_task) { + /* Re-sort ordered lists after the priority of 'p_task' has changed. */ + P_TCB p_CB; + + if (p_task->p_rlnk == NULL) { + if (p_task->state == READY) { + /* Task is chained into READY list. */ + p_CB = (P_TCB)&os_rdy; + goto res; + } + } + else { + p_CB = p_task->p_rlnk; + while (p_CB->cb_type == TCB) { + /* Find a header of this task chain list. */ + p_CB = p_CB->p_rlnk; + } +res:rt_rmv_list (p_task); + rt_put_prio ((P_XCB)p_CB, p_task); + } +} + + +/*--------------------------- rt_put_dly ------------------------------------*/ + +void rt_put_dly (P_TCB p_task, U16 delay) { + /* Put a task identified with "p_task" into chained delay wait list using */ + /* a delay value of "delay". */ + P_TCB p; + U32 delta,idelay = delay; + + p = (P_TCB)&os_dly; + if (p->p_dlnk == NULL) { + /* Delay list empty */ + delta = 0; + goto last; + } + delta = os_dly.delta_time; + while (delta < idelay) { + if (p->p_dlnk == NULL) { + /* End of list found */ +last: p_task->p_dlnk = NULL; + p->p_dlnk = p_task; + p_task->p_blnk = p; + p->delta_time = (U16)(idelay - delta); + p_task->delta_time = 0; + return; + } + p = p->p_dlnk; + delta += p->delta_time; + } + /* Right place found */ + p_task->p_dlnk = p->p_dlnk; + p->p_dlnk = p_task; + p_task->p_blnk = p; + if (p_task->p_dlnk != NULL) { + p_task->p_dlnk->p_blnk = p_task; + } + p_task->delta_time = (U16)(delta - idelay); + p->delta_time -= p_task->delta_time; +} + + +/*--------------------------- rt_dec_dly ------------------------------------*/ + +void rt_dec_dly (void) { + /* Decrement delta time of list head: remove tasks having a value of zero.*/ + P_TCB p_rdy; + + if (os_dly.p_dlnk == NULL) { + return; + } + os_dly.delta_time--; + while ((os_dly.delta_time == 0) && (os_dly.p_dlnk != NULL)) { + p_rdy = os_dly.p_dlnk; + if (p_rdy->p_rlnk != NULL) { + /* Task is really enqueued, remove task from semaphore/mailbox */ + /* timeout waiting list. */ + p_rdy->p_rlnk->p_lnk = p_rdy->p_lnk; + if (p_rdy->p_lnk != NULL) { + p_rdy->p_lnk->p_rlnk = p_rdy->p_rlnk; + p_rdy->p_lnk = NULL; + } + p_rdy->p_rlnk = NULL; + } + rt_put_prio (&os_rdy, p_rdy); + os_dly.delta_time = p_rdy->delta_time; + if (p_rdy->state == WAIT_ITV) { + /* Calculate the next time for interval wait. */ + p_rdy->delta_time = p_rdy->interval_time + (U16)os_time; + } + p_rdy->state = READY; + os_dly.p_dlnk = p_rdy->p_dlnk; + if (p_rdy->p_dlnk != NULL) { + p_rdy->p_dlnk->p_blnk = (P_TCB)&os_dly; + p_rdy->p_dlnk = NULL; + } + p_rdy->p_blnk = NULL; + } +} + + +/*--------------------------- rt_rmv_list -----------------------------------*/ + +void rt_rmv_list (P_TCB p_task) { + /* Remove task identified with "p_task" from ready, semaphore or mailbox */ + /* waiting list if enqueued. */ + P_TCB p_b; + + if (p_task->p_rlnk != NULL) { + /* A task is enqueued in semaphore / mailbox waiting list. */ + p_task->p_rlnk->p_lnk = p_task->p_lnk; + if (p_task->p_lnk != NULL) { + p_task->p_lnk->p_rlnk = p_task->p_rlnk; + } + return; + } + + p_b = (P_TCB)&os_rdy; + while (p_b != NULL) { + /* Search the ready list for task "p_task" */ + if (p_b->p_lnk == p_task) { + p_b->p_lnk = p_task->p_lnk; + return; + } + p_b = p_b->p_lnk; + } +} + + +/*--------------------------- rt_rmv_dly ------------------------------------*/ + +void rt_rmv_dly (P_TCB p_task) { + /* Remove task identified with "p_task" from delay list if enqueued. */ + P_TCB p_b; + + p_b = p_task->p_blnk; + if (p_b != NULL) { + /* Task is really enqueued */ + p_b->p_dlnk = p_task->p_dlnk; + if (p_task->p_dlnk != NULL) { + /* 'p_task' is in the middle of list */ + p_b->delta_time += p_task->delta_time; + p_task->p_dlnk->p_blnk = p_b; + p_task->p_dlnk = NULL; + } + else { + /* 'p_task' is at the end of list */ + p_b->delta_time = 0; + } + p_task->p_blnk = NULL; + } +} + + +/*--------------------------- rt_psq_enq ------------------------------------*/ + +void rt_psq_enq (OS_ID entry, U32 arg) { + /* Insert post service request "entry" into ps-queue. */ + U32 idx; + + idx = rt_inc_qi (os_psq->size, &os_psq->count, &os_psq->first); + if (idx < os_psq->size) { + os_psq->q[idx].id = entry; + os_psq->q[idx].arg = arg; + } + else { + os_error (OS_ERR_FIFO_OVF); + } +} + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/rt_List.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,67 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_LIST.H + * Purpose: Functions for the management of different lists + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +/* Definitions */ + +/* Values for 'cb_type' */ +#define TCB 0 +#define MCB 1 +#define SCB 2 +#define MUCB 3 +#define HCB 4 + +/* Variables */ +extern struct OS_XCB os_rdy; +extern struct OS_XCB os_dly; + +/* Functions */ +extern void rt_put_prio (P_XCB p_CB, P_TCB p_task); +extern P_TCB rt_get_first (P_XCB p_CB); +extern void rt_put_rdy_first (P_TCB p_task); +extern P_TCB rt_get_same_rdy_prio (void); +extern void rt_resort_prio (P_TCB p_task); +extern void rt_put_dly (P_TCB p_task, U16 delay); +extern void rt_dec_dly (void); +extern void rt_rmv_list (P_TCB p_task); +extern void rt_rmv_dly (P_TCB p_task); +extern void rt_psq_enq (OS_ID entry, U32 arg); + +/* This is a fast macro generating in-line code */ +#define rt_rdy_prio(void) (os_rdy.p_lnk->prio) + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/rt_Mailbox.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,296 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MAILBOX.C + * Purpose: Implements waits and wake-ups for mailbox messages + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "RTX_Config.h" +#include "rt_System.h" +#include "rt_List.h" +#include "rt_Mailbox.h" +#include "rt_MemBox.h" +#include "rt_Task.h" +#ifdef __CORTEX_A9 +#include "rt_HAL_CA.h" +#else +#include "rt_HAL_CM.h" +#endif + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_mbx_init -----------------------------------*/ + +void rt_mbx_init (OS_ID mailbox, U16 mbx_size) { + /* Initialize a mailbox */ + P_MCB p_MCB = mailbox; + + p_MCB->cb_type = MCB; + p_MCB->state = 0; + p_MCB->isr_st = 0; + p_MCB->p_lnk = NULL; + p_MCB->first = 0; + p_MCB->last = 0; + p_MCB->count = 0; + p_MCB->size = (mbx_size + sizeof(void *) - sizeof(struct OS_MCB)) / + (U32)sizeof (void *); +} + + +/*--------------------------- rt_mbx_send -----------------------------------*/ + +OS_RESULT rt_mbx_send (OS_ID mailbox, void *p_msg, U16 timeout) { + /* Send message to a mailbox */ + P_MCB p_MCB = mailbox; + P_TCB p_TCB; + + if ((p_MCB->p_lnk != NULL) && (p_MCB->state == 1)) { + /* A task is waiting for message */ + p_TCB = rt_get_first ((P_XCB)p_MCB); +#ifdef __CMSIS_RTOS + rt_ret_val2(p_TCB, 0x10/*osEventMessage*/, (U32)p_msg); +#else + *p_TCB->msg = p_msg; + rt_ret_val (p_TCB, OS_R_MBX); +#endif + rt_rmv_dly (p_TCB); + rt_dispatch (p_TCB); + } + else { + /* Store message in mailbox queue */ + if (p_MCB->count == p_MCB->size) { + /* No free message entry, wait for one. If message queue is full, */ + /* then no task is waiting for message. The 'p_MCB->p_lnk' list */ + /* pointer can now be reused for send message waits task list. */ + if (timeout == 0) { + return (OS_R_TMO); + } + if (p_MCB->p_lnk != NULL) { + rt_put_prio ((P_XCB)p_MCB, os_tsk.run); + } + else { + p_MCB->p_lnk = os_tsk.run; + os_tsk.run->p_lnk = NULL; + os_tsk.run->p_rlnk = (P_TCB)p_MCB; + /* Task is waiting to send a message */ + p_MCB->state = 2; + } + os_tsk.run->msg = p_msg; + rt_block (timeout, WAIT_MBX); + return (OS_R_TMO); + } + /* Yes, there is a free entry in a mailbox. */ + p_MCB->msg[p_MCB->first] = p_msg; + rt_inc (&p_MCB->count); + if (++p_MCB->first == p_MCB->size) { + p_MCB->first = 0; + } + } + return (OS_R_OK); +} + + +/*--------------------------- rt_mbx_wait -----------------------------------*/ + +OS_RESULT rt_mbx_wait (OS_ID mailbox, void **message, U16 timeout) { + /* Receive a message; possibly wait for it */ + P_MCB p_MCB = mailbox; + P_TCB p_TCB; + + /* If a message is available in the fifo buffer */ + /* remove it from the fifo buffer and return. */ + if (p_MCB->count) { + *message = p_MCB->msg[p_MCB->last]; + if (++p_MCB->last == p_MCB->size) { + p_MCB->last = 0; + } + if ((p_MCB->p_lnk != NULL) && (p_MCB->state == 2)) { + /* A task is waiting to send message */ + p_TCB = rt_get_first ((P_XCB)p_MCB); +#ifdef __CMSIS_RTOS + rt_ret_val(p_TCB, 0/*osOK*/); +#else + rt_ret_val(p_TCB, OS_R_OK); +#endif + p_MCB->msg[p_MCB->first] = p_TCB->msg; + if (++p_MCB->first == p_MCB->size) { + p_MCB->first = 0; + } + rt_rmv_dly (p_TCB); + rt_dispatch (p_TCB); + } + else { + rt_dec (&p_MCB->count); + } + return (OS_R_OK); + } + /* No message available: wait for one */ + if (timeout == 0) { + return (OS_R_TMO); + } + if (p_MCB->p_lnk != NULL) { + rt_put_prio ((P_XCB)p_MCB, os_tsk.run); + } + else { + p_MCB->p_lnk = os_tsk.run; + os_tsk.run->p_lnk = NULL; + os_tsk.run->p_rlnk = (P_TCB)p_MCB; + /* Task is waiting to receive a message */ + p_MCB->state = 1; + } + rt_block(timeout, WAIT_MBX); +#ifndef __CMSIS_RTOS + os_tsk.run->msg = message; +#endif + return (OS_R_TMO); +} + + +/*--------------------------- rt_mbx_check ----------------------------------*/ + +OS_RESULT rt_mbx_check (OS_ID mailbox) { + /* Check for free space in a mailbox. Returns the number of messages */ + /* that can be stored to a mailbox. It returns 0 when mailbox is full. */ + P_MCB p_MCB = mailbox; + + return (p_MCB->size - p_MCB->count); +} + + +/*--------------------------- isr_mbx_send ----------------------------------*/ + +void isr_mbx_send (OS_ID mailbox, void *p_msg) { + /* Same function as "os_mbx_send", but to be called by ISRs. */ + P_MCB p_MCB = mailbox; + + rt_psq_enq (p_MCB, (U32)p_msg); + rt_psh_req (); +} + + +/*--------------------------- isr_mbx_receive -------------------------------*/ + +OS_RESULT isr_mbx_receive (OS_ID mailbox, void **message) { + /* Receive a message in the interrupt function. The interrupt function */ + /* should not wait for a message since this would block the rtx os. */ + P_MCB p_MCB = mailbox; + + if (p_MCB->count) { + /* A message is available in the fifo buffer. */ + *message = p_MCB->msg[p_MCB->last]; + if (p_MCB->state == 2) { + /* A task is locked waiting to send message */ + rt_psq_enq (p_MCB, 0); + rt_psh_req (); + } + rt_dec (&p_MCB->count); + if (++p_MCB->last == p_MCB->size) { + p_MCB->last = 0; + } + return (OS_R_MBX); + } + return (OS_R_OK); +} + + +/*--------------------------- rt_mbx_psh ------------------------------------*/ + +void rt_mbx_psh (P_MCB p_CB, void *p_msg) { + /* Store the message to the mailbox queue or pass it to task directly. */ + P_TCB p_TCB; + void *mem; + + if (p_CB->p_lnk != NULL) switch (p_CB->state) { +#ifdef __CMSIS_RTOS + case 3: + /* Task is waiting to allocate memory, remove it from the waiting list */ + mem = rt_alloc_box(p_msg); + if (mem == NULL) break; + p_TCB = rt_get_first ((P_XCB)p_CB); + rt_ret_val(p_TCB, (U32)mem); + p_TCB->state = READY; + rt_rmv_dly (p_TCB); + rt_put_prio (&os_rdy, p_TCB); + break; +#endif + case 2: + /* Task is waiting to send a message, remove it from the waiting list */ + p_TCB = rt_get_first ((P_XCB)p_CB); +#ifdef __CMSIS_RTOS + rt_ret_val(p_TCB, 0/*osOK*/); +#else + rt_ret_val(p_TCB, OS_R_OK); +#endif + p_CB->msg[p_CB->first] = p_TCB->msg; + rt_inc (&p_CB->count); + if (++p_CB->first == p_CB->size) { + p_CB->first = 0; + } + p_TCB->state = READY; + rt_rmv_dly (p_TCB); + rt_put_prio (&os_rdy, p_TCB); + break; + case 1: + /* Task is waiting for a message, pass the message to the task directly */ + p_TCB = rt_get_first ((P_XCB)p_CB); +#ifdef __CMSIS_RTOS + rt_ret_val2(p_TCB, 0x10/*osEventMessage*/, (U32)p_msg); +#else + *p_TCB->msg = p_msg; + rt_ret_val (p_TCB, OS_R_MBX); +#endif + p_TCB->state = READY; + rt_rmv_dly (p_TCB); + rt_put_prio (&os_rdy, p_TCB); + break; + } else { + /* No task is waiting for a message, store it to the mailbox queue */ + if (p_CB->count < p_CB->size) { + p_CB->msg[p_CB->first] = p_msg; + rt_inc (&p_CB->count); + if (++p_CB->first == p_CB->size) { + p_CB->first = 0; + } + } + else { + os_error (OS_ERR_MBX_OVF); + } + } +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/rt_Mailbox.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,48 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MAILBOX.H + * Purpose: Implements waits and wake-ups for mailbox messages + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +/* Functions */ +extern void rt_mbx_init (OS_ID mailbox, U16 mbx_size); +extern OS_RESULT rt_mbx_send (OS_ID mailbox, void *p_msg, U16 timeout); +extern OS_RESULT rt_mbx_wait (OS_ID mailbox, void **message, U16 timeout); +extern OS_RESULT rt_mbx_check (OS_ID mailbox); +extern void isr_mbx_send (OS_ID mailbox, void *p_msg); +extern OS_RESULT isr_mbx_receive (OS_ID mailbox, void **message); +extern void rt_mbx_psh (P_MCB p_CB, void *p_msg); + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/rt_MemBox.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,170 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MEMBOX.C + * Purpose: Interface functions for fixed memory block management system + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "RTX_Config.h" +#include "rt_System.h" +#include "rt_MemBox.h" +#ifdef __CORTEX_A9 +#include "rt_HAL_CA.h" +#else +#include "rt_HAL_CM.h" +#endif + +/*---------------------------------------------------------------------------- + * Global Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- _init_box -------------------------------------*/ + +int _init_box (void *box_mem, U32 box_size, U32 blk_size) { + /* Initialize memory block system, returns 0 if OK, 1 if fails. */ + void *end; + void *blk; + void *next; + U32 sizeof_bm; + + /* Create memory structure. */ + if (blk_size & BOX_ALIGN_8) { + /* Memory blocks 8-byte aligned. */ + blk_size = ((blk_size & ~BOX_ALIGN_8) + 7) & ~7; + sizeof_bm = (sizeof (struct OS_BM) + 7) & ~7; + } + else { + /* Memory blocks 4-byte aligned. */ + blk_size = (blk_size + 3) & ~3; + sizeof_bm = sizeof (struct OS_BM); + } + if (blk_size == 0) { + return (1); + } + if ((blk_size + sizeof_bm) > box_size) { + return (1); + } + /* Create a Memory structure. */ + blk = ((U8 *) box_mem) + sizeof_bm; + ((P_BM) box_mem)->free = blk; + end = ((U8 *) box_mem) + box_size; + ((P_BM) box_mem)->end = end; + ((P_BM) box_mem)->blk_size = blk_size; + + /* Link all free blocks using offsets. */ + end = ((U8 *) end) - blk_size; + while (1) { + next = ((U8 *) blk) + blk_size; + if (next > end) break; + *((void **)blk) = next; + blk = next; + } + /* end marker */ + *((void **)blk) = 0; + return (0); +} + +/*--------------------------- rt_alloc_box ----------------------------------*/ + +void *rt_alloc_box (void *box_mem) { + /* Allocate a memory block and return start address. */ + void **free; +#ifndef __USE_EXCLUSIVE_ACCESS + int irq_dis; + + irq_dis = __disable_irq (); + free = ((P_BM) box_mem)->free; + if (free) { + ((P_BM) box_mem)->free = *free; + } + if (!irq_dis) __enable_irq (); +#else + do { + if ((free = (void **)__ldrex(&((P_BM) box_mem)->free)) == 0) { + __clrex(); + break; + } + } while (__strex((U32)*free, &((P_BM) box_mem)->free)); +#endif + return (free); +} + + +/*--------------------------- _calloc_box -----------------------------------*/ + +void *_calloc_box (void *box_mem) { + /* Allocate a 0-initialized memory block and return start address. */ + void *free; + U32 *p; + U32 i; + + free = _alloc_box (box_mem); + if (free) { + p = free; + for (i = ((P_BM) box_mem)->blk_size; i; i -= 4) { + *p = 0; + p++; + } + } + return (free); +} + + +/*--------------------------- rt_free_box -----------------------------------*/ + +int rt_free_box (void *box_mem, void *box) { + /* Free a memory block, returns 0 if OK, 1 if box does not belong to box_mem */ +#ifndef __USE_EXCLUSIVE_ACCESS + int irq_dis; +#endif + + if (box < box_mem || box >= ((P_BM) box_mem)->end) { + return (1); + } + +#ifndef __USE_EXCLUSIVE_ACCESS + irq_dis = __disable_irq (); + *((void **)box) = ((P_BM) box_mem)->free; + ((P_BM) box_mem)->free = box; + if (!irq_dis) __enable_irq (); +#else + do { + *((void **)box) = (void *)__ldrex(&((P_BM) box_mem)->free); + } while (__strex ((U32)box, &((P_BM) box_mem)->free)); +#endif + return (0); +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/rt_MemBox.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,46 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MEMBOX.H + * Purpose: Interface functions for fixed memory block management system + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +/* Functions */ +#define rt_init_box _init_box +#define rt_calloc_box _calloc_box +extern int _init_box (void *box_mem, U32 box_size, U32 blk_size); +extern void *rt_alloc_box (void *box_mem); +extern void * _calloc_box (void *box_mem); +extern int rt_free_box (void *box_mem, void *box); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/rt_Memory.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,140 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MEMORY.C + * Purpose: Interface functions for Dynamic Memory Management System + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "rt_Memory.h" + + +/* Functions */ + +// Initialize Dynamic Memory pool +// Parameters: +// pool: Pointer to memory pool +// size: Size of memory pool in bytes +// Return: 0 - OK, 1 - Error + +int rt_init_mem (void *pool, U32 size) { + MEMP *ptr; + + if ((pool == NULL) || (size < sizeof(MEMP))) return (1); + + ptr = (MEMP *)pool; + ptr->next = (MEMP *)((U32)pool + size - sizeof(MEMP *)); + ptr->next->next = NULL; + ptr->len = 0; + + return (0); +} + +// Allocate Memory from Memory pool +// Parameters: +// pool: Pointer to memory pool +// size: Size of memory in bytes to allocate +// Return: Pointer to allocated memory + +void *rt_alloc_mem (void *pool, U32 size) { + MEMP *p, *p_search, *p_new; + U32 hole_size; + + if ((pool == NULL) || (size == 0)) return NULL; + + /* Add header offset to 'size' */ + size += sizeof(MEMP); + /* Make sure that block is 4-byte aligned */ + size = (size + 3) & ~3; + + p_search = (MEMP *)pool; + while (1) { + hole_size = (U32)p_search->next - (U32)p_search; + hole_size -= p_search->len; + /* Check if hole size is big enough */ + if (hole_size >= size) break; + p_search = p_search->next; + if (p_search->next == NULL) { + /* Failed, we are at the end of the list */ + return NULL; + } + } + + if (p_search->len == 0) { + /* No block is allocated, set the Length of the first element */ + p_search->len = size; + p = (MEMP *)(((U32)p_search) + sizeof(MEMP)); + } else { + /* Insert new list element into the memory list */ + p_new = (MEMP *)((U32)p_search + p_search->len); + p_new->next = p_search->next; + p_new->len = size; + p_search->next = p_new; + p = (MEMP *)(((U32)p_new) + sizeof(MEMP)); + } + + return (p); +} + +// Free Memory and return it to Memory pool +// Parameters: +// pool: Pointer to memory pool +// mem: Pointer to memory to free +// Return: 0 - OK, 1 - Error + +int rt_free_mem (void *pool, void *mem) { + MEMP *p_search, *p_prev, *p_return; + + if ((pool == NULL) || (mem == NULL)) return (1); + + p_return = (MEMP *)((U32)mem - sizeof(MEMP)); + + /* Set list header */ + p_prev = NULL; + p_search = (MEMP *)pool; + while (p_search != p_return) { + p_prev = p_search; + p_search = p_search->next; + if (p_search == NULL) { + /* Valid Memory block not found */ + return (1); + } + } + + if (p_prev == NULL) { + /* First block to be released, only set length to 0 */ + p_search->len = 0; + } else { + /* Discard block from chain list */ + p_prev->next = p_search->next; + } + + return (0); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/rt_Memory.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,44 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MEMORY.H + * Purpose: Interface functions for Dynamic Memory Management System + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +/* Types */ +typedef struct mem { /* << Memory Pool management struct >> */ + struct mem *next; /* Next Memory Block in the list */ + U32 len; /* Length of data block */ +} MEMP; + +/* Functions */ +extern int rt_init_mem (void *pool, U32 size); +extern void *rt_alloc_mem (void *pool, U32 size); +extern int rt_free_mem (void *pool, void *mem);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/rt_Mutex.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,204 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MUTEX.C + * Purpose: Implements mutex synchronization objects + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "RTX_Config.h" +#include "rt_List.h" +#include "rt_Task.h" +#include "rt_Mutex.h" +#ifdef __CORTEX_A9 +#include "rt_HAL_CA.h" +#else +#include "rt_HAL_CM.h" +#endif + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_mut_init -----------------------------------*/ + +void rt_mut_init (OS_ID mutex) { + /* Initialize a mutex object */ + P_MUCB p_MCB = mutex; + + p_MCB->cb_type = MUCB; + p_MCB->prio = 0; + p_MCB->level = 0; + p_MCB->p_lnk = NULL; + p_MCB->owner = NULL; +} + + +/*--------------------------- rt_mut_delete ---------------------------------*/ + +#ifdef __CMSIS_RTOS +OS_RESULT rt_mut_delete (OS_ID mutex) { + /* Delete a mutex object */ + P_MUCB p_MCB = mutex; + P_TCB p_TCB; + + __DMB(); + /* Restore owner task's priority. */ + if (p_MCB->level != 0) { + p_MCB->owner->prio = p_MCB->prio; + if (p_MCB->owner != os_tsk.run) { + rt_resort_prio (p_MCB->owner); + } + } + + while (p_MCB->p_lnk != NULL) { + /* A task is waiting for mutex. */ + p_TCB = rt_get_first ((P_XCB)p_MCB); + rt_ret_val(p_TCB, 0/*osOK*/); + rt_rmv_dly(p_TCB); + p_TCB->state = READY; + rt_put_prio (&os_rdy, p_TCB); + } + + if (os_rdy.p_lnk && (os_rdy.p_lnk->prio > os_tsk.run->prio)) { + /* preempt running task */ + rt_put_prio (&os_rdy, os_tsk.run); + os_tsk.run->state = READY; + rt_dispatch (NULL); + } + + p_MCB->cb_type = 0; + + return (OS_R_OK); +} +#endif + + +/*--------------------------- rt_mut_release --------------------------------*/ + +OS_RESULT rt_mut_release (OS_ID mutex) { + /* Release a mutex object */ + P_MUCB p_MCB = mutex; + P_TCB p_TCB; + + if (p_MCB->level == 0 || p_MCB->owner != os_tsk.run) { + /* Unbalanced mutex release or task is not the owner */ + return (OS_R_NOK); + } + __DMB(); + if (--p_MCB->level != 0) { + return (OS_R_OK); + } + /* Restore owner task's priority. */ + os_tsk.run->prio = p_MCB->prio; + if (p_MCB->p_lnk != NULL) { + /* A task is waiting for mutex. */ + p_TCB = rt_get_first ((P_XCB)p_MCB); +#ifdef __CMSIS_RTOS + rt_ret_val(p_TCB, 0/*osOK*/); +#else + rt_ret_val(p_TCB, OS_R_MUT); +#endif + rt_rmv_dly (p_TCB); + /* A waiting task becomes the owner of this mutex. */ + p_MCB->level = 1; + p_MCB->owner = p_TCB; + p_MCB->prio = p_TCB->prio; + /* Priority inversion, check which task continues. */ + if (os_tsk.run->prio >= rt_rdy_prio()) { + rt_dispatch (p_TCB); + } + else { + /* Ready task has higher priority than running task. */ + rt_put_prio (&os_rdy, os_tsk.run); + rt_put_prio (&os_rdy, p_TCB); + os_tsk.run->state = READY; + p_TCB->state = READY; + rt_dispatch (NULL); + } + } + else { + /* Check if own priority raised by priority inversion. */ + if (rt_rdy_prio() > os_tsk.run->prio) { + rt_put_prio (&os_rdy, os_tsk.run); + os_tsk.run->state = READY; + rt_dispatch (NULL); + } + } + return (OS_R_OK); +} + + +/*--------------------------- rt_mut_wait -----------------------------------*/ + +OS_RESULT rt_mut_wait (OS_ID mutex, U16 timeout) { + /* Wait for a mutex, continue when mutex is free. */ + P_MUCB p_MCB = mutex; + + if (p_MCB->level == 0) { + p_MCB->owner = os_tsk.run; + p_MCB->prio = os_tsk.run->prio; + goto inc; + } + if (p_MCB->owner == os_tsk.run) { + /* OK, running task is the owner of this mutex. */ +inc:p_MCB->level++; + __DMB(); + return (OS_R_OK); + } + /* Mutex owned by another task, wait until released. */ + if (timeout == 0) { + return (OS_R_TMO); + } + /* Raise the owner task priority if lower than current priority. */ + /* This priority inversion is called priority inheritance. */ + if (p_MCB->prio < os_tsk.run->prio) { + p_MCB->owner->prio = os_tsk.run->prio; + rt_resort_prio (p_MCB->owner); + } + if (p_MCB->p_lnk != NULL) { + rt_put_prio ((P_XCB)p_MCB, os_tsk.run); + } + else { + p_MCB->p_lnk = os_tsk.run; + os_tsk.run->p_lnk = NULL; + os_tsk.run->p_rlnk = (P_TCB)p_MCB; + } + rt_block(timeout, WAIT_MUT); + return (OS_R_TMO); +} + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/rt_Mutex.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,44 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MUTEX.H + * Purpose: Implements mutex synchronization objects + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +/* Functions */ +extern void rt_mut_init (OS_ID mutex); +extern OS_RESULT rt_mut_delete (OS_ID mutex); +extern OS_RESULT rt_mut_release (OS_ID mutex); +extern OS_RESULT rt_mut_wait (OS_ID mutex, U16 timeout); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/rt_Robin.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,88 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_ROBIN.C + * Purpose: Round Robin Task switching + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "RTX_Config.h" +#include "rt_List.h" +#include "rt_Task.h" +#include "rt_Time.h" +#include "rt_Robin.h" +#ifdef __CORTEX_A9 +#include "rt_HAL_CA.h" +#else +#include "rt_HAL_CM.h" +#endif + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +struct OS_ROBIN os_robin; + + +/*---------------------------------------------------------------------------- + * Global Functions + *---------------------------------------------------------------------------*/ + +/*--------------------------- rt_init_robin ---------------------------------*/ + +__weak void rt_init_robin (void) { + /* Initialize Round Robin variables. */ + os_robin.task = NULL; + os_robin.tout = (U16)os_rrobin; +} + +/*--------------------------- rt_chk_robin ----------------------------------*/ + +__weak void rt_chk_robin (void) { + /* Check if Round Robin timeout expired and switch to the next ready task.*/ + P_TCB p_new; + + if (os_robin.task != os_rdy.p_lnk) { + /* New task was suspended, reset Round Robin timeout. */ + os_robin.task = os_rdy.p_lnk; + os_robin.time = (U16)os_time + os_robin.tout - 1; + } + if (os_robin.time == (U16)os_time) { + /* Round Robin timeout has expired, swap Robin tasks. */ + os_robin.task = NULL; + p_new = rt_get_first (&os_rdy); + rt_put_prio ((P_XCB)&os_rdy, p_new); + } +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/rt_Robin.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,45 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_ROBIN.H + * Purpose: Round Robin Task switching definitions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +/* Variables */ +extern struct OS_ROBIN os_robin; + +/* Functions */ +extern void rt_init_robin (void); +extern void rt_chk_robin (void); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/rt_Semaphore.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,191 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_SEMAPHORE.C + * Purpose: Implements binary and counting semaphores + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "RTX_Config.h" +#include "rt_System.h" +#include "rt_List.h" +#include "rt_Task.h" +#include "rt_Semaphore.h" +#ifdef __CORTEX_A9 +#include "rt_HAL_CA.h" +#else +#include "rt_HAL_CM.h" +#endif + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_sem_init -----------------------------------*/ + +void rt_sem_init (OS_ID semaphore, U16 token_count) { + /* Initialize a semaphore */ + P_SCB p_SCB = semaphore; + + p_SCB->cb_type = SCB; + p_SCB->p_lnk = NULL; + p_SCB->tokens = token_count; +} + + +/*--------------------------- rt_sem_delete ---------------------------------*/ + +#ifdef __CMSIS_RTOS +OS_RESULT rt_sem_delete (OS_ID semaphore) { + /* Delete semaphore */ + P_SCB p_SCB = semaphore; + P_TCB p_TCB; + + __DMB(); + while (p_SCB->p_lnk != NULL) { + /* A task is waiting for token */ + p_TCB = rt_get_first ((P_XCB)p_SCB); + rt_ret_val(p_TCB, 0); + rt_rmv_dly(p_TCB); + p_TCB->state = READY; + rt_put_prio (&os_rdy, p_TCB); + } + + if (os_rdy.p_lnk && (os_rdy.p_lnk->prio > os_tsk.run->prio)) { + /* preempt running task */ + rt_put_prio (&os_rdy, os_tsk.run); + os_tsk.run->state = READY; + rt_dispatch (NULL); + } + + p_SCB->cb_type = 0; + + return (OS_R_OK); +} +#endif + + +/*--------------------------- rt_sem_send -----------------------------------*/ + +OS_RESULT rt_sem_send (OS_ID semaphore) { + /* Return a token to semaphore */ + P_SCB p_SCB = semaphore; + P_TCB p_TCB; + + __DMB(); + if (p_SCB->p_lnk != NULL) { + /* A task is waiting for token */ + p_TCB = rt_get_first ((P_XCB)p_SCB); +#ifdef __CMSIS_RTOS + rt_ret_val(p_TCB, 1); +#else + rt_ret_val(p_TCB, OS_R_SEM); +#endif + rt_rmv_dly (p_TCB); + rt_dispatch (p_TCB); + } + else { + /* Store token. */ + p_SCB->tokens++; + } + return (OS_R_OK); +} + + +/*--------------------------- rt_sem_wait -----------------------------------*/ + +OS_RESULT rt_sem_wait (OS_ID semaphore, U16 timeout) { + /* Obtain a token; possibly wait for it */ + P_SCB p_SCB = semaphore; + + if (p_SCB->tokens) { + p_SCB->tokens--; + __DMB(); + return (OS_R_OK); + } + /* No token available: wait for one */ + if (timeout == 0) { + return (OS_R_TMO); + } + if (p_SCB->p_lnk != NULL) { + rt_put_prio ((P_XCB)p_SCB, os_tsk.run); + } + else { + p_SCB->p_lnk = os_tsk.run; + os_tsk.run->p_lnk = NULL; + os_tsk.run->p_rlnk = (P_TCB)p_SCB; + } + rt_block(timeout, WAIT_SEM); + return (OS_R_TMO); +} + + +/*--------------------------- isr_sem_send ----------------------------------*/ + +void isr_sem_send (OS_ID semaphore) { + /* Same function as "os_sem"send", but to be called by ISRs */ + P_SCB p_SCB = semaphore; + + rt_psq_enq (p_SCB, 0); + rt_psh_req (); +} + + +/*--------------------------- rt_sem_psh ------------------------------------*/ + +void rt_sem_psh (P_SCB p_CB) { + /* Check if task has to be waken up */ + P_TCB p_TCB; + + __DMB(); + if (p_CB->p_lnk != NULL) { + /* A task is waiting for token */ + p_TCB = rt_get_first ((P_XCB)p_CB); + rt_rmv_dly (p_TCB); + p_TCB->state = READY; +#ifdef __CMSIS_RTOS + rt_ret_val(p_TCB, 1); +#else + rt_ret_val(p_TCB, OS_R_SEM); +#endif + rt_put_prio (&os_rdy, p_TCB); + } + else { + /* Store token */ + p_CB->tokens++; + } +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/rt_Semaphore.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,46 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_SEMAPHORE.H + * Purpose: Implements binary and counting semaphores + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +/* Functions */ +extern void rt_sem_init (OS_ID semaphore, U16 token_count); +extern OS_RESULT rt_sem_delete(OS_ID semaphore); +extern OS_RESULT rt_sem_send (OS_ID semaphore); +extern OS_RESULT rt_sem_wait (OS_ID semaphore, U16 timeout); +extern void isr_sem_send (OS_ID semaphore); +extern void rt_sem_psh (P_SCB p_CB); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/rt_System.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,304 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_SYSTEM.C + * Purpose: System Task Manager + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "RTX_Config.h" +#include "rt_Task.h" +#include "rt_System.h" +#include "rt_Event.h" +#include "rt_List.h" +#include "rt_Mailbox.h" +#include "rt_Semaphore.h" +#include "rt_Time.h" +#include "rt_Timer.h" +#include "rt_Robin.h" +#ifdef __CORTEX_A9 +#include "rt_HAL_CA.h" +#else +#include "rt_HAL_CM.h" +#endif + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +int os_tick_irqn; + +/*---------------------------------------------------------------------------- + * Local Variables + *---------------------------------------------------------------------------*/ + +static volatile BIT os_lock; +static volatile BIT os_psh_flag; +#ifndef __CORTEX_A9 +static U8 pend_flags; +#endif +/*---------------------------------------------------------------------------- + * Global Functions + *---------------------------------------------------------------------------*/ + +#if defined (__CC_ARM) +__asm void $$RTX$$version (void) { + /* Export a version number symbol for a version control. */ + + EXPORT __RL_RTX_VER + +__RL_RTX_VER EQU 0x450 +} +#endif + + +/*--------------------------- rt_suspend ------------------------------------*/ + +U32 rt_suspend (void) { + /* Suspend OS scheduler */ + U32 delta = 0xFFFF; + + rt_tsk_lock(); + + if (os_dly.p_dlnk) { + delta = os_dly.delta_time; + } +#ifndef __CMSIS_RTOS + if (os_tmr.next) { + if (os_tmr.tcnt < delta) delta = os_tmr.tcnt; + } +#endif + + return (delta); +} + + +/*--------------------------- rt_resume -------------------------------------*/ + +void rt_resume (U32 sleep_time) { + /* Resume OS scheduler after suspend */ + P_TCB next; + U32 delta; + + os_tsk.run->state = READY; + rt_put_rdy_first (os_tsk.run); + + os_robin.task = NULL; + + /* Update delays. */ + if (os_dly.p_dlnk) { + delta = sleep_time; + if (delta >= os_dly.delta_time) { + delta -= os_dly.delta_time; + os_time += os_dly.delta_time; + os_dly.delta_time = 1; + while (os_dly.p_dlnk) { + rt_dec_dly(); + if (delta == 0) break; + delta--; + os_time++; + } + } else { + os_time += delta; + os_dly.delta_time -= delta; + } + } else { + os_time += sleep_time; + } + +#ifndef __CMSIS_RTOS + /* Check the user timers. */ + if (os_tmr.next) { + delta = sleep_time; + if (delta >= os_tmr.tcnt) { + delta -= os_tmr.tcnt; + os_tmr.tcnt = 1; + while (os_tmr.next) { + rt_tmr_tick(); + if (delta == 0) break; + delta--; + } + } else { + os_tmr.tcnt -= delta; + } + } +#endif + + /* Switch back to highest ready task */ + next = rt_get_first (&os_rdy); + rt_switch_req (next); + + rt_tsk_unlock(); +} + + +/*--------------------------- rt_tsk_lock -----------------------------------*/ + +void rt_tsk_lock (void) { + /* Prevent task switching by locking out scheduler */ + if (os_tick_irqn < 0) { + OS_LOCK(); + os_lock = __TRUE; + OS_UNPEND (&pend_flags); + } else { + OS_X_LOCK(os_tick_irqn); + os_lock = __TRUE; + OS_X_UNPEND (&pend_flags); + } +} + + +/*--------------------------- rt_tsk_unlock ---------------------------------*/ + +void rt_tsk_unlock (void) { + /* Unlock scheduler and re-enable task switching */ + if (os_tick_irqn < 0) { + OS_UNLOCK(); + os_lock = __FALSE; + OS_PEND (pend_flags, os_psh_flag); + os_psh_flag = __FALSE; + } else { + OS_X_UNLOCK(os_tick_irqn); + os_lock = __FALSE; + OS_X_PEND (pend_flags, os_psh_flag); + os_psh_flag = __FALSE; + } +} + + +/*--------------------------- rt_psh_req ------------------------------------*/ + +void rt_psh_req (void) { + /* Initiate a post service handling request if required. */ + if (os_lock == __FALSE) { + OS_PEND_IRQ (); + } + else { + os_psh_flag = __TRUE; + } +} + + +/*--------------------------- rt_pop_req ------------------------------------*/ + +void rt_pop_req (void) { + /* Process an ISR post service requests. */ + struct OS_XCB *p_CB; + P_TCB next; + U32 idx; + + os_tsk.run->state = READY; + rt_put_rdy_first (os_tsk.run); + + idx = os_psq->last; + while (os_psq->count) { + p_CB = os_psq->q[idx].id; + if (p_CB->cb_type == TCB) { + /* Is of TCB type */ + rt_evt_psh ((P_TCB)p_CB, (U16)os_psq->q[idx].arg); + } + else if (p_CB->cb_type == MCB) { + /* Is of MCB type */ + rt_mbx_psh ((P_MCB)p_CB, (void *)os_psq->q[idx].arg); + } + else { + /* Must be of SCB type */ + rt_sem_psh ((P_SCB)p_CB); + } + if (++idx == os_psq->size) idx = 0; + rt_dec (&os_psq->count); + } + os_psq->last = idx; + + next = rt_get_first (&os_rdy); + rt_switch_req (next); +} + + +/*--------------------------- os_tick_init ----------------------------------*/ + +__weak int os_tick_init (void) { + /* Initialize SysTick timer as system tick timer. */ + rt_systick_init (); + return (-1); /* Return IRQ number of SysTick timer */ +} + + +/*--------------------------- os_tick_irqack --------------------------------*/ + +__weak void os_tick_irqack (void) { + /* Acknowledge timer interrupt. */ +} + + +/*--------------------------- rt_systick ------------------------------------*/ + +extern void sysTimerTick(void); + +void rt_systick (void) { + /* Check for system clock update, suspend running task. */ + P_TCB next; + + os_tsk.run->state = READY; + rt_put_rdy_first (os_tsk.run); + + /* Check Round Robin timeout. */ + rt_chk_robin (); + + /* Update delays. */ + os_time++; + rt_dec_dly (); + + /* Check the user timers. */ +#ifdef __CMSIS_RTOS + sysTimerTick(); +#else + rt_tmr_tick (); +#endif + + /* Switch back to highest ready task */ + next = rt_get_first (&os_rdy); + rt_switch_req (next); +} + +/*--------------------------- rt_stk_check ----------------------------------*/ + +__weak void rt_stk_check (void) { + /* Check for stack overflow. */ + if ((os_tsk.run->tsk_stack < (U32)os_tsk.run->stack) || + (os_tsk.run->stack[0] != MAGIC_WORD)) { + os_error (OS_ERR_STK_OVF); + } +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/rt_System.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,52 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_SYSTEM.H + * Purpose: System Task Manager definitions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +/* Variables */ +#define os_psq ((P_PSQ)&os_fifo) +extern int os_tick_irqn; + +/* Functions */ +extern U32 rt_suspend (void); +extern void rt_resume (U32 sleep_time); +extern void rt_tsk_lock (void); +extern void rt_tsk_unlock (void); +extern void rt_psh_req (void); +extern void rt_pop_req (void); +extern void rt_systick (void); +extern void rt_stk_check (void); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/rt_Task.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,372 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_TASK.C + * Purpose: Task functions and system start up. + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "RTX_Config.h" +#include "rt_System.h" +#include "rt_Task.h" +#include "rt_List.h" +#include "rt_MemBox.h" +#include "rt_Robin.h" +#ifdef __CORTEX_A9 +#include "rt_HAL_CA.h" +#else +#include "rt_HAL_CM.h" +#endif + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +/* Running and next task info. */ +struct OS_TSK os_tsk; + +/* Task Control Blocks of idle demon */ +struct OS_TCB os_idle_TCB; + + +/*---------------------------------------------------------------------------- + * Local Functions + *---------------------------------------------------------------------------*/ + +static OS_TID rt_get_TID (void) { + U32 tid; + + for (tid = 1; tid <= os_maxtaskrun; tid++) { + if (os_active_TCB[tid-1] == NULL) { + return ((OS_TID)tid); + } + } + return (0); +} + + +/*--------------------------- rt_init_context -------------------------------*/ + +static void rt_init_context (P_TCB p_TCB, U8 priority, FUNCP task_body) { + /* Initialize general part of the Task Control Block. */ + p_TCB->cb_type = TCB; + p_TCB->state = READY; + p_TCB->prio = priority; + p_TCB->p_lnk = NULL; + p_TCB->p_rlnk = NULL; + p_TCB->p_dlnk = NULL; + p_TCB->p_blnk = NULL; + p_TCB->delta_time = 0; + p_TCB->interval_time = 0; + p_TCB->events = 0; + p_TCB->waits = 0; + p_TCB->stack_frame = 0; + + if (p_TCB->priv_stack == 0) { + /* Allocate the memory space for the stack. */ + p_TCB->stack = rt_alloc_box (mp_stk); + } + rt_init_stack (p_TCB, task_body); +} + + +/*--------------------------- rt_switch_req ---------------------------------*/ + +void rt_switch_req (P_TCB p_new) { + /* Switch to next task (identified by "p_new"). */ + os_tsk.new = p_new; + p_new->state = RUNNING; + DBG_TASK_SWITCH(p_new->task_id); +} + + +/*--------------------------- rt_dispatch -----------------------------------*/ + +void rt_dispatch (P_TCB next_TCB) { + /* Dispatch next task if any identified or dispatch highest ready task */ + /* "next_TCB" identifies a task to run or has value NULL (=no next task) */ + if (next_TCB == NULL) { + /* Running task was blocked: continue with highest ready task */ + next_TCB = rt_get_first (&os_rdy); + rt_switch_req (next_TCB); + } + else { + /* Check which task continues */ + if (next_TCB->prio > os_tsk.run->prio) { + /* preempt running task */ + rt_put_rdy_first (os_tsk.run); + os_tsk.run->state = READY; + rt_switch_req (next_TCB); + } + else { + /* put next task into ready list, no task switch takes place */ + next_TCB->state = READY; + rt_put_prio (&os_rdy, next_TCB); + } + } +} + + +/*--------------------------- rt_block --------------------------------------*/ + +void rt_block (U16 timeout, U8 block_state) { + /* Block running task and choose next ready task. */ + /* "timeout" sets a time-out value or is 0xffff (=no time-out). */ + /* "block_state" defines the appropriate task state */ + P_TCB next_TCB; + + if (timeout) { + if (timeout < 0xffff) { + rt_put_dly (os_tsk.run, timeout); + } + os_tsk.run->state = block_state; + next_TCB = rt_get_first (&os_rdy); + rt_switch_req (next_TCB); + } +} + + +/*--------------------------- rt_tsk_pass -----------------------------------*/ + +void rt_tsk_pass (void) { + /* Allow tasks of same priority level to run cooperatively.*/ + P_TCB p_new; + + p_new = rt_get_same_rdy_prio(); + if (p_new != NULL) { + rt_put_prio ((P_XCB)&os_rdy, os_tsk.run); + os_tsk.run->state = READY; + rt_switch_req (p_new); + } +} + + +/*--------------------------- rt_tsk_self -----------------------------------*/ + +OS_TID rt_tsk_self (void) { + /* Return own task identifier value. */ + if (os_tsk.run == NULL) { + return (0); + } + return (os_tsk.run->task_id); +} + + +/*--------------------------- rt_tsk_prio -----------------------------------*/ + +OS_RESULT rt_tsk_prio (OS_TID task_id, U8 new_prio) { + /* Change execution priority of a task to "new_prio". */ + P_TCB p_task; + + if (task_id == 0) { + /* Change execution priority of calling task. */ + os_tsk.run->prio = new_prio; +run:if (rt_rdy_prio() > new_prio) { + rt_put_prio (&os_rdy, os_tsk.run); + os_tsk.run->state = READY; + rt_dispatch (NULL); + } + return (OS_R_OK); + } + + /* Find the task in the "os_active_TCB" array. */ + if (task_id > os_maxtaskrun || os_active_TCB[task_id-1] == NULL) { + /* Task with "task_id" not found or not started. */ + return (OS_R_NOK); + } + p_task = os_active_TCB[task_id-1]; + p_task->prio = new_prio; + if (p_task == os_tsk.run) { + goto run; + } + rt_resort_prio (p_task); + if (p_task->state == READY) { + /* Task enqueued in a ready list. */ + p_task = rt_get_first (&os_rdy); + rt_dispatch (p_task); + } + return (OS_R_OK); +} + + +/*--------------------------- rt_tsk_create ---------------------------------*/ + +OS_TID rt_tsk_create (FUNCP task, U32 prio_stksz, void *stk, void *argv) { + /* Start a new task declared with "task". */ + P_TCB task_context; + U32 i; + + /* Priority 0 is reserved for idle task! */ + if ((prio_stksz & 0xFF) == 0) { + prio_stksz += 1; + } + task_context = rt_alloc_box (mp_tcb); + if (task_context == NULL) { + return (0); + } + /* If "size != 0" use a private user provided stack. */ + task_context->stack = stk; + task_context->priv_stack = prio_stksz >> 8; + /* Pass parameter 'argv' to 'rt_init_context' */ + task_context->msg = argv; + /* For 'size == 0' system allocates the user stack from the memory pool. */ + rt_init_context (task_context, prio_stksz & 0xFF, task); + + /* Find a free entry in 'os_active_TCB' table. */ + i = rt_get_TID (); + os_active_TCB[i-1] = task_context; + task_context->task_id = i; + DBG_TASK_NOTIFY(task_context, __TRUE); + rt_dispatch (task_context); + return ((OS_TID)i); +} + + +/*--------------------------- rt_tsk_delete ---------------------------------*/ + +OS_RESULT rt_tsk_delete (OS_TID task_id) { + /* Terminate the task identified with "task_id". */ + P_TCB task_context; + + if (task_id == 0 || task_id == os_tsk.run->task_id) { + /* Terminate itself. */ + os_tsk.run->state = INACTIVE; + os_tsk.run->tsk_stack = rt_get_PSP (); + rt_stk_check (); + os_active_TCB[os_tsk.run->task_id-1] = NULL; + rt_free_box (mp_stk, os_tsk.run->stack); + os_tsk.run->stack = NULL; + DBG_TASK_NOTIFY(os_tsk.run, __FALSE); + rt_free_box (mp_tcb, os_tsk.run); + os_tsk.run = NULL; + rt_dispatch (NULL); + /* The program should never come to this point. */ + } + else { + /* Find the task in the "os_active_TCB" array. */ + if (task_id > os_maxtaskrun || os_active_TCB[task_id-1] == NULL) { + /* Task with "task_id" not found or not started. */ + return (OS_R_NOK); + } + task_context = os_active_TCB[task_id-1]; + rt_rmv_list (task_context); + rt_rmv_dly (task_context); + os_active_TCB[task_id-1] = NULL; + rt_free_box (mp_stk, task_context->stack); + task_context->stack = NULL; + DBG_TASK_NOTIFY(task_context, __FALSE); + rt_free_box (mp_tcb, task_context); + } + return (OS_R_OK); +} + + +/*--------------------------- rt_sys_init -----------------------------------*/ + +#ifdef __CMSIS_RTOS +void rt_sys_init (void) { +#else +void rt_sys_init (FUNCP first_task, U32 prio_stksz, void *stk) { +#endif + /* Initialize system and start up task declared with "first_task". */ + U32 i; + + DBG_INIT(); + + /* Initialize dynamic memory and task TCB pointers to NULL. */ + for (i = 0; i < os_maxtaskrun; i++) { + os_active_TCB[i] = NULL; + } + rt_init_box (&mp_tcb, mp_tcb_size, sizeof(struct OS_TCB)); + rt_init_box (&mp_stk, mp_stk_size, BOX_ALIGN_8 | (U16)(os_stackinfo)); + rt_init_box ((U32 *)m_tmr, mp_tmr_size, sizeof(struct OS_TMR)); + + /* Set up TCB of idle demon */ + os_idle_TCB.task_id = 255; + os_idle_TCB.priv_stack = 0; + rt_init_context (&os_idle_TCB, 0, os_idle_demon); + + /* Set up ready list: initially empty */ + os_rdy.cb_type = HCB; + os_rdy.p_lnk = NULL; + /* Set up delay list: initially empty */ + os_dly.cb_type = HCB; + os_dly.p_dlnk = NULL; + os_dly.p_blnk = NULL; + os_dly.delta_time = 0; + + /* Fix SP and system variables to assume idle task is running */ + /* Transform main program into idle task by assuming idle TCB */ +#ifndef __CMSIS_RTOS + rt_set_PSP (os_idle_TCB.tsk_stack+32); +#endif + os_tsk.run = &os_idle_TCB; + os_tsk.run->state = RUNNING; + + /* Initialize ps queue */ + os_psq->first = 0; + os_psq->last = 0; + os_psq->size = os_fifo_size; + + rt_init_robin (); + + /* Initialize SVC and PendSV */ + rt_svc_init (); + +#ifndef __CMSIS_RTOS + /* Initialize and start system clock timer */ + os_tick_irqn = os_tick_init (); + if (os_tick_irqn >= 0) { + OS_X_INIT(os_tick_irqn); + } + + /* Start up first user task before entering the endless loop */ + rt_tsk_create (first_task, prio_stksz, stk, NULL); +#endif +} + + +/*--------------------------- rt_sys_start ----------------------------------*/ + +#ifdef __CMSIS_RTOS +void rt_sys_start (void) { + /* Start system */ + + /* Initialize and start system clock timer */ + os_tick_irqn = os_tick_init (); + if (os_tick_irqn >= 0) { + OS_X_INIT(os_tick_irqn); + } +} +#endif + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/rt_Task.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,87 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_TASK.H + * Purpose: Task functions and system start up. + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +/* Definitions */ + +/* Values for 'state' */ +#define INACTIVE 0 +#define READY 1 +#define RUNNING 2 +#define WAIT_DLY 3 +#define WAIT_ITV 4 +#define WAIT_OR 5 +#define WAIT_AND 6 +#define WAIT_SEM 7 +#define WAIT_MBX 8 +#define WAIT_MUT 9 + +/* Return codes */ +#define OS_R_TMO 0x01 +#define OS_R_EVT 0x02 +#define OS_R_SEM 0x03 +#define OS_R_MBX 0x04 +#define OS_R_MUT 0x05 + +#define OS_R_OK 0x00 +#define OS_R_NOK 0xff + +/* Variables */ +extern struct OS_TSK os_tsk; +extern struct OS_TCB os_idle_TCB; + +/* Functions */ +extern void rt_switch_req (P_TCB p_new); +extern void rt_dispatch (P_TCB next_TCB); +extern void rt_block (U16 timeout, U8 block_state); +extern void rt_tsk_pass (void); +extern OS_TID rt_tsk_self (void); +extern OS_RESULT rt_tsk_prio (OS_TID task_id, U8 new_prio); +extern OS_TID rt_tsk_create (FUNCP task, U32 prio_stksz, void *stk, void *argv); +extern OS_RESULT rt_tsk_delete (OS_TID task_id); +#ifdef __CMSIS_RTOS +extern void rt_sys_init (void); +extern void rt_sys_start (void); +#else +extern void rt_sys_init (FUNCP first_task, U32 prio_stksz, void *stk); +#endif + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/rt_Time.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,94 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_TIME.C + * Purpose: Delay and interval wait functions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "RTX_Config.h" +#include "rt_Task.h" +#include "rt_Time.h" + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +/* Free running system tick counter */ +U32 os_time; + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_time_get -----------------------------------*/ + +U32 rt_time_get (void) { + /* Get system time tick */ + return (os_time); +} + + +/*--------------------------- rt_dly_wait -----------------------------------*/ + +void rt_dly_wait (U16 delay_time) { + /* Delay task by "delay_time" */ + rt_block (delay_time, WAIT_DLY); +} + + +/*--------------------------- rt_itv_set ------------------------------------*/ + +void rt_itv_set (U16 interval_time) { + /* Set interval length and define start of first interval */ + os_tsk.run->interval_time = interval_time; + os_tsk.run->delta_time = interval_time + (U16)os_time; +} + + +/*--------------------------- rt_itv_wait -----------------------------------*/ + +void rt_itv_wait (void) { + /* Wait for interval end and define start of next one */ + U16 delta; + + delta = os_tsk.run->delta_time - (U16)os_time; + os_tsk.run->delta_time += os_tsk.run->interval_time; + if ((delta & 0x8000) == 0) { + rt_block (delta, WAIT_ITV); + } +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/rt_Time.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,47 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_TIME.H + * Purpose: Delay and interval wait functions definitions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +/* Variables */ +extern U32 os_time; + +/* Functions */ +extern U32 rt_time_get (void); +extern void rt_dly_wait (U16 delay_time); +extern void rt_itv_set (U16 interval_time); +extern void rt_itv_wait (void); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/rt_Timer.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,129 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_TIMER.C + * Purpose: User timer functions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "RTX_Config.h" +#include "rt_Timer.h" +#include "rt_MemBox.h" + + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +/* User Timer list pointer */ +struct OS_XTMR os_tmr; + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + +/*--------------------------- rt_tmr_tick -----------------------------------*/ + +void rt_tmr_tick (void) { + /* Decrement delta count of timer list head. Timers having the value of */ + /* zero are removed from the list and the callback function is called. */ + P_TMR p; + + if (os_tmr.next == NULL) { + return; + } + os_tmr.tcnt--; + while (os_tmr.tcnt == 0 && (p = os_tmr.next) != NULL) { + /* Call a user provided function to handle an elapsed timer */ + os_tmr_call (p->info); + os_tmr.tcnt = p->tcnt; + os_tmr.next = p->next; + rt_free_box ((U32 *)m_tmr, p); + } +} + +/*--------------------------- rt_tmr_create ---------------------------------*/ + +OS_ID rt_tmr_create (U16 tcnt, U16 info) { + /* Create an user timer and put it into the chained timer list using */ + /* a timeout count value of "tcnt". User parameter "info" is used as a */ + /* parameter for the user provided callback function "os_tmr_call ()". */ + P_TMR p_tmr, p; + U32 delta,itcnt = tcnt; + + if (tcnt == 0 || m_tmr == NULL) { + return (NULL); + } + p_tmr = rt_alloc_box ((U32 *)m_tmr); + if (!p_tmr) { + return (NULL); + } + p_tmr->info = info; + p = (P_TMR)&os_tmr; + delta = p->tcnt; + while (delta < itcnt && p->next != NULL) { + p = p->next; + delta += p->tcnt; + } + /* Right place found, insert timer into the list */ + p_tmr->next = p->next; + p_tmr->tcnt = (U16)(delta - itcnt); + p->next = p_tmr; + p->tcnt -= p_tmr->tcnt; + return (p_tmr); +} + +/*--------------------------- rt_tmr_kill -----------------------------------*/ + +OS_ID rt_tmr_kill (OS_ID timer) { + /* Remove user timer from the chained timer list. */ + P_TMR p, p_tmr; + + p_tmr = (P_TMR)timer; + p = (P_TMR)&os_tmr; + /* Search timer list for requested timer */ + while (p->next != p_tmr) { + if (p->next == NULL) { + /* Failed, "timer" is not in the timer list */ + return (p_tmr); + } + p = p->next; + } + /* Timer was found, remove it from the list */ + p->next = p_tmr->next; + p->tcnt += p_tmr->tcnt; + rt_free_box ((U32 *)m_tmr, p_tmr); + /* Timer killed */ + return (NULL); +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/rt_Timer.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,46 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_TIMER.H + * Purpose: User timer functions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +/* Variables */ +extern struct OS_XTMR os_tmr; + +/* Functions */ +extern void rt_tmr_tick (void); +extern OS_ID rt_tmr_create (U16 tcnt, U16 info); +extern OS_ID rt_tmr_kill (OS_ID timer); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_A/rt_TypeDef.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,167 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_TYPEDEF.H + * Purpose: Type Definitions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +/* Types */ +typedef char S8; +typedef unsigned char U8; +typedef short S16; +typedef unsigned short U16; +typedef int S32; +typedef unsigned int U32; +typedef long long S64; +typedef unsigned long long U64; +typedef unsigned char BIT; +typedef unsigned int BOOL; +typedef void (*FUNCP)(void); + +typedef U32 OS_TID; +typedef void *OS_ID; +typedef U32 OS_RESULT; + +typedef struct OS_TCB { + /* General part: identical for all implementations. */ + U8 cb_type; /* Control Block Type */ + U8 state; /* Task state */ + U8 prio; /* Execution priority */ + U8 task_id; /* Task ID value for optimized TCB access */ + struct OS_TCB *p_lnk; /* Link pointer for ready/sem. wait list */ + struct OS_TCB *p_rlnk; /* Link pointer for sem./mbx lst backwards */ + struct OS_TCB *p_dlnk; /* Link pointer for delay list */ + struct OS_TCB *p_blnk; /* Link pointer for delay list backwards */ + U16 delta_time; /* Time until time out */ + U16 interval_time; /* Time interval for periodic waits */ + U16 events; /* Event flags */ + U16 waits; /* Wait flags */ + void **msg; /* Direct message passing when task waits */ + + /* Hardware dependant part: specific for Cortex processor */ + U8 stack_frame; /* Stack frame: 0x1 Basic/Extended, 0x2 FP stacked/not stacked */ + U8 reserved; + U16 priv_stack; /* Private stack size, 0= system assigned */ + U32 tsk_stack; /* Current task Stack pointer (R13) */ + U32 *stack; /* Pointer to Task Stack memory block */ + + /* Task entry point used for uVision debugger */ + FUNCP ptask; /* Task entry address */ +} *P_TCB; +#define TCB_TID 3 /* 'task id' offset */ +#define TCB_STACKF 32 /* 'stack_frame' offset */ +#define TCB_TSTACK 36 /* 'tsk_stack' offset */ + +typedef struct OS_PSFE { /* Post Service Fifo Entry */ + void *id; /* Object Identification */ + U32 arg; /* Object Argument */ +} *P_PSFE; + +typedef struct OS_PSQ { /* Post Service Queue */ + U8 first; /* FIFO Head Index */ + U8 last; /* FIFO Tail Index */ + U8 count; /* Number of stored items in FIFO */ + U8 size; /* FIFO Size */ + struct OS_PSFE q[1]; /* FIFO Content */ +} *P_PSQ; + +typedef struct OS_TSK { + P_TCB run; /* Current running task */ + P_TCB new; /* Scheduled task to run */ +} *P_TSK; + +typedef struct OS_ROBIN { /* Round Robin Control */ + P_TCB task; /* Round Robin task */ + U16 time; /* Round Robin switch time */ + U16 tout; /* Round Robin timeout */ +} *P_ROBIN; + +typedef struct OS_XCB { + U8 cb_type; /* Control Block Type */ + struct OS_TCB *p_lnk; /* Link pointer for ready/sem. wait list */ + struct OS_TCB *p_rlnk; /* Link pointer for sem./mbx lst backwards */ + struct OS_TCB *p_dlnk; /* Link pointer for delay list */ + struct OS_TCB *p_blnk; /* Link pointer for delay list backwards */ + U16 delta_time; /* Time until time out */ +} *P_XCB; + +typedef struct OS_MCB { + U8 cb_type; /* Control Block Type */ + U8 state; /* State flag variable */ + U8 isr_st; /* State flag variable for isr functions */ + struct OS_TCB *p_lnk; /* Chain of tasks waiting for message */ + U16 first; /* Index of the message list begin */ + U16 last; /* Index of the message list end */ + U16 count; /* Actual number of stored messages */ + U16 size; /* Maximum number of stored messages */ + void *msg[1]; /* FIFO for Message pointers 1st element */ +} *P_MCB; + +typedef struct OS_SCB { + U8 cb_type; /* Control Block Type */ + U8 mask; /* Semaphore token mask */ + U16 tokens; /* Semaphore tokens */ + struct OS_TCB *p_lnk; /* Chain of tasks waiting for tokens */ +} *P_SCB; + +typedef struct OS_MUCB { + U8 cb_type; /* Control Block Type */ + U8 prio; /* Owner task default priority */ + U16 level; /* Call nesting level */ + struct OS_TCB *p_lnk; /* Chain of tasks waiting for mutex */ + struct OS_TCB *owner; /* Mutex owner task */ +} *P_MUCB; + +typedef struct OS_XTMR { + struct OS_TMR *next; + U16 tcnt; +} *P_XTMR; + +typedef struct OS_TMR { + struct OS_TMR *next; /* Link pointer to Next timer */ + U16 tcnt; /* Timer delay count */ + U16 info; /* User defined call info */ +} *P_TMR; + +typedef struct OS_BM { + void *free; /* Pointer to first free memory block */ + void *end; /* Pointer to memory block end */ + U32 blk_size; /* Memory block size */ +} *P_BM; + +/* Definitions */ +#define __TRUE 1 +#define __FALSE 0 +#define NULL ((void *) 0) + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/HAL_CM.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,170 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: HAL_CM.C + * Purpose: Hardware Abstraction Layer for Cortex-M + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_HAL_CM.h" + + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +#ifdef DBG_MSG +BIT dbg_msg; +#endif + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_init_stack ---------------------------------*/ + +void rt_init_stack (P_TCB p_TCB, FUNCP task_body) { + /* Prepare TCB and saved context for a first time start of a task. */ + U32 *stk,i,size; + + /* Prepare a complete interrupt frame for first task start */ + size = p_TCB->priv_stack >> 2; + + /* Write to the top of stack. */ + stk = &p_TCB->stack[size]; + + /* Auto correct to 8-byte ARM stack alignment. */ + if ((U32)stk & 0x04) { + stk--; + } + + stk -= 16; + + /* Default xPSR and initial PC */ + stk[15] = INITIAL_xPSR; + stk[14] = (U32)task_body; + + /* Clear R4-R11,R0-R3,R12,LR registers. */ + for (i = 0; i < 14; i++) { + stk[i] = 0; + } + + /* Assign a void pointer to R0. */ + stk[8] = (U32)p_TCB->msg; + + /* Initial Task stack pointer. */ + p_TCB->tsk_stack = (U32)stk; + + /* Task entry point. */ + p_TCB->ptask = task_body; + + /* Set a magic word for checking of stack overflow. + For the main thread (ID: 0x01) the stack is in a memory area shared with the + heap, therefore the last word of the stack is a moving target. + We want to do stack/heap collision detection instead. + */ + if (p_TCB->task_id != 0x01) + p_TCB->stack[0] = MAGIC_WORD; +} + + +/*--------------------------- rt_ret_val ----------------------------------*/ + +static __inline U32 *rt_ret_regs (P_TCB p_TCB) { + /* Get pointer to task return value registers (R0..R3) in Stack */ +#if (__TARGET_FPU_VFP) + if (p_TCB->stack_frame) { + /* Extended Stack Frame: R4-R11,S16-S31,R0-R3,R12,LR,PC,xPSR,S0-S15,FPSCR */ + return (U32 *)(p_TCB->tsk_stack + 8*4 + 16*4); + } else { + /* Basic Stack Frame: R4-R11,R0-R3,R12,LR,PC,xPSR */ + return (U32 *)(p_TCB->tsk_stack + 8*4); + } +#else + /* Stack Frame: R4-R11,R0-R3,R12,LR,PC,xPSR */ + return (U32 *)(p_TCB->tsk_stack + 8*4); +#endif +} + +void rt_ret_val (P_TCB p_TCB, U32 v0) { + U32 *ret; + + ret = rt_ret_regs(p_TCB); + ret[0] = v0; +} + +void rt_ret_val2(P_TCB p_TCB, U32 v0, U32 v1) { + U32 *ret; + + ret = rt_ret_regs(p_TCB); + ret[0] = v0; + ret[1] = v1; +} + + +/*--------------------------- dbg_init --------------------------------------*/ + +#ifdef DBG_MSG +void dbg_init (void) { + if ((DEMCR & DEMCR_TRCENA) && + (ITM_CONTROL & ITM_ITMENA) && + (ITM_ENABLE & (1UL << 31))) { + dbg_msg = __TRUE; + } +} +#endif + +/*--------------------------- dbg_task_notify -------------------------------*/ + +#ifdef DBG_MSG +void dbg_task_notify (P_TCB p_tcb, BOOL create) { + while (ITM_PORT31_U32 == 0); + ITM_PORT31_U32 = (U32)p_tcb->ptask; + while (ITM_PORT31_U32 == 0); + ITM_PORT31_U16 = (create << 8) | p_tcb->task_id; +} +#endif + +/*--------------------------- dbg_task_switch -------------------------------*/ + +#ifdef DBG_MSG +void dbg_task_switch (U32 task_id) { + while (ITM_PORT31_U32 == 0); + ITM_PORT31_U8 = task_id; +} +#endif + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/RTX_CM_lib.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,453 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RTX_CM_LIB.H + * Purpose: RTX Kernel System Configuration + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ +#include "mbed_error.h" + +#if defined (__CC_ARM) +#pragma O3 +#define __USED __attribute__((used)) +#elif defined (__GNUC__) +#pragma GCC optimize ("O3") +#define __USED __attribute__((used)) +#elif defined (__ICCARM__) +#define __USED __root +#endif + + +/*---------------------------------------------------------------------------- + * Definitions + *---------------------------------------------------------------------------*/ + +#define _declare_box(pool,size,cnt) uint32_t pool[(((size)+3)/4)*(cnt) + 3] +#define _declare_box8(pool,size,cnt) uint64_t pool[(((size)+7)/8)*(cnt) + 2] + +#define OS_TCB_SIZE 48 +#define OS_TMR_SIZE 8 + +#if defined (__CC_ARM) && !defined (__MICROLIB) + +typedef void *OS_ID; +typedef uint32_t OS_TID; +typedef uint32_t OS_MUT[3]; +typedef uint32_t OS_RESULT; + +#define runtask_id() rt_tsk_self() +#define mutex_init(m) rt_mut_init(m) +#define mutex_wait(m) os_mut_wait(m,0xFFFF) +#define mutex_rel(m) os_mut_release(m) + +extern OS_TID rt_tsk_self (void); +extern void rt_mut_init (OS_ID mutex); +extern OS_RESULT rt_mut_release (OS_ID mutex); +extern OS_RESULT rt_mut_wait (OS_ID mutex, uint16_t timeout); + +#define os_mut_wait(mutex,timeout) _os_mut_wait((uint32_t)rt_mut_wait,mutex,timeout) +#define os_mut_release(mutex) _os_mut_release((uint32_t)rt_mut_release,mutex) + +OS_RESULT _os_mut_release (uint32_t p, OS_ID mutex) __svc_indirect(0); +OS_RESULT _os_mut_wait (uint32_t p, OS_ID mutex, uint16_t timeout) __svc_indirect(0); + +#endif + + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +#if (OS_TIMERS != 0) +#define OS_TASK_CNT (OS_TASKCNT + 1) +#else +#define OS_TASK_CNT OS_TASKCNT +#endif + +uint16_t const os_maxtaskrun = OS_TASK_CNT; +uint32_t const os_rrobin = (OS_ROBIN << 16) | OS_ROBINTOUT; +uint32_t const os_trv = OS_TRV; +uint8_t const os_flags = OS_RUNPRIV; + +/* Export following defines to uVision debugger. */ +__USED uint32_t const os_clockrate = OS_TICK; +__USED uint32_t const os_timernum = 0; + +/* Stack for the os_idle_demon */ +unsigned int idle_task_stack[OS_IDLESTKSIZE]; +unsigned short const idle_task_stack_size = OS_IDLESTKSIZE; + +#ifndef OS_FIFOSZ + #define OS_FIFOSZ 16 +#endif + +/* Fifo Queue buffer for ISR requests.*/ +uint32_t os_fifo[OS_FIFOSZ*2+1]; +uint8_t const os_fifo_size = OS_FIFOSZ; + +/* An array of Active task pointers. */ +void *os_active_TCB[OS_TASK_CNT]; + +/* User Timers Resources */ +#if (OS_TIMERS != 0) +extern void osTimerThread (void const *argument); +osThreadDef(osTimerThread, (osPriority)(OS_TIMERPRIO-3), 4*OS_TIMERSTKSZ); +osThreadId osThreadId_osTimerThread; +osMessageQDef(osTimerMessageQ, OS_TIMERCBQS, void *); +osMessageQId osMessageQId_osTimerMessageQ; +#else +osThreadDef_t os_thread_def_osTimerThread = { NULL }; +osThreadId osThreadId_osTimerThread; +osMessageQDef(osTimerMessageQ, 0, void *); +osMessageQId osMessageQId_osTimerMessageQ; +#endif + + +/*---------------------------------------------------------------------------- + * RTX Optimizations (empty functions) + *---------------------------------------------------------------------------*/ + +#if OS_ROBIN == 0 + void rt_init_robin (void) {;} + void rt_chk_robin (void) {;} +#endif + +#if OS_STKCHECK == 0 + void rt_stk_check (void) {;} +#endif + + +/*---------------------------------------------------------------------------- + * Standard Library multithreading interface + *---------------------------------------------------------------------------*/ + +#if defined (__CC_ARM) && !defined (__MICROLIB) + static OS_MUT std_libmutex[OS_MUTEXCNT]; + static uint32_t nr_mutex; + + /*--------------------------- _mutex_initialize -----------------------------*/ + +int _mutex_initialize (OS_ID *mutex) { + /* Allocate and initialize a system mutex. */ + + if (nr_mutex >= OS_MUTEXCNT) { + /* If you are here, you need to increase the number OS_MUTEXCNT. */ + error("Not enough stdlib mutexes\n"); + } + *mutex = &std_libmutex[nr_mutex++]; + mutex_init (*mutex); + return (1); +} + + +/*--------------------------- _mutex_acquire --------------------------------*/ + +__attribute__((used)) void _mutex_acquire (OS_ID *mutex) { + /* Acquire a system mutex, lock stdlib resources. */ + if (runtask_id ()) { + /* RTX running, acquire a mutex. */ + mutex_wait (*mutex); + } +} + + +/*--------------------------- _mutex_release --------------------------------*/ + +__attribute__((used)) void _mutex_release (OS_ID *mutex) { + /* Release a system mutex, unlock stdlib resources. */ + if (runtask_id ()) { + /* RTX running, release a mutex. */ + mutex_rel (*mutex); + } +} + +#endif + + +/*---------------------------------------------------------------------------- + * RTX Startup + *---------------------------------------------------------------------------*/ + +/* Main Thread definition */ +extern int main (void); +osThreadDef_t os_thread_def_main = {(os_pthread)main, osPriorityNormal, 0, NULL}; + +// This define should be probably moved to the CMSIS layer +#if defined(TARGET_LPC1768) +#define INITIAL_SP (0x10008000UL) + +#elif defined(TARGET_LPC11U24) +#define INITIAL_SP (0x10002000UL) + +#elif defined(TARGET_LPC11U35_401) || defined(TARGET_LPC11U35_501) || defined(TARGET_LPCCAPPUCCINO) +#define INITIAL_SP (0x10002000UL) + +#elif defined(TARGET_LPC1114) +#define INITIAL_SP (0x10001000UL) + +#elif defined(TARGET_LPC812) +#define INITIAL_SP (0x10001000UL) + +#elif defined(TARGET_LPC824) +#define INITIAL_SP (0x10002000UL) + +#elif defined(TARGET_KL25Z) +#define INITIAL_SP (0x20003000UL) + +#elif defined(TARGET_K64F) +#define INITIAL_SP (0x20030000UL) + +#elif defined(TARGET_KL46Z) +#define INITIAL_SP (0x20006000UL) + +#elif defined(TARGET_KL43Z) +#define INITIAL_SP (0x20006000UL) + +#elif defined(TARGET_KL05Z) +#define INITIAL_SP (0x20000C00UL) + +#elif defined(TARGET_LPC4088) +#define INITIAL_SP (0x10010000UL) + +#elif defined(TARGET_LPC4337) +#define INITIAL_SP (0x10008000UL) + +#elif defined(TARGET_LPC1347) +#define INITIAL_SP (0x10002000UL) + +#elif defined(TARGET_STM32F100RB) || defined(TARGET_STM32F051R8) +#define INITIAL_SP (0x20002000UL) + +#elif defined(TARGET_DISCO_F303VC) +#define INITIAL_SP (0x2000A000UL) + +#elif defined(TARGET_STM32F407) || defined(TARGET_F407VG) +#define INITIAL_SP (0x20020000UL) + +#elif defined(TARGET_STM32F401RE) +#define INITIAL_SP (0x20018000UL) + +#elif defined(TARGET_LPC1549) +#define INITIAL_SP (0x02009000UL) + +#elif defined(TARGET_LPC11U68) +#define INITIAL_SP (0x10004000UL) + +#elif defined(TARGET_NRF51822) +#define INITIAL_SP (0x20004000UL) + +#elif defined(TARGET_STM32F411RE) +#define INITIAL_SP (0x20020000UL) + +#elif defined(TARGET_STM32F103RB) +#define INITIAL_SP (0x20005000UL) + +#elif defined(TARGET_STM32F302R8) +#define INITIAL_SP (0x20004000UL) + +#elif defined(TARGET_STM32F334R8) +#define INITIAL_SP (0x20003000UL) + +#elif defined(TARGET_STM32F334C8) +#define INITIAL_SP (0x20003000UL) + +#else +#error "no target defined" + +#endif + +#ifdef __CC_ARM +extern unsigned char Image$$RW_IRAM1$$ZI$$Limit[]; +#define HEAP_START (Image$$RW_IRAM1$$ZI$$Limit) +#elif defined(__GNUC__) +extern unsigned char __end__[]; +#define HEAP_START (__end__) +#endif + +void set_main_stack(void) { + // That is the bottom of the main stack block: no collision detection + os_thread_def_main.stack_pointer = HEAP_START; + + // Leave OS_SCHEDULERSTKSIZE words for the scheduler and interrupts + os_thread_def_main.stacksize = (INITIAL_SP - (unsigned int)HEAP_START) - (OS_SCHEDULERSTKSIZE * 4); +} + +#if defined (__CC_ARM) +#ifdef __MICROLIB +void _main_init (void) __attribute__((section(".ARM.Collect$$$$000000FF"))); +void _main_init (void) { + osKernelInitialize(); + set_main_stack(); + osThreadCreate(&os_thread_def_main, NULL); + osKernelStart(); + for (;;); +} +#else + +/* The single memory model is checking for stack collision at run time, verifing + that the heap pointer is underneath the stack pointer. + + With the RTOS there is not only one stack above the heap, there are multiple + stacks and some of them are underneath the heap pointer. +*/ +#pragma import(__use_two_region_memory) + +__asm void __rt_entry (void) { + + IMPORT __user_setup_stackheap + IMPORT __rt_lib_init + IMPORT os_thread_def_main + IMPORT osKernelInitialize + IMPORT set_main_stack + IMPORT osKernelStart + IMPORT osThreadCreate + IMPORT exit + + BL __user_setup_stackheap + MOV R1,R2 + BL __rt_lib_init + BL osKernelInitialize + BL set_main_stack + LDR R0,=os_thread_def_main + MOVS R1,#0 + BL osThreadCreate + BL osKernelStart + BL exit + + ALIGN +} +#endif + +#elif defined (__GNUC__) + +#ifdef __CS3__ + +/* CS3 start_c routine. + * + * Copyright (c) 2006, 2007 CodeSourcery Inc + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +#include "cs3.h" + +extern void __libc_init_array (void); + +__attribute ((noreturn)) void __cs3_start_c (void){ + unsigned regions = __cs3_region_num; + const struct __cs3_region *rptr = __cs3_regions; + + /* Initialize memory */ + for (regions = __cs3_region_num, rptr = __cs3_regions; regions--; rptr++) { + long long *src = (long long *)rptr->init; + long long *dst = (long long *)rptr->data; + unsigned limit = rptr->init_size; + unsigned count; + + if (src != dst) + for (count = 0; count != limit; count += sizeof (long long)) + *dst++ = *src++; + else + dst = (long long *)((char *)dst + limit); + limit = rptr->zero_size; + for (count = 0; count != limit; count += sizeof (long long)) + *dst++ = 0; + } + + /* Run initializers. */ + __libc_init_array (); + + osKernelInitialize(); + set_main_stack(); + osThreadCreate(&os_thread_def_main, NULL); + osKernelStart(); + for (;;); +} + +#else + +__attribute__((naked)) void software_init_hook (void) { + __asm ( + ".syntax unified\n" + ".thumb\n" + "movs r0,#0\n" + "movs r1,#0\n" + "mov r4,r0\n" + "mov r5,r1\n" + "ldr r0,= __libc_fini_array\n" + "bl atexit\n" + "bl __libc_init_array\n" + "mov r0,r4\n" + "mov r1,r5\n" + "bl osKernelInitialize\n" + "bl set_main_stack\n" + "ldr r0,=os_thread_def_main\n" + "movs r1,#0\n" + "bl osThreadCreate\n" + "bl osKernelStart\n" + "bl exit\n" + ); +} + +#endif + +#elif defined (__ICCARM__) + +extern int __low_level_init(void); +extern void __iar_data_init3(void); +extern void exit(int arg); + +__noreturn __stackless void __cmain(void) { + int a; + + if (__low_level_init() != 0) { + __iar_data_init3(); + } + osKernelInitialize(); + osThreadCreate(&os_thread_def_main, NULL); + a = osKernelStart(); + exit(a); +} + +#endif + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/RTX_Conf.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,72 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RTX_CONFIG.H + * Purpose: Exported functions of RTX_Config.c + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + + +/* Error Codes */ +#define OS_ERR_STK_OVF 1 +#define OS_ERR_FIFO_OVF 2 +#define OS_ERR_MBX_OVF 3 + +/* Definitions */ +#define BOX_ALIGN_8 0x80000000 +#define _declare_box(pool,size,cnt) U32 pool[(((size)+3)/4)*(cnt) + 3] +#define _declare_box8(pool,size,cnt) U64 pool[(((size)+7)/8)*(cnt) + 2] +#define _init_box8(pool,size,bsize) _init_box (pool,size,(bsize) | BOX_ALIGN_8) + +/* Variables */ +extern U32 idle_task_stack[]; +extern U32 os_fifo[]; +extern void *os_active_TCB[]; + +/* Constants */ +extern U16 const os_maxtaskrun; +extern U32 const os_trv; +extern U8 const os_flags; +extern U32 const os_rrobin; +extern U32 const os_clockrate; +extern U32 const os_timernum; +extern U16 const idle_task_stack_size; + +extern U8 const os_fifo_size; + +/* Functions */ +extern void os_idle_demon (void); +extern int os_tick_init (void); +extern void os_tick_irqack (void); +extern void os_tmr_call (U16 info); +extern void os_error (U32 err_code); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/RTX_Conf_CM.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,289 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RTX_Conf_CM.C + * Purpose: Configuration of CMSIS RTX Kernel for Cortex-M + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "cmsis_os.h" + + +/*---------------------------------------------------------------------------- + * RTX User configuration part BEGIN + *---------------------------------------------------------------------------*/ + +//-------- <<< Use Configuration Wizard in Context Menu >>> ----------------- +// +// <h>Thread Configuration +// ======================= +// +// <o>Number of concurrent running threads <0-250> +// <i> Defines max. number of threads that will run at the same time. +// counting "main", but not counting "osTimerThread" +// <i> Default: 6 +#ifndef OS_TASKCNT +# if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088) || defined(TARGET_LPC4337) || defined(TARGET_LPC1347) || defined(TARGET_K64F) || defined(TARGET_STM32F401RE)\ + || defined(TARGET_KL46Z) || defined(TARGET_KL43Z) || defined(TARGET_STM32F407) || defined(TARGET_F407VG) || defined(TARGET_STM32F303VC) || defined(TARGET_LPC1549) || defined(TARGET_LPC11U68) || defined(TARGET_NRF51822) || defined(TARGET_STM32F411RE) +# define OS_TASKCNT 14 +# elif defined(TARGET_LPC11U24) || defined(TARGET_LPC11U35_401) || defined(TARGET_LPC11U35_501) || defined(TARGET_LPCCAPPUCCINO) || defined(TARGET_LPC1114) \ + || defined(TARGET_LPC812) || defined(TARGET_KL25Z) || defined(TARGET_KL05Z) || defined(TARGET_STM32F100RB) || defined(TARGET_STM32F051R8) \ + || defined(TARGET_STM32F103RB) || defined(TARGET_LPC824) || defined(TARGET_STM32F302R8) || defined(TARGET_STM32F334R8) || defined(TARGET_STM32F334C8) +# define OS_TASKCNT 6 +# else +# error "no target defined" +# endif +#endif + +// <o>Scheduler (+ interrupts) stack size [bytes] <64-4096:8><#/4> +#ifndef OS_SCHEDULERSTKSIZE +# if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088) || defined(TARGET_LPC4337) || defined(TARGET_LPC1347) || defined(TARGET_K64F) || defined(TARGET_STM32F401RE)\ + || defined(TARGET_KL46Z) || defined(TARGET_KL43Z) || defined(TARGET_STM32F407) || defined(TARGET_F407VG) || defined(TARGET_STM32F303VC) || defined(TARGET_LPC1549) || defined(TARGET_LPC11U68) || defined(TARGET_NRF51822) || defined(TARGET_STM32F411RE) +# define OS_SCHEDULERSTKSIZE 256 +# elif defined(TARGET_LPC11U24) || defined(TARGET_LPC11U35_401) || defined(TARGET_LPC11U35_501) || defined(TARGET_LPCCAPPUCCINO) || defined(TARGET_LPC1114) \ + || defined(TARGET_LPC812) || defined(TARGET_KL25Z) || defined(TARGET_KL05Z) || defined(TARGET_STM32F100RB) || defined(TARGET_STM32F051R8) \ + || defined(TARGET_STM32F103RB) || defined(TARGET_LPC824) || defined(TARGET_STM32F302R8) || defined(TARGET_STM32F334R8) || defined(TARGET_STM32F334C8) +# define OS_SCHEDULERSTKSIZE 128 +# else +# error "no target defined" +# endif +#endif + +// <o>Idle stack size [bytes] <64-4096:8><#/4> +// <i> Defines default stack size for the Idle thread. +#ifndef OS_IDLESTKSIZE + #define OS_IDLESTKSIZE 128 +#endif + +// <o>Timer Thread stack size [bytes] <64-4096:8><#/4> +// <i> Defines stack size for Timer thread. +// <i> Default: 200 +#ifndef OS_TIMERSTKSZ + #define OS_TIMERSTKSZ WORDS_STACK_SIZE +#endif + +// <q>Check for stack overflow +// <i> Includes the stack checking code for stack overflow. +// <i> Note that additional code reduces the Kernel performance. +#ifndef OS_STKCHECK + #define OS_STKCHECK 1 +#endif + +// <o>Processor mode for thread execution +// <0=> Unprivileged mode +// <1=> Privileged mode +// <i> Default: Privileged mode +#ifndef OS_RUNPRIV + #define OS_RUNPRIV 1 +#endif + +// </h> +// <h>SysTick Timer Configuration +// ============================== +// +// <o>Timer clock value [Hz] <1-1000000000> +// <i> Defines the timer clock value. +// <i> Default: 6000000 (6MHz) +#ifndef OS_CLOCK +# if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) +# define OS_CLOCK 96000000 + +# elif defined(TARGET_LPC1347) || defined(TARGET_STM32F303VC) || defined(TARGET_LPC1549) || defined(TARGET_STM32F302R8) || defined(TARGET_STM32F334R8) || defined(TARGET_STM32F334C8) +# define OS_CLOCK 72000000 + +# elif defined(TARGET_LPC11U24) || defined(TARGET_LPC11U35_401) || defined(TARGET_LPC11U35_501) || defined(TARGET_LPCCAPPUCCINO) || defined(TARGET_LPC1114) || defined(TARGET_KL25Z) || defined(TARGET_KL05Z) || defined(TARGET_KL46Z) || defined(TARGET_KL43Z) || defined(TARGET_STM32F051R8) || defined(TARGET_LPC11U68) +# define OS_CLOCK 48000000 + +# elif defined(TARGET_LPC812) +# define OS_CLOCK 36000000 + +# elif defined(TARGET_LPC824) +# define OS_CLOCK 30000000 + +# elif defined(TARGET_STM32F100RB) +# define OS_CLOCK 24000000 + +# elif defined(TARGET_LPC4088) || defined(TARGET_K64F) +# define OS_CLOCK 120000000 + +# elif defined(TARGET_LPC4337) +# define OS_CLOCK 204000000 + +# elif defined(TARGET_STM32F407) || defined(TARGET_F407VG) +# define OS_CLOCK 168000000 + +# elif defined(TARGET_NRF51822) +# define OS_CLOCK 16000000 + +# elif defined(TARGET_STM32F401RE) +# define OS_CLOCK 84000000 + +# elif defined(TARGET_STM32F411RE) +# define OS_CLOCK 100000000 + +#elif defined(TARGET_STM32F103RB) +# define OS_CLOCK 72000000 + +# else +# error "no target defined" +# endif +#endif + +// <o>Timer tick value [us] <1-1000000> +// <i> Defines the timer tick value. +// <i> Default: 1000 (1ms) +#ifndef OS_TICK + #define OS_TICK 1000 +#endif + +// </h> + +// <h>System Configuration +// ======================= +// +// <e>Round-Robin Thread switching +// =============================== +// +// <i> Enables Round-Robin Thread switching. +#ifndef OS_ROBIN + #define OS_ROBIN 1 +#endif + +// <o>Round-Robin Timeout [ticks] <1-1000> +// <i> Defines how long a thread will execute before a thread switch. +// <i> Default: 5 +#ifndef OS_ROBINTOUT + #define OS_ROBINTOUT 5 +#endif + +// </e> + +// <e>User Timers +// ============== +// <i> Enables user Timers +#ifndef OS_TIMERS + #define OS_TIMERS 1 +#endif + +// <o>Timer Thread Priority +// <1=> Low +// <2=> Below Normal +// <3=> Normal +// <4=> Above Normal +// <5=> High +// <6=> Realtime (highest) +// <i> Defines priority for Timer Thread +// <i> Default: High +#ifndef OS_TIMERPRIO + #define OS_TIMERPRIO 5 +#endif + +// <o>Timer Callback Queue size <1-32> +// <i> Number of concurrent active timer callback functions. +// <i> Default: 4 +#ifndef OS_TIMERCBQSZ + #define OS_TIMERCBQS 4 +#endif + +// </e> + +// <o>ISR FIFO Queue size<4=> 4 entries <8=> 8 entries +// <12=> 12 entries <16=> 16 entries +// <24=> 24 entries <32=> 32 entries +// <48=> 48 entries <64=> 64 entries +// <96=> 96 entries +// <i> ISR functions store requests to this buffer, +// <i> when they are called from the interrupt handler. +// <i> Default: 16 entries +#ifndef OS_FIFOSZ + #define OS_FIFOSZ 16 +#endif + +// </h> + +//------------- <<< end of configuration section >>> ----------------------- + +// Standard library system mutexes +// =============================== +// Define max. number system mutexes that are used to protect +// the arm standard runtime library. For microlib they are not used. +#ifndef OS_MUTEXCNT + #define OS_MUTEXCNT 12 +#endif + +/*---------------------------------------------------------------------------- + * RTX User configuration part END + *---------------------------------------------------------------------------*/ + +#define OS_TRV ((uint32_t)(((double)OS_CLOCK*(double)OS_TICK)/1E6)-1) + + +/*---------------------------------------------------------------------------- + * OS Idle daemon + *---------------------------------------------------------------------------*/ +void os_idle_demon (void) { + /* The idle demon is a system thread, running when no other thread is */ + /* ready to run. */ + + /* Sleep: ideally, we should put the chip to sleep. + Unfortunately, this usually requires disconnecting the interface chip (debugger). + This can be done, but it would break the local file system. + */ + for (;;) { + // sleep(); + } +} + +/*---------------------------------------------------------------------------- + * RTX Errors + *---------------------------------------------------------------------------*/ +extern void mbed_die(void); + +void os_error (uint32_t err_code) { + /* This function is called when a runtime error is detected. Parameter */ + /* 'err_code' holds the runtime error code (defined in RTX_Conf.h). */ + mbed_die(); +} + +void sysThreadError(osStatus status) { + if (status != osOK) { + mbed_die(); + } +} + +/*---------------------------------------------------------------------------- + * RTX Configuration Functions + *---------------------------------------------------------------------------*/ + +#include "RTX_CM_lib.h" + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/HAL_CM0.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,301 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: HAL_CM0.C + * Purpose: Hardware Abstraction Layer for Cortex-M0 + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_System.h" +#include "rt_HAL_CM.h" +#include "rt_Task.h" +#include "rt_MemBox.h" + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_set_PSP ------------------------------------*/ + +__asm void rt_set_PSP (U32 stack) { + MSR PSP,R0 + BX LR +} + + +/*--------------------------- rt_get_PSP ------------------------------------*/ + +__asm U32 rt_get_PSP (void) { + MRS R0,PSP + BX LR +} + + +/*--------------------------- os_set_env ------------------------------------*/ + +__asm void os_set_env (void) { + /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ + MOV R0,SP ; PSP = MSP + MSR PSP,R0 + LDR R0,=__cpp(&os_flags) + LDRB R0,[R0] + LSLS R0,#31 + BNE PrivilegedE + MOVS R0,#0x03 ; Unprivileged Thread mode, use PSP + MSR CONTROL,R0 + BX LR +PrivilegedE + MOVS R0,#0x02 ; Privileged Thread mode, use PSP + MSR CONTROL,R0 + BX LR + + ALIGN +} + + +/*--------------------------- _alloc_box ------------------------------------*/ + +__asm void *_alloc_box (void *box_mem) { + /* Function wrapper for Unprivileged/Privileged mode. */ + LDR R3,=__cpp(rt_alloc_box) + MOV R12,R3 + MRS R3,IPSR + LSLS R3,#24 + BNE PrivilegedA + MRS R3,CONTROL + LSLS R3,#31 + BEQ PrivilegedA + SVC 0 + BX LR +PrivilegedA + BX R12 + + ALIGN +} + + +/*--------------------------- _free_box -------------------------------------*/ + +__asm int _free_box (void *box_mem, void *box) { + /* Function wrapper for Unprivileged/Privileged mode. */ + LDR R3,=__cpp(rt_free_box) + MOV R12,R3 + MRS R3,IPSR + LSLS R3,#24 + BNE PrivilegedF + MRS R3,CONTROL + LSLS R3,#31 + BEQ PrivilegedF + SVC 0 + BX LR +PrivilegedF + BX R12 + + ALIGN +} + + +/*-------------------------- SVC_Handler ------------------------------------*/ + +__asm void SVC_Handler (void) { + PRESERVE8 + + IMPORT SVC_Count + IMPORT SVC_Table + IMPORT rt_stk_check + + MRS R0,PSP ; Read PSP + LDR R1,[R0,#24] ; Read Saved PC from Stack + SUBS R1,R1,#2 ; Point to SVC Instruction + LDRB R1,[R1] ; Load SVC Number + CMP R1,#0 + BNE SVC_User ; User SVC Number > 0 + + MOV LR,R4 + LDMIA R0,{R0-R3,R4} ; Read R0-R3,R12 from stack + MOV R12,R4 + MOV R4,LR + BLX R12 ; Call SVC Function + + MRS R3,PSP ; Read PSP + STMIA R3!,{R0-R2} ; Store return values + + LDR R3,=__cpp(&os_tsk) + LDMIA R3!,{R1,R2} ; os_tsk.run, os_tsk.new + CMP R1,R2 + BEQ SVC_Exit ; no task switch + + SUBS R3,#8 + CMP R1,#0 ; Runtask deleted? + BEQ SVC_Next + + MRS R0,PSP ; Read PSP + SUBS R0,R0,#32 ; Adjust Start Address + STR R0,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack + STMIA R0!,{R4-R7} ; Save old context (R4-R7) + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} ; Save old context (R8-R11) + + PUSH {R2,R3} + BL rt_stk_check ; Check for Stack overflow + POP {R2,R3} + +SVC_Next + STR R2,[R3] ; os_tsk.run = os_tsk.new + + LDR R0,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack + ADDS R0,R0,#16 ; Adjust Start Address + LDMIA R0!,{R4-R7} ; Restore new Context (R8-R11) + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 ; Write PSP + SUBS R0,R0,#32 ; Adjust Start Address + LDMIA R0!,{R4-R7} ; Restore new Context (R4-R7) + +SVC_Exit + MOVS R0,#:NOT:0xFFFFFFFD ; Set EXC_RETURN value + MVNS R0,R0 + BX R0 ; RETI to Thread Mode, use PSP + + /*------------------- User SVC ------------------------------*/ + +SVC_User + PUSH {R4,LR} ; Save Registers + LDR R2,=SVC_Count + LDR R2,[R2] + CMP R1,R2 + BHI SVC_Done ; Overflow + + LDR R4,=SVC_Table-4 + LSLS R1,R1,#2 + LDR R4,[R4,R1] ; Load SVC Function Address + MOV LR,R4 + + LDMIA R0,{R0-R3,R4} ; Read R0-R3,R12 from stack + MOV R12,R4 + BLX LR ; Call SVC Function + + MRS R4,PSP ; Read PSP + STMIA R4!,{R0-R3} ; Function return values +SVC_Done + POP {R4,PC} ; RETI + + ALIGN +} + + +/*-------------------------- PendSV_Handler ---------------------------------*/ + +__asm void PendSV_Handler (void) { + PRESERVE8 + + BL __cpp(rt_pop_req) + +Sys_Switch + LDR R3,=__cpp(&os_tsk) + LDMIA R3!,{R1,R2} ; os_tsk.run, os_tsk.new + CMP R1,R2 + BEQ Sys_Exit ; no task switch + + SUBS R3,#8 + + MRS R0,PSP ; Read PSP + SUBS R0,R0,#32 ; Adjust Start Address + STR R0,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack + STMIA R0!,{R4-R7} ; Save old context (R4-R7) + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} ; Save old context (R8-R11) + + PUSH {R2,R3} + BL rt_stk_check ; Check for Stack overflow + POP {R2,R3} + + STR R2,[R3] ; os_tsk.run = os_tsk.new + + LDR R0,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack + ADDS R0,R0,#16 ; Adjust Start Address + LDMIA R0!,{R4-R7} ; Restore new Context (R8-R11) + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 ; Write PSP + SUBS R0,R0,#32 ; Adjust Start Address + LDMIA R0!,{R4-R7} ; Restore new Context (R4-R7) + +Sys_Exit + MOVS R0,#:NOT:0xFFFFFFFD ; Set EXC_RETURN value + MVNS R0,R0 + BX R0 ; RETI to Thread Mode, use PSP + + ALIGN +} + + +/*-------------------------- SysTick_Handler --------------------------------*/ + +__asm void SysTick_Handler (void) { + PRESERVE8 + + BL __cpp(rt_systick) + B Sys_Switch + + ALIGN +} + + +/*-------------------------- OS_Tick_Handler --------------------------------*/ + +__asm void OS_Tick_Handler (void) { + PRESERVE8 + + BL __cpp(os_tick_irqack) + BL __cpp(rt_systick) + B Sys_Switch + + ALIGN +} + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/SVC_Table.s Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,57 @@ +;/*---------------------------------------------------------------------------- +; * RL-ARM - RTX +; *---------------------------------------------------------------------------- +; * Name: SVC_TABLE.S +; * Purpose: Pre-defined SVC Table for Cortex-M +; * Rev.: V4.60 +; *---------------------------------------------------------------------------- +; * +; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH +; * All rights reserved. +; * Redistribution and use in source and binary forms, with or without +; * modification, are permitted provided that the following conditions are met: +; * - Redistributions of source code must retain the above copyright +; * notice, this list of conditions and the following disclaimer. +; * - Redistributions in binary form must reproduce the above copyright +; * notice, this list of conditions and the following disclaimer in the +; * documentation and/or other materials provided with the distribution. +; * - Neither the name of ARM nor the names of its contributors may be used +; * to endorse or promote products derived from this software without +; * specific prior written permission. +; * +; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE +; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; * POSSIBILITY OF SUCH DAMAGE. +; *---------------------------------------------------------------------------*/ + + + AREA SVC_TABLE, CODE, READONLY + + EXPORT SVC_Count + +SVC_Cnt EQU (SVC_End-SVC_Table)/4 +SVC_Count DCD SVC_Cnt + +; Import user SVC functions here. +; IMPORT __SVC_1 + + EXPORT SVC_Table +SVC_Table +; Insert user SVC functions here. SVC 0 used by RTL Kernel. +; DCD __SVC_1 ; user SVC function + +SVC_End + + END + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/HAL_CM0.s Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,370 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: HAL_CM0.S + * Purpose: Hardware Abstraction Layer for Cortex-M0 + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + + .file "HAL_CM0.S" + .syntax unified + + .equ TCB_TSTACK, 36 + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + .thumb + + .section ".text" + .align 2 + + +/*--------------------------- rt_set_PSP ------------------------------------*/ + +# void rt_set_PSP (U32 stack); + + .thumb_func + .type rt_set_PSP, %function + .global rt_set_PSP +rt_set_PSP: + .fnstart + .cantunwind + + MSR PSP,R0 + BX LR + + .fnend + .size rt_set_PSP, .-rt_set_PSP + + +/*--------------------------- rt_get_PSP ------------------------------------*/ + +# U32 rt_get_PSP (void); + + .thumb_func + .type rt_get_PSP, %function + .global rt_get_PSP +rt_get_PSP: + .fnstart + .cantunwind + + MRS R0,PSP + BX LR + + .fnend + .size rt_get_PSP, .-rt_get_PSP + + +/*--------------------------- os_set_env ------------------------------------*/ + +# void os_set_env (void); + /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ + + .thumb_func + .type os_set_env, %function + .global os_set_env +os_set_env: + .fnstart + .cantunwind + + MOV R0,SP /* PSP = MSP */ + MSR PSP,R0 + LDR R0,=os_flags + LDRB R0,[R0] + LSLS R0,#31 + BNE PrivilegedE + MOVS R0,#0x03 /* Unprivileged Thread mode, use PSP */ + MSR CONTROL,R0 + BX LR +PrivilegedE: + MOVS R0,#0x02 /* Privileged Thread mode, use PSP */ + MSR CONTROL,R0 + BX LR + + .fnend + .size os_set_env, .-os_set_env + + +/*--------------------------- _alloc_box ------------------------------------*/ + +# void *_alloc_box (void *box_mem); + /* Function wrapper for Unprivileged/Privileged mode. */ + + .thumb_func + .type _alloc_box, %function + .global _alloc_box +_alloc_box: + .fnstart + .cantunwind + + LDR R3,=rt_alloc_box + MOV R12,R3 + MRS R3,IPSR + LSLS R3,#24 + BNE PrivilegedA + MRS R3,CONTROL + LSLS R3,#31 + BEQ PrivilegedA + SVC 0 + BX LR +PrivilegedA: + BX R12 + + .fnend + .size _alloc_box, .-_alloc_box + + +/*--------------------------- _free_box -------------------------------------*/ + +# int _free_box (void *box_mem, void *box); + /* Function wrapper for Unprivileged/Privileged mode. */ + + .thumb_func + .type _free_box, %function + .global _free_box +_free_box: + .fnstart + .cantunwind + + LDR R3,=rt_free_box + MOV R12,R3 + MRS R3,IPSR + LSLS R3,#24 + BNE PrivilegedF + MRS R3,CONTROL + LSLS R3,#31 + BEQ PrivilegedF + SVC 0 + BX LR +PrivilegedF: + BX R12 + + .fnend + .size _free_box, .-_free_box + + +/*-------------------------- SVC_Handler ------------------------------------*/ + +# void SVC_Handler (void); + + .thumb_func + .type SVC_Handler, %function + .global SVC_Handler +SVC_Handler: + .fnstart + .cantunwind + + MRS R0,PSP /* Read PSP */ + LDR R1,[R0,#24] /* Read Saved PC from Stack */ + SUBS R1,R1,#2 /* Point to SVC Instruction */ + LDRB R1,[R1] /* Load SVC Number */ + CMP R1,#0 + BNE SVC_User /* User SVC Number > 0 */ + + MOV LR,R4 + LDMIA R0,{R0-R3,R4} /* Read R0-R3,R12 from stack */ + MOV R12,R4 + MOV R4,LR + BLX R12 /* Call SVC Function */ + + MRS R3,PSP /* Read PSP */ + STMIA R3!,{R0-R2} /* Store return values */ + + LDR R3,=os_tsk + LDMIA R3!,{R1,R2} /* os_tsk.run, os_tsk.new */ + CMP R1,R2 + BEQ SVC_Exit /* no task switch */ + + SUBS R3,#8 + CMP R1,#0 /* Runtask deleted? */ + BEQ SVC_Next + + MRS R0,PSP /* Read PSP */ + SUBS R0,R0,#32 /* Adjust Start Address */ + STR R0,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ + STMIA R0!,{R4-R7} /* Save old context (R4-R7) */ + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} /* Save old context (R8-R11) */ + + PUSH {R2,R3} + BL rt_stk_check /* Check for Stack overflow */ + POP {R2,R3} + +SVC_Next: + STR R2,[R3] /* os_tsk.run = os_tsk.new */ + + LDR R0,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ + ADDS R0,R0,#16 /* Adjust Start Address */ + LDMIA R0!,{R4-R7} /* Restore new Context (R8-R11) */ + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 /* Write PSP */ + SUBS R0,R0,#32 /* Adjust Start Address */ + LDMIA R0!,{R4-R7} /* Restore new Context (R4-R7) */ + +SVC_Exit: + MOVS R0,#~0xFFFFFFFD /* Set EXC_RETURN value */ + MVNS R0,R0 + BX R0 /* RETI to Thread Mode, use PSP */ + + /*------------------- User SVC ------------------------------*/ + +SVC_User: + PUSH {R4,LR} /* Save Registers */ + LDR R2,=SVC_Count + LDR R2,[R2] + CMP R1,R2 + BHI SVC_Done /* Overflow */ + + LDR R4,=SVC_Table-4 + LSLS R1,R1,#2 + LDR R4,[R4,R1] /* Load SVC Function Address */ + MOV LR,R4 + + LDMIA R0,{R0-R3,R4} /* Read R0-R3,R12 from stack */ + MOV R12,R4 + BLX LR /* Call SVC Function */ + + MRS R4,PSP /* Read PSP */ + STMIA R4!,{R0-R3} /* Function return values */ +SVC_Done: + POP {R4,PC} /* RETI */ + + .fnend + .size SVC_Handler, .-SVC_Handler + + +/*-------------------------- PendSV_Handler ---------------------------------*/ + +# void PendSV_Handler (void); + + .thumb_func + .type PendSV_Handler, %function + .global PendSV_Handler + .global Sys_Switch +PendSV_Handler: + .fnstart + .cantunwind + + BL rt_pop_req + +Sys_Switch: + LDR R3,=os_tsk + LDMIA R3!,{R1,R2} /* os_tsk.run, os_tsk.new */ + CMP R1,R2 + BEQ Sys_Exit /* no task switch */ + + SUBS R3,#8 + + MRS R0,PSP /* Read PSP */ + SUBS R0,R0,#32 /* Adjust Start Address */ + STR R0,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ + STMIA R0!,{R4-R7} /* Save old context (R4-R7) */ + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} /* Save old context (R8-R11) */ + + PUSH {R2,R3} + BL rt_stk_check /* Check for Stack overflow */ + POP {R2,R3} + + STR R2,[R3] /* os_tsk.run = os_tsk.new */ + + LDR R0,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ + ADDS R0,R0,#16 /* Adjust Start Address */ + LDMIA R0!,{R4-R7} /* Restore new Context (R8-R11) */ + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 /* Write PSP */ + SUBS R0,R0,#32 /* Adjust Start Address */ + LDMIA R0!,{R4-R7} /* Restore new Context (R4-R7) */ + +Sys_Exit: + MOVS R0,#~0xFFFFFFFD /* Set EXC_RETURN value */ + MVNS R0,R0 + BX R0 /* RETI to Thread Mode, use PSP */ + + .fnend + .size PendSV_Handler, .-PendSV_Handler + + +/*-------------------------- SysTick_Handler --------------------------------*/ + +# void SysTick_Handler (void); + + .thumb_func + .type SysTick_Handler, %function + .global SysTick_Handler +SysTick_Handler: + .fnstart + .cantunwind + + BL rt_systick + B Sys_Switch + + .fnend + .size SysTick_Handler, .-SysTick_Handler + + +/*-------------------------- OS_Tick_Handler --------------------------------*/ + +# void OS_Tick_Handler (void); + + .thumb_func + .type OS_Tick_Handler, %function + .global OS_Tick_Handler +OS_Tick_Handler: + .fnstart + .cantunwind + + BL os_tick_irqack + BL rt_systick + B Sys_Switch + + .fnend + .size OS_Tick_Handler, .-OS_Tick_Handler + + + .end + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/SVC_Table.s Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,56 @@ +;/*---------------------------------------------------------------------------- +; * RL-ARM - RTX +; *---------------------------------------------------------------------------- +; * Name: SVC_TABLE.S +; * Purpose: Pre-defined SVC Table for Cortex-M +; * Rev.: V4.60 +; *---------------------------------------------------------------------------- +; * +; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH +; * All rights reserved. +; * Redistribution and use in source and binary forms, with or without +; * modification, are permitted provided that the following conditions are met: +; * - Redistributions of source code must retain the above copyright +; * notice, this list of conditions and the following disclaimer. +; * - Redistributions in binary form must reproduce the above copyright +; * notice, this list of conditions and the following disclaimer in the +; * documentation and/or other materials provided with the distribution. +; * - Neither the name of ARM nor the names of its contributors may be used +; * to endorse or promote products derived from this software without +; * specific prior written permission. +; * +; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE +; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; * POSSIBILITY OF SUCH DAMAGE. +; *---------------------------------------------------------------------------*/ + + + .file "SVC_Table.S" + + + .section ".svc_table" + + .global SVC_Table +SVC_Table: +/* Insert user SVC functions here. SVC 0 used by RTL Kernel. */ +# .long __SVC_1 /* user SVC function */ +SVC_End: + + .global SVC_Count +SVC_Count: + .long (SVC_End-SVC_Table)/4 + + + .end + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/HAL_CM0.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,301 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: HAL_CM0.C + * Purpose: Hardware Abstraction Layer for Cortex-M0 + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_System.h" +#include "rt_HAL_CM.h" +#include "rt_Task.h" +#include "rt_MemBox.h" + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_set_PSP ------------------------------------*/ + +__asm void rt_set_PSP (U32 stack) { + MSR PSP,R0 + BX LR +} + + +/*--------------------------- rt_get_PSP ------------------------------------*/ + +__asm U32 rt_get_PSP (void) { + MRS R0,PSP + BX LR +} + + +/*--------------------------- os_set_env ------------------------------------*/ + +__asm void os_set_env (void) { + /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ + MOV R0,SP ; PSP = MSP + MSR PSP,R0 + LDR R0,=__cpp(&os_flags) + LDRB R0,[R0] + LSLS R0,#31 + BNE PrivilegedE + MOVS R0,#0x03 ; Unprivileged Thread mode, use PSP + MSR CONTROL,R0 + BX LR +PrivilegedE + MOVS R0,#0x02 ; Privileged Thread mode, use PSP + MSR CONTROL,R0 + BX LR + + ALIGN +} + + +/*--------------------------- _alloc_box ------------------------------------*/ + +__asm void *_alloc_box (void *box_mem) { + /* Function wrapper for Unprivileged/Privileged mode. */ + LDR R3,=__cpp(rt_alloc_box) + MOV R12,R3 + MRS R3,IPSR + LSLS R3,#24 + BNE PrivilegedA + MRS R3,CONTROL + LSLS R3,#31 + BEQ PrivilegedA + SVC 0 + BX LR +PrivilegedA + BX R12 + + ALIGN +} + + +/*--------------------------- _free_box -------------------------------------*/ + +__asm int _free_box (void *box_mem, void *box) { + /* Function wrapper for Unprivileged/Privileged mode. */ + LDR R3,=__cpp(rt_free_box) + MOV R12,R3 + MRS R3,IPSR + LSLS R3,#24 + BNE PrivilegedF + MRS R3,CONTROL + LSLS R3,#31 + BEQ PrivilegedF + SVC 0 + BX LR +PrivilegedF + BX R12 + + ALIGN +} + + +/*-------------------------- SVC_Handler ------------------------------------*/ + +__asm void SVC_Handler (void) { + PRESERVE8 + + IMPORT SVC_Count + IMPORT SVC_Table + IMPORT rt_stk_check + + MRS R0,PSP ; Read PSP + LDR R1,[R0,#24] ; Read Saved PC from Stack + SUBS R1,R1,#2 ; Point to SVC Instruction + LDRB R1,[R1] ; Load SVC Number + CMP R1,#0 + BNE SVC_User ; User SVC Number > 0 + + MOV LR,R4 + LDMIA R0,{R0-R3,R4} ; Read R0-R3,R12 from stack + MOV R12,R4 + MOV R4,LR + BLX R12 ; Call SVC Function + + MRS R3,PSP ; Read PSP + STMIA R3!,{R0-R2} ; Store return values + + LDR R3,=__cpp(&os_tsk) + LDMIA R3!,{R1,R2} ; os_tsk.run, os_tsk.new + CMP R1,R2 + BEQ SVC_Exit ; no task switch + + SUBS R3,#8 + CMP R1,#0 ; Runtask deleted? + BEQ SVC_Next + + MRS R0,PSP ; Read PSP + SUBS R0,R0,#32 ; Adjust Start Address + STR R0,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack + STMIA R0!,{R4-R7} ; Save old context (R4-R7) + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} ; Save old context (R8-R11) + + PUSH {R2,R3} + BL rt_stk_check ; Check for Stack overflow + POP {R2,R3} + +SVC_Next + STR R2,[R3] ; os_tsk.run = os_tsk.new + + LDR R0,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack + ADDS R0,R0,#16 ; Adjust Start Address + LDMIA R0!,{R4-R7} ; Restore new Context (R8-R11) + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 ; Write PSP + SUBS R0,R0,#32 ; Adjust Start Address + LDMIA R0!,{R4-R7} ; Restore new Context (R4-R7) + +SVC_Exit + MOVS R0,#:NOT:0xFFFFFFFD ; Set EXC_RETURN value + MVNS R0,R0 + BX R0 ; RETI to Thread Mode, use PSP + + /*------------------- User SVC ------------------------------*/ + +SVC_User + PUSH {R4,LR} ; Save Registers + LDR R2,=SVC_Count + LDR R2,[R2] + CMP R1,R2 + BHI SVC_Done ; Overflow + + LDR R4,=SVC_Table-4 + LSLS R1,R1,#2 + LDR R4,[R4,R1] ; Load SVC Function Address + MOV LR,R4 + + LDMIA R0,{R0-R3,R4} ; Read R0-R3,R12 from stack + MOV R12,R4 + BLX LR ; Call SVC Function + + MRS R4,PSP ; Read PSP + STMIA R4!,{R0-R3} ; Function return values +SVC_Done + POP {R4,PC} ; RETI + + ALIGN +} + + +/*-------------------------- PendSV_Handler ---------------------------------*/ + +__asm void PendSV_Handler (void) { + PRESERVE8 + + BL __cpp(rt_pop_req) + +Sys_Switch + LDR R3,=__cpp(&os_tsk) + LDMIA R3!,{R1,R2} ; os_tsk.run, os_tsk.new + CMP R1,R2 + BEQ Sys_Exit ; no task switch + + SUBS R3,#8 + + MRS R0,PSP ; Read PSP + SUBS R0,R0,#32 ; Adjust Start Address + STR R0,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack + STMIA R0!,{R4-R7} ; Save old context (R4-R7) + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} ; Save old context (R8-R11) + + PUSH {R2,R3} + BL rt_stk_check ; Check for Stack overflow + POP {R2,R3} + + STR R2,[R3] ; os_tsk.run = os_tsk.new + + LDR R0,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack + ADDS R0,R0,#16 ; Adjust Start Address + LDMIA R0!,{R4-R7} ; Restore new Context (R8-R11) + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 ; Write PSP + SUBS R0,R0,#32 ; Adjust Start Address + LDMIA R0!,{R4-R7} ; Restore new Context (R4-R7) + +Sys_Exit + MOVS R0,#:NOT:0xFFFFFFFD ; Set EXC_RETURN value + MVNS R0,R0 + BX R0 ; RETI to Thread Mode, use PSP + + ALIGN +} + + +/*-------------------------- SysTick_Handler --------------------------------*/ + +__asm void SysTick_Handler (void) { + PRESERVE8 + + BL __cpp(rt_systick) + B Sys_Switch + + ALIGN +} + + +/*-------------------------- OS_Tick_Handler --------------------------------*/ + +__asm void OS_Tick_Handler (void) { + PRESERVE8 + + BL __cpp(os_tick_irqack) + BL __cpp(rt_systick) + B Sys_Switch + + ALIGN +} + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/SVC_Table.s Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,57 @@ +;/*---------------------------------------------------------------------------- +; * RL-ARM - RTX +; *---------------------------------------------------------------------------- +; * Name: SVC_TABLE.S +; * Purpose: Pre-defined SVC Table for Cortex-M +; * Rev.: V4.60 +; *---------------------------------------------------------------------------- +; * +; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH +; * All rights reserved. +; * Redistribution and use in source and binary forms, with or without +; * modification, are permitted provided that the following conditions are met: +; * - Redistributions of source code must retain the above copyright +; * notice, this list of conditions and the following disclaimer. +; * - Redistributions in binary form must reproduce the above copyright +; * notice, this list of conditions and the following disclaimer in the +; * documentation and/or other materials provided with the distribution. +; * - Neither the name of ARM nor the names of its contributors may be used +; * to endorse or promote products derived from this software without +; * specific prior written permission. +; * +; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE +; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; * POSSIBILITY OF SUCH DAMAGE. +; *---------------------------------------------------------------------------*/ + + + AREA SVC_TABLE, CODE, READONLY + + EXPORT SVC_Count + +SVC_Cnt EQU (SVC_End-SVC_Table)/4 +SVC_Count DCD SVC_Cnt + +; Import user SVC functions here. +; IMPORT __SVC_1 + + EXPORT SVC_Table +SVC_Table +; Insert user SVC functions here. SVC 0 used by RTL Kernel. +; DCD __SVC_1 ; user SVC function + +SVC_End + + END + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/HAL_CM0.s Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,370 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: HAL_CM0.S + * Purpose: Hardware Abstraction Layer for Cortex-M0 + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + + .file "HAL_CM0.S" + .syntax unified + + .equ TCB_TSTACK, 36 + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + .thumb + + .section ".text" + .align 2 + + +/*--------------------------- rt_set_PSP ------------------------------------*/ + +# void rt_set_PSP (U32 stack); + + .thumb_func + .type rt_set_PSP, %function + .global rt_set_PSP +rt_set_PSP: + .fnstart + .cantunwind + + MSR PSP,R0 + BX LR + + .fnend + .size rt_set_PSP, .-rt_set_PSP + + +/*--------------------------- rt_get_PSP ------------------------------------*/ + +# U32 rt_get_PSP (void); + + .thumb_func + .type rt_get_PSP, %function + .global rt_get_PSP +rt_get_PSP: + .fnstart + .cantunwind + + MRS R0,PSP + BX LR + + .fnend + .size rt_get_PSP, .-rt_get_PSP + + +/*--------------------------- os_set_env ------------------------------------*/ + +# void os_set_env (void); + /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ + + .thumb_func + .type os_set_env, %function + .global os_set_env +os_set_env: + .fnstart + .cantunwind + + MOV R0,SP /* PSP = MSP */ + MSR PSP,R0 + LDR R0,=os_flags + LDRB R0,[R0] + LSLS R0,#31 + BNE PrivilegedE + MOVS R0,#0x03 /* Unprivileged Thread mode, use PSP */ + MSR CONTROL,R0 + BX LR +PrivilegedE: + MOVS R0,#0x02 /* Privileged Thread mode, use PSP */ + MSR CONTROL,R0 + BX LR + + .fnend + .size os_set_env, .-os_set_env + + +/*--------------------------- _alloc_box ------------------------------------*/ + +# void *_alloc_box (void *box_mem); + /* Function wrapper for Unprivileged/Privileged mode. */ + + .thumb_func + .type _alloc_box, %function + .global _alloc_box +_alloc_box: + .fnstart + .cantunwind + + LDR R3,=rt_alloc_box + MOV R12,R3 + MRS R3,IPSR + LSLS R3,#24 + BNE PrivilegedA + MRS R3,CONTROL + LSLS R3,#31 + BEQ PrivilegedA + SVC 0 + BX LR +PrivilegedA: + BX R12 + + .fnend + .size _alloc_box, .-_alloc_box + + +/*--------------------------- _free_box -------------------------------------*/ + +# int _free_box (void *box_mem, void *box); + /* Function wrapper for Unprivileged/Privileged mode. */ + + .thumb_func + .type _free_box, %function + .global _free_box +_free_box: + .fnstart + .cantunwind + + LDR R3,=rt_free_box + MOV R12,R3 + MRS R3,IPSR + LSLS R3,#24 + BNE PrivilegedF + MRS R3,CONTROL + LSLS R3,#31 + BEQ PrivilegedF + SVC 0 + BX LR +PrivilegedF: + BX R12 + + .fnend + .size _free_box, .-_free_box + + +/*-------------------------- SVC_Handler ------------------------------------*/ + +# void SVC_Handler (void); + + .thumb_func + .type SVC_Handler, %function + .global SVC_Handler +SVC_Handler: + .fnstart + .cantunwind + + MRS R0,PSP /* Read PSP */ + LDR R1,[R0,#24] /* Read Saved PC from Stack */ + SUBS R1,R1,#2 /* Point to SVC Instruction */ + LDRB R1,[R1] /* Load SVC Number */ + CMP R1,#0 + BNE SVC_User /* User SVC Number > 0 */ + + MOV LR,R4 + LDMIA R0,{R0-R3,R4} /* Read R0-R3,R12 from stack */ + MOV R12,R4 + MOV R4,LR + BLX R12 /* Call SVC Function */ + + MRS R3,PSP /* Read PSP */ + STMIA R3!,{R0-R2} /* Store return values */ + + LDR R3,=os_tsk + LDMIA R3!,{R1,R2} /* os_tsk.run, os_tsk.new */ + CMP R1,R2 + BEQ SVC_Exit /* no task switch */ + + SUBS R3,#8 + CMP R1,#0 /* Runtask deleted? */ + BEQ SVC_Next + + MRS R0,PSP /* Read PSP */ + SUBS R0,R0,#32 /* Adjust Start Address */ + STR R0,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ + STMIA R0!,{R4-R7} /* Save old context (R4-R7) */ + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} /* Save old context (R8-R11) */ + + PUSH {R2,R3} + BL rt_stk_check /* Check for Stack overflow */ + POP {R2,R3} + +SVC_Next: + STR R2,[R3] /* os_tsk.run = os_tsk.new */ + + LDR R0,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ + ADDS R0,R0,#16 /* Adjust Start Address */ + LDMIA R0!,{R4-R7} /* Restore new Context (R8-R11) */ + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 /* Write PSP */ + SUBS R0,R0,#32 /* Adjust Start Address */ + LDMIA R0!,{R4-R7} /* Restore new Context (R4-R7) */ + +SVC_Exit: + MOVS R0,#~0xFFFFFFFD /* Set EXC_RETURN value */ + MVNS R0,R0 + BX R0 /* RETI to Thread Mode, use PSP */ + + /*------------------- User SVC ------------------------------*/ + +SVC_User: + PUSH {R4,LR} /* Save Registers */ + LDR R2,=SVC_Count + LDR R2,[R2] + CMP R1,R2 + BHI SVC_Done /* Overflow */ + + LDR R4,=SVC_Table-4 + LSLS R1,R1,#2 + LDR R4,[R4,R1] /* Load SVC Function Address */ + MOV LR,R4 + + LDMIA R0,{R0-R3,R4} /* Read R0-R3,R12 from stack */ + MOV R12,R4 + BLX LR /* Call SVC Function */ + + MRS R4,PSP /* Read PSP */ + STMIA R4!,{R0-R3} /* Function return values */ +SVC_Done: + POP {R4,PC} /* RETI */ + + .fnend + .size SVC_Handler, .-SVC_Handler + + +/*-------------------------- PendSV_Handler ---------------------------------*/ + +# void PendSV_Handler (void); + + .thumb_func + .type PendSV_Handler, %function + .global PendSV_Handler + .global Sys_Switch +PendSV_Handler: + .fnstart + .cantunwind + + BL rt_pop_req + +Sys_Switch: + LDR R3,=os_tsk + LDMIA R3!,{R1,R2} /* os_tsk.run, os_tsk.new */ + CMP R1,R2 + BEQ Sys_Exit /* no task switch */ + + SUBS R3,#8 + + MRS R0,PSP /* Read PSP */ + SUBS R0,R0,#32 /* Adjust Start Address */ + STR R0,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ + STMIA R0!,{R4-R7} /* Save old context (R4-R7) */ + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} /* Save old context (R8-R11) */ + + PUSH {R2,R3} + BL rt_stk_check /* Check for Stack overflow */ + POP {R2,R3} + + STR R2,[R3] /* os_tsk.run = os_tsk.new */ + + LDR R0,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ + ADDS R0,R0,#16 /* Adjust Start Address */ + LDMIA R0!,{R4-R7} /* Restore new Context (R8-R11) */ + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 /* Write PSP */ + SUBS R0,R0,#32 /* Adjust Start Address */ + LDMIA R0!,{R4-R7} /* Restore new Context (R4-R7) */ + +Sys_Exit: + MOVS R0,#~0xFFFFFFFD /* Set EXC_RETURN value */ + MVNS R0,R0 + BX R0 /* RETI to Thread Mode, use PSP */ + + .fnend + .size PendSV_Handler, .-PendSV_Handler + + +/*-------------------------- SysTick_Handler --------------------------------*/ + +# void SysTick_Handler (void); + + .thumb_func + .type SysTick_Handler, %function + .global SysTick_Handler +SysTick_Handler: + .fnstart + .cantunwind + + BL rt_systick + B Sys_Switch + + .fnend + .size SysTick_Handler, .-SysTick_Handler + + +/*-------------------------- OS_Tick_Handler --------------------------------*/ + +# void OS_Tick_Handler (void); + + .thumb_func + .type OS_Tick_Handler, %function + .global OS_Tick_Handler +OS_Tick_Handler: + .fnstart + .cantunwind + + BL os_tick_irqack + BL rt_systick + B Sys_Switch + + .fnend + .size OS_Tick_Handler, .-OS_Tick_Handler + + + .end + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/SVC_Table.s Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,56 @@ +;/*---------------------------------------------------------------------------- +; * RL-ARM - RTX +; *---------------------------------------------------------------------------- +; * Name: SVC_TABLE.S +; * Purpose: Pre-defined SVC Table for Cortex-M +; * Rev.: V4.60 +; *---------------------------------------------------------------------------- +; * +; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH +; * All rights reserved. +; * Redistribution and use in source and binary forms, with or without +; * modification, are permitted provided that the following conditions are met: +; * - Redistributions of source code must retain the above copyright +; * notice, this list of conditions and the following disclaimer. +; * - Redistributions in binary form must reproduce the above copyright +; * notice, this list of conditions and the following disclaimer in the +; * documentation and/or other materials provided with the distribution. +; * - Neither the name of ARM nor the names of its contributors may be used +; * to endorse or promote products derived from this software without +; * specific prior written permission. +; * +; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE +; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; * POSSIBILITY OF SUCH DAMAGE. +; *---------------------------------------------------------------------------*/ + + + .file "SVC_Table.S" + + + .section ".svc_table" + + .global SVC_Table +SVC_Table: +/* Insert user SVC functions here. SVC 0 used by RTL Kernel. */ +# .long __SVC_1 /* user SVC function */ +SVC_End: + + .global SVC_Count +SVC_Count: + .long (SVC_End-SVC_Table)/4 + + + .end + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/HAL_CM3.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,249 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: HAL_CM3.C + * Purpose: Hardware Abstraction Layer for Cortex-M3 + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_System.h" +#include "rt_HAL_CM.h" +#include "rt_Task.h" +#include "rt_MemBox.h" + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_set_PSP ------------------------------------*/ + +__asm void rt_set_PSP (U32 stack) { + MSR PSP,R0 + BX LR +} + + +/*--------------------------- rt_get_PSP ------------------------------------*/ + +__asm U32 rt_get_PSP (void) { + MRS R0,PSP + BX LR +} + + +/*--------------------------- os_set_env ------------------------------------*/ + +__asm void os_set_env (void) { + /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ + MOV R0,SP ; PSP = MSP + MSR PSP,R0 + LDR R0,=__cpp(&os_flags) + LDRB R0,[R0] + LSLS R0,#31 + MOVNE R0,#0x02 ; Privileged Thread mode, use PSP + MOVEQ R0,#0x03 ; Unprivileged Thread mode, use PSP + MSR CONTROL,R0 + BX LR + + ALIGN +} + + +/*--------------------------- _alloc_box ------------------------------------*/ + +__asm void *_alloc_box (void *box_mem) { + /* Function wrapper for Unprivileged/Privileged mode. */ + LDR R12,=__cpp(rt_alloc_box) + MRS R3,IPSR + LSLS R3,#24 + BXNE R12 + MRS R3,CONTROL + LSLS R3,#31 + BXEQ R12 + SVC 0 + BX LR + + ALIGN +} + + +/*--------------------------- _free_box -------------------------------------*/ + +__asm int _free_box (void *box_mem, void *box) { + /* Function wrapper for Unprivileged/Privileged mode. */ + LDR R12,=__cpp(rt_free_box) + MRS R3,IPSR + LSLS R3,#24 + BXNE R12 + MRS R3,CONTROL + LSLS R3,#31 + BXEQ R12 + SVC 0 + BX LR + + ALIGN +} + + +/*-------------------------- SVC_Handler ------------------------------------*/ + +__asm void SVC_Handler (void) { + PRESERVE8 + + IMPORT SVC_Count + IMPORT SVC_Table + IMPORT rt_stk_check + + MRS R0,PSP ; Read PSP + LDR R1,[R0,#24] ; Read Saved PC from Stack + LDRB R1,[R1,#-2] ; Load SVC Number + CBNZ R1,SVC_User + + LDM R0,{R0-R3,R12} ; Read R0-R3,R12 from stack + BLX R12 ; Call SVC Function + + MRS R12,PSP ; Read PSP + STM R12,{R0-R2} ; Store return values + + LDR R3,=__cpp(&os_tsk) + LDM R3,{R1,R2} ; os_tsk.run, os_tsk.new + CMP R1,R2 + BEQ SVC_Exit ; no task switch + + CBZ R1,SVC_Next ; Runtask deleted? + STMDB R12!,{R4-R11} ; Save Old context + STR R12,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack + + PUSH {R2,R3} + BL rt_stk_check ; Check for Stack overflow + POP {R2,R3} + +SVC_Next + STR R2,[R3] ; os_tsk.run = os_tsk.new + + LDR R12,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack + LDMIA R12!,{R4-R11} ; Restore New Context + MSR PSP,R12 ; Write PSP + +SVC_Exit + MVN LR,#:NOT:0xFFFFFFFD ; set EXC_RETURN value + BX LR + + /*------------------- User SVC ------------------------------*/ + +SVC_User + PUSH {R4,LR} ; Save Registers + LDR R2,=SVC_Count + LDR R2,[R2] + CMP R1,R2 + BHI SVC_Done ; Overflow + + LDR R4,=SVC_Table-4 + LDR R4,[R4,R1,LSL #2] ; Load SVC Function Address + + LDM R0,{R0-R3,R12} ; Read R0-R3,R12 from stack + BLX R4 ; Call SVC Function + + MRS R12,PSP + STM R12,{R0-R3} ; Function return values +SVC_Done + POP {R4,PC} ; RETI + + ALIGN +} + + +/*-------------------------- PendSV_Handler ---------------------------------*/ + +__asm void PendSV_Handler (void) { + PRESERVE8 + + BL __cpp(rt_pop_req) + +Sys_Switch + LDR R3,=__cpp(&os_tsk) + LDM R3,{R1,R2} ; os_tsk.run, os_tsk.new + CMP R1,R2 + BEQ Sys_Exit + + MRS R12,PSP ; Read PSP + STMDB R12!,{R4-R11} ; Save Old context + STR R12,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack + + PUSH {R2,R3} + BL rt_stk_check ; Check for Stack overflow + POP {R2,R3} + + STR R2,[R3] ; os_tsk.run = os_tsk.new + + LDR R12,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack + LDMIA R12!,{R4-R11} ; Restore New Context + MSR PSP,R12 ; Write PSP + +Sys_Exit + MVN LR,#:NOT:0xFFFFFFFD ; set EXC_RETURN value + BX LR ; Return to Thread Mode + + ALIGN +} + + +/*-------------------------- SysTick_Handler --------------------------------*/ + +__asm void SysTick_Handler (void) { + PRESERVE8 + + BL __cpp(rt_systick) + B Sys_Switch + + ALIGN +} + + +/*-------------------------- OS_Tick_Handler --------------------------------*/ + +__asm void OS_Tick_Handler (void) { + PRESERVE8 + + BL __cpp(os_tick_irqack) + BL __cpp(rt_systick) + B Sys_Switch + + ALIGN +} + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/SVC_Table.s Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,57 @@ +;/*---------------------------------------------------------------------------- +; * RL-ARM - RTX +; *---------------------------------------------------------------------------- +; * Name: SVC_TABLE.S +; * Purpose: Pre-defined SVC Table for Cortex-M +; * Rev.: V4.60 +; *---------------------------------------------------------------------------- +; * +; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH +; * All rights reserved. +; * Redistribution and use in source and binary forms, with or without +; * modification, are permitted provided that the following conditions are met: +; * - Redistributions of source code must retain the above copyright +; * notice, this list of conditions and the following disclaimer. +; * - Redistributions in binary form must reproduce the above copyright +; * notice, this list of conditions and the following disclaimer in the +; * documentation and/or other materials provided with the distribution. +; * - Neither the name of ARM nor the names of its contributors may be used +; * to endorse or promote products derived from this software without +; * specific prior written permission. +; * +; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE +; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; * POSSIBILITY OF SUCH DAMAGE. +; *---------------------------------------------------------------------------*/ + + + AREA SVC_TABLE, CODE, READONLY + + EXPORT SVC_Count + +SVC_Cnt EQU (SVC_End-SVC_Table)/4 +SVC_Count DCD SVC_Cnt + +; Import user SVC functions here. +; IMPORT __SVC_1 + + EXPORT SVC_Table +SVC_Table +; Insert user SVC functions here. SVC 0 used by RTL Kernel. +; DCD __SVC_1 ; user SVC function + +SVC_End + + END + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/HAL_CM3.s Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,323 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: HAL_CM3.S + * Purpose: Hardware Abstraction Layer for Cortex-M3 + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + + .file "HAL_CM3.S" + .syntax unified + + .equ TCB_TSTACK, 36 + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + .thumb + + .section ".text" + .align 2 + + +/*--------------------------- rt_set_PSP ------------------------------------*/ + +# void rt_set_PSP (U32 stack); + + .thumb_func + .type rt_set_PSP, %function + .global rt_set_PSP +rt_set_PSP: + .fnstart + .cantunwind + + MSR PSP,R0 + BX LR + + .fnend + .size rt_set_PSP, .-rt_set_PSP + + +/*--------------------------- rt_get_PSP ------------------------------------*/ + +# U32 rt_get_PSP (void); + + .thumb_func + .type rt_get_PSP, %function + .global rt_get_PSP +rt_get_PSP: + .fnstart + .cantunwind + + MRS R0,PSP + BX LR + + .fnend + .size rt_get_PSP, .-rt_get_PSP + + +/*--------------------------- os_set_env ------------------------------------*/ + +# void os_set_env (void); + /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ + + .thumb_func + .type os_set_env, %function + .global os_set_env +os_set_env: + .fnstart + .cantunwind + + MOV R0,SP /* PSP = MSP */ + MSR PSP,R0 + LDR R0,=os_flags + LDRB R0,[R0] + LSLS R0,#31 + ITE NE + MOVNE R0,#0x02 /* Privileged Thread mode, use PSP */ + MOVEQ R0,#0x03 /* Unprivileged Thread mode, use PSP */ + MSR CONTROL,R0 + BX LR + + .fnend + .size os_set_env, .-os_set_env + + +/*--------------------------- _alloc_box ------------------------------------*/ + +# void *_alloc_box (void *box_mem); + /* Function wrapper for Unprivileged/Privileged mode. */ + + .thumb_func + .type _alloc_box, %function + .global _alloc_box +_alloc_box: + .fnstart + .cantunwind + + LDR R12,=rt_alloc_box + MRS R3,IPSR + LSLS R3,#24 + IT NE + BXNE R12 + MRS R3,CONTROL + LSLS R3,#31 + IT EQ + BXEQ R12 + SVC 0 + BX LR + + .fnend + .size _alloc_box, .-_alloc_box + + +/*--------------------------- _free_box -------------------------------------*/ + +# int _free_box (void *box_mem, void *box); + /* Function wrapper for Unprivileged/Privileged mode. */ + + .thumb_func + .type _free_box, %function + .global _free_box +_free_box: + .fnstart + .cantunwind + + LDR R12,=rt_free_box + MRS R3,IPSR + LSLS R3,#24 + IT NE + BXNE R12 + MRS R3,CONTROL + LSLS R3,#31 + IT EQ + BXEQ R12 + SVC 0 + BX LR + + .fnend + .size _free_box, .-_free_box + + +/*-------------------------- SVC_Handler ------------------------------------*/ + +# void SVC_Handler (void); + + .thumb_func + .type SVC_Handler, %function + .global SVC_Handler +SVC_Handler: + .fnstart + .cantunwind + + MRS R0,PSP /* Read PSP */ + LDR R1,[R0,#24] /* Read Saved PC from Stack */ + LDRB R1,[R1,#-2] /* Load SVC Number */ + CBNZ R1,SVC_User + + LDM R0,{R0-R3,R12} /* Read R0-R3,R12 from stack */ + BLX R12 /* Call SVC Function */ + + MRS R12,PSP /* Read PSP */ + STM R12,{R0-R2} /* Store return values */ + + LDR R3,=os_tsk + LDM R3,{R1,R2} /* os_tsk.run, os_tsk.new */ + CMP R1,R2 + BEQ SVC_Exit /* no task switch */ + + CBZ R1,SVC_Next /* Runtask deleted? */ + STMDB R12!,{R4-R11} /* Save Old context */ + STR R12,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ + + PUSH {R2,R3} + BL rt_stk_check /* Check for Stack overflow */ + POP {R2,R3} + +SVC_Next: + STR R2,[R3] /* os_tsk.run = os_tsk.new */ + + LDR R12,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ + LDMIA R12!,{R4-R11} /* Restore New Context */ + MSR PSP,R12 /* Write PSP */ + +SVC_Exit: + MVN LR,#~0xFFFFFFFD /* set EXC_RETURN value */ + BX LR + + /*------------------- User SVC ------------------------------*/ + +SVC_User: + PUSH {R4,LR} /* Save Registers */ + LDR R2,=SVC_Count + LDR R2,[R2] + CMP R1,R2 + BHI SVC_Done /* Overflow */ + + LDR R4,=SVC_Table-4 + LDR R4,[R4,R1,LSL #2] /* Load SVC Function Address */ + + LDM R0,{R0-R3,R12} /* Read R0-R3,R12 from stack */ + BLX R4 /* Call SVC Function */ + + MRS R12,PSP + STM R12,{R0-R3} /* Function return values */ +SVC_Done: + POP {R4,PC} /* RETI */ + + .fnend + .size SVC_Handler, .-SVC_Handler + + +/*-------------------------- PendSV_Handler ---------------------------------*/ + +# void PendSV_Handler (void); + + .thumb_func + .type PendSV_Handler, %function + .global PendSV_Handler + .global Sys_Switch +PendSV_Handler: + .fnstart + .cantunwind + + BL rt_pop_req + +Sys_Switch: + LDR R3,=os_tsk + LDM R3,{R1,R2} /* os_tsk.run, os_tsk.new */ + CMP R1,R2 + BEQ Sys_Exit + + MRS R12,PSP /* Read PSP */ + STMDB R12!,{R4-R11} /* Save Old context */ + STR R12,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ + + PUSH {R2,R3} + BL rt_stk_check /* Check for Stack overflow */ + POP {R2,R3} + + STR R2,[R3] /* os_tsk.run = os_tsk.new */ + + LDR R12,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ + LDMIA R12!,{R4-R11} /* Restore New Context */ + MSR PSP,R12 /* Write PSP */ + +Sys_Exit: + MVN LR,#~0xFFFFFFFD /* set EXC_RETURN value */ + BX LR /* Return to Thread Mode */ + + .fnend + .size PendSV_Handler, .-PendSV_Handler + + +/*-------------------------- SysTick_Handler --------------------------------*/ + +# void SysTick_Handler (void); + + .thumb_func + .type SysTick_Handler, %function + .global SysTick_Handler +SysTick_Handler: + .fnstart + .cantunwind + + BL rt_systick + B Sys_Switch + + .fnend + .size SysTick_Handler, .-SysTick_Handler + + +/*-------------------------- OS_Tick_Handler --------------------------------*/ + +# void OS_Tick_Handler (void); + + .thumb_func + .type OS_Tick_Handler, %function + .global OS_Tick_Handler +OS_Tick_Handler: + .fnstart + .cantunwind + + BL os_tick_irqack + BL rt_systick + B Sys_Switch + + .fnend + .size OS_Tick_Handler, .-OS_Tick_Handler + + + .end + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/SVC_Table.s Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,56 @@ +;/*---------------------------------------------------------------------------- +; * RL-ARM - RTX +; *---------------------------------------------------------------------------- +; * Name: SVC_TABLE.S +; * Purpose: Pre-defined SVC Table for Cortex-M +; * Rev.: V4.60 +; *---------------------------------------------------------------------------- +; * +; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH +; * All rights reserved. +; * Redistribution and use in source and binary forms, with or without +; * modification, are permitted provided that the following conditions are met: +; * - Redistributions of source code must retain the above copyright +; * notice, this list of conditions and the following disclaimer. +; * - Redistributions in binary form must reproduce the above copyright +; * notice, this list of conditions and the following disclaimer in the +; * documentation and/or other materials provided with the distribution. +; * - Neither the name of ARM nor the names of its contributors may be used +; * to endorse or promote products derived from this software without +; * specific prior written permission. +; * +; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE +; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; * POSSIBILITY OF SUCH DAMAGE. +; *---------------------------------------------------------------------------*/ + + + .file "SVC_Table.S" + + + .section ".svc_table" + + .global SVC_Table +SVC_Table: +/* Insert user SVC functions here. SVC 0 used by RTL Kernel. */ +# .long __SVC_1 /* user SVC function */ +SVC_End: + + .global SVC_Count +SVC_Count: + .long (SVC_End-SVC_Table)/4 + + + .end + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_ARM/HAL_CM4.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,309 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: HAL_CM4.C + * Purpose: Hardware Abstraction Layer for Cortex-M4 + * Rev.: V4.70 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_System.h" +#include "rt_HAL_CM.h" +#include "rt_Task.h" +#include "rt_MemBox.h" + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_set_PSP ------------------------------------*/ + +__asm void rt_set_PSP (U32 stack) { + MSR PSP,R0 + BX LR +} + + +/*--------------------------- rt_get_PSP ------------------------------------*/ + +__asm U32 rt_get_PSP (void) { + MRS R0,PSP + BX LR +} + + +/*--------------------------- os_set_env ------------------------------------*/ + +__asm void os_set_env (void) { + /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ + MOV R0,SP ; PSP = MSP + MSR PSP,R0 + LDR R0,=__cpp(&os_flags) + LDRB R0,[R0] + LSLS R0,#31 + MOVNE R0,#0x02 ; Privileged Thread mode, use PSP + MOVEQ R0,#0x03 ; Unprivileged Thread mode, use PSP + MSR CONTROL,R0 + BX LR + + ALIGN +} + + +/*--------------------------- _alloc_box ------------------------------------*/ + +__asm void *_alloc_box (void *box_mem) { + /* Function wrapper for Unprivileged/Privileged mode. */ + LDR R12,=__cpp(rt_alloc_box) + MRS R3,IPSR + LSLS R3,#24 + BXNE R12 + MRS R3,CONTROL + LSLS R3,#31 + BXEQ R12 + SVC 0 + BX LR + + ALIGN +} + + +/*--------------------------- _free_box -------------------------------------*/ + +__asm int _free_box (void *box_mem, void *box) { + /* Function wrapper for Unprivileged/Privileged mode. */ + LDR R12,=__cpp(rt_free_box) + MRS R3,IPSR + LSLS R3,#24 + BXNE R12 + MRS R3,CONTROL + LSLS R3,#31 + BXEQ R12 + SVC 0 + BX LR + + ALIGN +} + + +/*-------------------------- SVC_Handler ------------------------------------*/ + +__asm void SVC_Handler (void) { + PRESERVE8 + + IMPORT SVC_Count + IMPORT SVC_Table + IMPORT rt_stk_check + +#ifdef IFX_XMC4XXX + EXPORT SVC_Handler_Veneer +SVC_Handler_Veneer +#endif + + MRS R0,PSP ; Read PSP + LDR R1,[R0,#24] ; Read Saved PC from Stack + LDRB R1,[R1,#-2] ; Load SVC Number + CBNZ R1,SVC_User + + LDM R0,{R0-R3,R12} ; Read R0-R3,R12 from stack + PUSH {R4,LR} ; Save EXC_RETURN + BLX R12 ; Call SVC Function + POP {R4,LR} ; Restore EXC_RETURN + + MRS R12,PSP ; Read PSP + STM R12,{R0-R2} ; Store return values + + LDR R3,=__cpp(&os_tsk) + LDM R3,{R1,R2} ; os_tsk.run, os_tsk.new + CMP R1,R2 +#ifdef IFX_XMC4XXX + PUSHEQ {LR} + POPEQ {PC} +#else + BXEQ LR ; RETI, no task switch +#endif + + CBZ R1,SVC_Next ; Runtask deleted? + TST LR,#0x10 ; is it extended frame? + VSTMDBEQ R12!,{S16-S31} ; yes, stack also VFP hi-regs + MOVEQ R0,#0x01 ; os_tsk->stack_frame val + MOVNE R0,#0x00 + STRB R0,[R1,#TCB_STACKF] ; os_tsk.run->stack_frame = val + STMDB R12!,{R4-R11} ; Save Old context + STR R12,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack + + PUSH {R2,R3} + BL rt_stk_check ; Check for Stack overflow + POP {R2,R3} + +SVC_Next + STR R2,[R3] ; os_tsk.run = os_tsk.new + + LDR R12,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack + LDMIA R12!,{R4-R11} ; Restore New Context + LDRB R0,[R2,#TCB_STACKF] ; Stack Frame + CMP R0,#0 ; Basic/Extended Stack Frame + VLDMIANE R12!,{S16-S31} ; restore VFP hi-registers + MVNNE LR,#:NOT:0xFFFFFFED ; set EXC_RETURN value + MVNEQ LR,#:NOT:0xFFFFFFFD + MSR PSP,R12 ; Write PSP + +SVC_Exit +#ifdef IFX_XMC4XXX + PUSH {LR} + POP {PC} +#else + BX LR +#endif + + /*------------------- User SVC ------------------------------*/ + +SVC_User + PUSH {R4,LR} ; Save Registers + LDR R2,=SVC_Count + LDR R2,[R2] + CMP R1,R2 + BHI SVC_Done ; Overflow + + LDR R4,=SVC_Table-4 + LDR R4,[R4,R1,LSL #2] ; Load SVC Function Address + + LDM R0,{R0-R3,R12} ; Read R0-R3,R12 from stack + BLX R4 ; Call SVC Function + + MRS R12,PSP + STM R12,{R0-R3} ; Function return values +SVC_Done + POP {R4,PC} ; RETI + + ALIGN +} + + +/*-------------------------- PendSV_Handler ---------------------------------*/ + +__asm void PendSV_Handler (void) { + PRESERVE8 + +#ifdef IFX_XMC4XXX + EXPORT PendSV_Handler_Veneer +PendSV_Handler_Veneer +#endif + + PUSH {R4,LR} ; Save EXC_RETURN + BL __cpp(rt_pop_req) + +Sys_Switch + POP {R4,LR} ; Restore EXC_RETURN + + LDR R3,=__cpp(&os_tsk) + LDM R3,{R1,R2} ; os_tsk.run, os_tsk.new + CMP R1,R2 +#ifdef IFX_XMC4XXX + PUSHEQ {LR} + POPEQ {PC} +#else + BXEQ LR ; RETI, no task switch +#endif + + MRS R12,PSP ; Read PSP + TST LR,#0x10 ; is it extended frame? + VSTMDBEQ R12!,{S16-S31} ; yes, stack also VFP hi-regs + MOVEQ R0,#0x01 ; os_tsk->stack_frame val + MOVNE R0,#0x00 + STRB R0,[R1,#TCB_STACKF] ; os_tsk.run->stack_frame = val + STMDB R12!,{R4-R11} ; Save Old context + STR R12,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack + + PUSH {R2,R3} + BL rt_stk_check ; Check for Stack overflow + POP {R2,R3} + + STR R2,[R3] ; os_tsk.run = os_tsk.new + + LDR R12,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack + LDMIA R12!,{R4-R11} ; Restore New Context + LDRB R0,[R2,#TCB_STACKF] ; Stack Frame + CMP R0,#0 ; Basic/Extended Stack Frame + VLDMIANE R12!,{S16-S31} ; restore VFP hi-regs + MVNNE LR,#:NOT:0xFFFFFFED ; set EXC_RETURN value + MVNEQ LR,#:NOT:0xFFFFFFFD + MSR PSP,R12 ; Write PSP + +Sys_Exit +#ifdef IFX_XMC4XXX + PUSH {LR} + POP {PC} +#else + BX LR ; Return to Thread Mode +#endif + + ALIGN +} + + +/*-------------------------- SysTick_Handler --------------------------------*/ + +__asm void SysTick_Handler (void) { + PRESERVE8 + +#ifdef IFX_XMC4XXX + EXPORT SysTick_Handler_Veneer +SysTick_Handler_Veneer +#endif + + PUSH {R4,LR} ; Save EXC_RETURN + BL __cpp(rt_systick) + B Sys_Switch + + ALIGN +} + + +/*-------------------------- OS_Tick_Handler --------------------------------*/ + +__asm void OS_Tick_Handler (void) { + PRESERVE8 + + PUSH {R4,LR} ; Save EXC_RETURN + BL __cpp(os_tick_irqack) + BL __cpp(rt_systick) + B Sys_Switch + + ALIGN +} + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_ARM/SVC_Table.s Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,57 @@ +;/*---------------------------------------------------------------------------- +; * RL-ARM - RTX +; *---------------------------------------------------------------------------- +; * Name: SVC_TABLE.S +; * Purpose: Pre-defined SVC Table for Cortex-M +; * Rev.: V4.70 +; *---------------------------------------------------------------------------- +; * +; * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH +; * All rights reserved. +; * Redistribution and use in source and binary forms, with or without +; * modification, are permitted provided that the following conditions are met: +; * - Redistributions of source code must retain the above copyright +; * notice, this list of conditions and the following disclaimer. +; * - Redistributions in binary form must reproduce the above copyright +; * notice, this list of conditions and the following disclaimer in the +; * documentation and/or other materials provided with the distribution. +; * - Neither the name of ARM nor the names of its contributors may be used +; * to endorse or promote products derived from this software without +; * specific prior written permission. +; * +; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE +; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; * POSSIBILITY OF SUCH DAMAGE. +; *---------------------------------------------------------------------------*/ + + + AREA SVC_TABLE, CODE, READONLY + + EXPORT SVC_Count + +SVC_Cnt EQU (SVC_End-SVC_Table)/4 +SVC_Count DCD SVC_Cnt + +; Import user SVC functions here. +; IMPORT __SVC_1 + + EXPORT SVC_Table +SVC_Table +; Insert user SVC functions here. SVC 0 used by RTL Kernel. +; DCD __SVC_1 ; user SVC function + +SVC_End + + END + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_GCC/HAL_CM4.s Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,389 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: HAL_CM4.S + * Purpose: Hardware Abstraction Layer for Cortex-M4 + * Rev.: V4.70 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + + .file "HAL_CM4.S" + .syntax unified + + .equ TCB_STACKF, 32 + .equ TCB_TSTACK, 36 + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + .thumb + + .section ".text" + .align 2 + + +/*--------------------------- rt_set_PSP ------------------------------------*/ + +# void rt_set_PSP (U32 stack); + + .thumb_func + .type rt_set_PSP, %function + .global rt_set_PSP +rt_set_PSP: + .fnstart + .cantunwind + + MSR PSP,R0 + BX LR + + .fnend + .size rt_set_PSP, .-rt_set_PSP + + +/*--------------------------- rt_get_PSP ------------------------------------*/ + +# U32 rt_get_PSP (void); + + .thumb_func + .type rt_get_PSP, %function + .global rt_get_PSP +rt_get_PSP: + .fnstart + .cantunwind + + MRS R0,PSP + BX LR + + .fnend + .size rt_get_PSP, .-rt_get_PSP + + +/*--------------------------- os_set_env ------------------------------------*/ + +# void os_set_env (void); + /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ + + .thumb_func + .type os_set_env, %function + .global os_set_env +os_set_env: + .fnstart + .cantunwind + + MOV R0,SP /* PSP = MSP */ + MSR PSP,R0 + LDR R0,=os_flags + LDRB R0,[R0] + LSLS R0,#31 + ITE NE + MOVNE R0,#0x02 /* Privileged Thread mode, use PSP */ + MOVEQ R0,#0x03 /* Unprivileged Thread mode, use PSP */ + MSR CONTROL,R0 + BX LR + + .fnend + .size os_set_env, .-os_set_env + + +/*--------------------------- _alloc_box ------------------------------------*/ + +# void *_alloc_box (void *box_mem); + /* Function wrapper for Unprivileged/Privileged mode. */ + + .thumb_func + .type _alloc_box, %function + .global _alloc_box +_alloc_box: + .fnstart + .cantunwind + + LDR R12,=rt_alloc_box + MRS R3,IPSR + LSLS R3,#24 + IT NE + BXNE R12 + MRS R3,CONTROL + LSLS R3,#31 + IT EQ + BXEQ R12 + SVC 0 + BX LR + + .fnend + .size _alloc_box, .-_alloc_box + + +/*--------------------------- _free_box -------------------------------------*/ + +# int _free_box (void *box_mem, void *box); + /* Function wrapper for Unprivileged/Privileged mode. */ + + .thumb_func + .type _free_box, %function + .global _free_box +_free_box: + .fnstart + .cantunwind + + LDR R12,=rt_free_box + MRS R3,IPSR + LSLS R3,#24 + IT NE + BXNE R12 + MRS R3,CONTROL + LSLS R3,#31 + IT EQ + BXEQ R12 + SVC 0 + BX LR + + .fnend + .size _free_box, .-_free_box + + +/*-------------------------- SVC_Handler ------------------------------------*/ + +# void SVC_Handler (void); + + .thumb_func + .type SVC_Handler, %function + .global SVC_Handler +SVC_Handler: + .ifdef IFX_XMC4XXX + .global SVC_Handler_Veneer +SVC_Handler_Veneer: + .endif + .fnstart + .cantunwind + + MRS R0,PSP /* Read PSP */ + LDR R1,[R0,#24] /* Read Saved PC from Stack */ + LDRB R1,[R1,#-2] /* Load SVC Number */ + CBNZ R1,SVC_User + + LDM R0,{R0-R3,R12} /* Read R0-R3,R12 from stack */ + PUSH {R4,LR} /* Save EXC_RETURN */ + BLX R12 /* Call SVC Function */ + POP {R4,LR} /* Restore EXC_RETURN */ + + MRS R12,PSP /* Read PSP */ + STM R12,{R0-R2} /* Store return values */ + + LDR R3,=os_tsk + LDM R3,{R1,R2} /* os_tsk.run, os_tsk.new */ + CMP R1,R2 + .ifdef IFX_XMC4XXX + ITT EQ + PUSHEQ {LR} + POPEQ {PC} + .else + IT EQ + BXEQ LR /* RETI, no task switch */ + .endif + + CBZ R1,SVC_Next /* Runtask deleted? */ + TST LR,#0x10 /* is it extended frame? */ + ITTE EQ + VSTMDBEQ R12!,{S16-S31} /* yes, stack also VFP hi-regs */ + MOVEQ R0,#0x01 /* os_tsk->stack_frame val */ + MOVNE R0,#0x00 + STRB R0,[R1,#TCB_STACKF] /* os_tsk.run->stack_frame = val */ + STMDB R12!,{R4-R11} /* Save Old context */ + STR R12,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ + + PUSH {R2,R3} + BL rt_stk_check /* Check for Stack overflow */ + POP {R2,R3} + +SVC_Next: + STR R2,[R3] /* os_tsk.run = os_tsk.new */ + + LDR R12,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ + LDMIA R12!,{R4-R11} /* Restore New Context */ + LDRB R0,[R2,#TCB_STACKF] /* Stack Frame */ + CMP R0,#0 /* Basic/Extended Stack Frame */ + ITTE NE + VLDMIANE R12!,{S16-S31} /* restore VFP hi-registers */ + MVNNE LR,#~0xFFFFFFED /* set EXC_RETURN value */ + MVNEQ LR,#~0xFFFFFFFD + MSR PSP,R12 /* Write PSP */ + +SVC_Exit: + .ifdef IFX_XMC4XXX + PUSH {LR} + POP {PC} + .else + BX LR + .endif + + /*------------------- User SVC ------------------------------*/ + +SVC_User: + PUSH {R4,LR} /* Save Registers */ + LDR R2,=SVC_Count + LDR R2,[R2] + CMP R1,R2 + BHI SVC_Done /* Overflow */ + + LDR R4,=SVC_Table-4 + LDR R4,[R4,R1,LSL #2] /* Load SVC Function Address */ + + LDM R0,{R0-R3,R12} /* Read R0-R3,R12 from stack */ + BLX R4 /* Call SVC Function */ + + MRS R12,PSP + STM R12,{R0-R3} /* Function return values */ +SVC_Done: + POP {R4,PC} /* RETI */ + + .fnend + .size SVC_Handler, .-SVC_Handler + + +/*-------------------------- PendSV_Handler ---------------------------------*/ + +# void PendSV_Handler (void); + + .thumb_func + .type PendSV_Handler, %function + .global PendSV_Handler + .global Sys_Switch +PendSV_Handler: + .ifdef IFX_XMC4XXX + .global PendSV_Handler_Veneer +PendSV_Handler_Veneer: + .endif + .fnstart + .cantunwind + + PUSH {R4,LR} /* Save EXC_RETURN */ + BL rt_pop_req + +Sys_Switch: + POP {R4,LR} /* Restore EXC_RETURN */ + + LDR R3,=os_tsk + LDM R3,{R1,R2} /* os_tsk.run, os_tsk.new */ + CMP R1,R2 + .ifdef IFX_XMC4XXX + ITT EQ + PUSHEQ {LR} + POPEQ {PC} + .else + IT EQ + BXEQ LR /* RETI, no task switch */ + .endif + + MRS R12,PSP /* Read PSP */ + TST LR,#0x10 /* is it extended frame? */ + ITTE EQ + VSTMDBEQ R12!,{S16-S31} /* yes, stack also VFP hi-regs */ + MOVEQ R0,#0x01 /* os_tsk->stack_frame val */ + MOVNE R0,#0x00 + STRB R0,[R1,#TCB_STACKF] /* os_tsk.run->stack_frame = val */ + STMDB R12!,{R4-R11} /* Save Old context */ + STR R12,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ + + PUSH {R2,R3} + BL rt_stk_check /* Check for Stack overflow */ + POP {R2,R3} + + STR R2,[R3] /* os_tsk.run = os_tsk.new */ + + LDR R12,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ + LDMIA R12!,{R4-R11} /* Restore New Context */ + LDRB R0,[R2,#TCB_STACKF] /* Stack Frame */ + CMP R0,#0 /* Basic/Extended Stack Frame */ + ITTE NE + VLDMIANE R12!,{S16-S31} /* restore VFP hi-registers */ + MVNNE LR,#~0xFFFFFFED /* set EXC_RETURN value */ + MVNEQ LR,#~0xFFFFFFFD + MSR PSP,R12 /* Write PSP */ + +Sys_Exit: + .ifdef IFX_XMC4XXX + PUSH {LR} + POP {PC} + .else + BX LR /* Return to Thread Mode */ + .endif + + .fnend + .size PendSV_Handler, .-PendSV_Handler + + +/*-------------------------- SysTick_Handler --------------------------------*/ + +# void SysTick_Handler (void); + + .thumb_func + .type SysTick_Handler, %function + .global SysTick_Handler +SysTick_Handler: + .ifdef IFX_XMC4XXX + .global SysTick_Handler_Veneer +SysTick_Handler_Veneer: + .endif + .fnstart + .cantunwind + + PUSH {R4,LR} /* Save EXC_RETURN */ + BL rt_systick + B Sys_Switch + + .fnend + .size SysTick_Handler, .-SysTick_Handler + + +/*-------------------------- OS_Tick_Handler --------------------------------*/ + +# void OS_Tick_Handler (void); + + .thumb_func + .type OS_Tick_Handler, %function + .global OS_Tick_Handler +OS_Tick_Handler: + .fnstart + .cantunwind + + PUSH {R4,LR} /* Save EXC_RETURN */ + BL os_tick_irqack + BL rt_systick + B Sys_Switch + + .fnend + .size OS_Tick_Handler, .-OS_Tick_Handler + + + .end + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_GCC/SVC_Table.s Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,56 @@ +;/*---------------------------------------------------------------------------- +; * RL-ARM - RTX +; *---------------------------------------------------------------------------- +; * Name: SVC_TABLE.S +; * Purpose: Pre-defined SVC Table for Cortex-M +; * Rev.: V4.70 +; *---------------------------------------------------------------------------- +; * +; * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH +; * All rights reserved. +; * Redistribution and use in source and binary forms, with or without +; * modification, are permitted provided that the following conditions are met: +; * - Redistributions of source code must retain the above copyright +; * notice, this list of conditions and the following disclaimer. +; * - Redistributions in binary form must reproduce the above copyright +; * notice, this list of conditions and the following disclaimer in the +; * documentation and/or other materials provided with the distribution. +; * - Neither the name of ARM nor the names of its contributors may be used +; * to endorse or promote products derived from this software without +; * specific prior written permission. +; * +; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE +; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +; * POSSIBILITY OF SUCH DAMAGE. +; *---------------------------------------------------------------------------*/ + + + .file "SVC_Table.S" + + + .section ".svc_table" + + .global SVC_Table +SVC_Table: +/* Insert user SVC functions here. SVC 0 used by RTL Kernel. */ +# .long __SVC_1 /* user SVC function */ +SVC_End: + + .global SVC_Count +SVC_Count: + .long (SVC_End-SVC_Table)/4 + + + .end + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/cmsis_os.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,772 @@ +/* ---------------------------------------------------------------------- + * Copyright (C) 2012 ARM Limited. All rights reserved. + * + * $Date: 5. June 2012 + * $Revision: V1.01 + * + * Project: CMSIS-RTOS API + * Title: cmsis_os.h RTX header file + * + * Version 0.02 + * Initial Proposal Phase + * Version 0.03 + * osKernelStart added, optional feature: main started as thread + * osSemaphores have standard behavior + * osTimerCreate does not start the timer, added osTimerStart + * osThreadPass is renamed to osThreadYield + * Version 1.01 + * Support for C++ interface + * - const attribute removed from the osXxxxDef_t typedef's + * - const attribute added to the osXxxxDef macros + * Added: osTimerDelete, osMutexDelete, osSemaphoreDelete + * Added: osKernelInitialize + * -------------------------------------------------------------------- */ + +/** +\page cmsis_os_h Header File Template: cmsis_os.h + +The file \b cmsis_os.h is a template header file for a CMSIS-RTOS compliant Real-Time Operating System (RTOS). +Each RTOS that is compliant with CMSIS-RTOS shall provide a specific \b cmsis_os.h header file that represents +its implementation. + +The file cmsis_os.h contains: + - CMSIS-RTOS API function definitions + - struct definitions for parameters and return types + - status and priority values used by CMSIS-RTOS API functions + - macros for defining threads and other kernel objects + + +<b>Name conventions and header file modifications</b> + +All definitions are prefixed with \b os to give an unique name space for CMSIS-RTOS functions. +Definitions that are prefixed \b os_ are not used in the application code but local to this header file. +All definitions and functions that belong to a module are grouped and have a common prefix, i.e. \b osThread. + +Definitions that are marked with <b>CAN BE CHANGED</b> can be adapted towards the needs of the actual CMSIS-RTOS implementation. +These definitions can be specific to the underlying RTOS kernel. + +Definitions that are marked with <b>MUST REMAIN UNCHANGED</b> cannot be altered. Otherwise the CMSIS-RTOS implementation is no longer +compliant to the standard. Note that some functions are optional and need not to be provided by every CMSIS-RTOS implementation. + + +<b>Function calls from interrupt service routines</b> + +The following CMSIS-RTOS functions can be called from threads and interrupt service routines (ISR): + - \ref osSignalSet + - \ref osSemaphoreRelease + - \ref osPoolAlloc, \ref osPoolCAlloc, \ref osPoolFree + - \ref osMessagePut, \ref osMessageGet + - \ref osMailAlloc, \ref osMailCAlloc, \ref osMailGet, \ref osMailPut, \ref osMailFree + +Functions that cannot be called from an ISR are verifying the interrupt status and return in case that they are called +from an ISR context the status code \b osErrorISR. In some implementations this condition might be caught using the HARD FAULT vector. + +Some CMSIS-RTOS implementations support CMSIS-RTOS function calls from multiple ISR at the same time. +If this is impossible, the CMSIS-RTOS rejects calls by nested ISR functions with the status code \b osErrorISRRecursive. + + +<b>Define and reference object definitions</b> + +With <b>\#define osObjectsExternal</b> objects are defined as external symbols. This allows to create a consistent header file +that is used throughout a project as shown below: + +<i>Header File</i> +\code +#include <cmsis_os.h> // CMSIS RTOS header file + +// Thread definition +extern void thread_sample (void const *argument); // function prototype +osThreadDef (thread_sample, osPriorityBelowNormal, 1, 100); + +// Pool definition +osPoolDef(MyPool, 10, long); +\endcode + + +This header file defines all objects when included in a C/C++ source file. When <b>\#define osObjectsExternal</b> is +present before the header file, the objects are defined as external symbols. A single consistent header file can therefore be +used throughout the whole project. + +<i>Example</i> +\code +#include "osObjects.h" // Definition of the CMSIS-RTOS objects +\endcode + +\code +#define osObjectExternal // Objects will be defined as external symbols +#include "osObjects.h" // Reference to the CMSIS-RTOS objects +\endcode + +*/ + +#ifndef _CMSIS_OS_H +#define _CMSIS_OS_H + +/// \note MUST REMAIN UNCHANGED: \b osCMSIS identifies the CMSIS-RTOS API version. +#define osCMSIS 0x10001 ///< API version (main [31:16] .sub [15:0]) + +/// \note CAN BE CHANGED: \b osCMSIS_KERNEL identifies the underlying RTOS kernel and version number. +#define osCMSIS_RTX ((4<<16)|61) ///< RTOS identification and version (main [31:16] .sub [15:0]) + +/// \note MUST REMAIN UNCHANGED: \b osKernelSystemId shall be consistent in every CMSIS-RTOS. +#define osKernelSystemId "RTX V4.61" ///< RTOS identification string + + +#define CMSIS_OS_RTX + +// The stack space occupied is mainly dependent on the underling C standard library +#if defined(TOOLCHAIN_GCC) || defined(TOOLCHAIN_ARM_STD) +# define WORDS_STACK_SIZE 512 +#elif defined(TOOLCHAIN_ARM_MICRO) +# define WORDS_STACK_SIZE 128 +#endif + +#define DEFAULT_STACK_SIZE (WORDS_STACK_SIZE*4) + + +/// \note MUST REMAIN UNCHANGED: \b osFeature_xxx shall be consistent in every CMSIS-RTOS. +#define osFeature_MainThread 1 ///< main thread 1=main can be thread, 0=not available +#define osFeature_Pool 1 ///< Memory Pools: 1=available, 0=not available +#define osFeature_MailQ 1 ///< Mail Queues: 1=available, 0=not available +#define osFeature_MessageQ 1 ///< Message Queues: 1=available, 0=not available +#define osFeature_Signals 16 ///< maximum number of Signal Flags available per thread +#define osFeature_Semaphore 65535 ///< maximum count for \ref osSemaphoreCreate function +#define osFeature_Wait 0 ///< osWait function: 1=available, 0=not available + +#if defined (__CC_ARM) +#define os_InRegs __value_in_regs // Compiler specific: force struct in registers +#else +#define os_InRegs +#endif + +#include <stdint.h> +#include <stddef.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "os_tcb.h" + +// ==== Enumeration, structures, defines ==== + +/// Priority used for thread control. +/// \note MUST REMAIN UNCHANGED: \b osPriority shall be consistent in every CMSIS-RTOS. +typedef enum { + osPriorityIdle = -3, ///< priority: idle (lowest) + osPriorityLow = -2, ///< priority: low + osPriorityBelowNormal = -1, ///< priority: below normal + osPriorityNormal = 0, ///< priority: normal (default) + osPriorityAboveNormal = +1, ///< priority: above normal + osPriorityHigh = +2, ///< priority: high + osPriorityRealtime = +3, ///< priority: realtime (highest) + osPriorityError = 0x84 ///< system cannot determine priority or thread has illegal priority +} osPriority; + +/// Timeout value. +/// \note MUST REMAIN UNCHANGED: \b osWaitForever shall be consistent in every CMSIS-RTOS. +#define osWaitForever 0xFFFFFFFF ///< wait forever timeout value + +/// Status code values returned by CMSIS-RTOS functions. +/// \note MUST REMAIN UNCHANGED: \b osStatus shall be consistent in every CMSIS-RTOS. +typedef enum { + osOK = 0, ///< function completed; no error or event occurred. + osEventSignal = 0x08, ///< function completed; signal event occurred. + osEventMessage = 0x10, ///< function completed; message event occurred. + osEventMail = 0x20, ///< function completed; mail event occurred. + osEventTimeout = 0x40, ///< function completed; timeout occurred. + osErrorParameter = 0x80, ///< parameter error: a mandatory parameter was missing or specified an incorrect object. + osErrorResource = 0x81, ///< resource not available: a specified resource was not available. + osErrorTimeoutResource = 0xC1, ///< resource not available within given time: a specified resource was not available within the timeout period. + osErrorISR = 0x82, ///< not allowed in ISR context: the function cannot be called from interrupt service routines. + osErrorISRRecursive = 0x83, ///< function called multiple times from ISR with same object. + osErrorPriority = 0x84, ///< system cannot determine priority or thread has illegal priority. + osErrorNoMemory = 0x85, ///< system is out of memory: it was impossible to allocate or reserve memory for the operation. + osErrorValue = 0x86, ///< value of a parameter is out of range. + osErrorOS = 0xFF, ///< unspecified RTOS error: run-time error but no other error message fits. + os_status_reserved = 0x7FFFFFFF ///< prevent from enum down-size compiler optimization. +} osStatus; + + +/// Timer type value for the timer definition. +/// \note MUST REMAIN UNCHANGED: \b os_timer_type shall be consistent in every CMSIS-RTOS. +typedef enum { + osTimerOnce = 0, ///< one-shot timer + osTimerPeriodic = 1 ///< repeating timer +} os_timer_type; + +/// Entry point of a thread. +/// \note MUST REMAIN UNCHANGED: \b os_pthread shall be consistent in every CMSIS-RTOS. +typedef void (*os_pthread) (void const *argument); + +/// Entry point of a timer call back function. +/// \note MUST REMAIN UNCHANGED: \b os_ptimer shall be consistent in every CMSIS-RTOS. +typedef void (*os_ptimer) (void const *argument); + +// >>> the following data type definitions may shall adapted towards a specific RTOS + +/// Thread ID identifies the thread (pointer to a thread control block). +/// \note CAN BE CHANGED: \b os_thread_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_thread_cb *osThreadId; + +/// Timer ID identifies the timer (pointer to a timer control block). +/// \note CAN BE CHANGED: \b os_timer_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_timer_cb *osTimerId; + +/// Mutex ID identifies the mutex (pointer to a mutex control block). +/// \note CAN BE CHANGED: \b os_mutex_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_mutex_cb *osMutexId; + +/// Semaphore ID identifies the semaphore (pointer to a semaphore control block). +/// \note CAN BE CHANGED: \b os_semaphore_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_semaphore_cb *osSemaphoreId; + +/// Pool ID identifies the memory pool (pointer to a memory pool control block). +/// \note CAN BE CHANGED: \b os_pool_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_pool_cb *osPoolId; + +/// Message ID identifies the message queue (pointer to a message queue control block). +/// \note CAN BE CHANGED: \b os_messageQ_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_messageQ_cb *osMessageQId; + +/// Mail ID identifies the mail queue (pointer to a mail queue control block). +/// \note CAN BE CHANGED: \b os_mailQ_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_mailQ_cb *osMailQId; + + +/// Thread Definition structure contains startup information of a thread. +/// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS. +typedef struct os_thread_def { + os_pthread pthread; ///< start address of thread function + osPriority tpriority; ///< initial thread priority + uint32_t stacksize; ///< stack size requirements in bytes + unsigned char *stack_pointer; ///< pointer to the stack memory block + struct OS_TCB tcb; +} osThreadDef_t; + +/// Timer Definition structure contains timer parameters. +/// \note CAN BE CHANGED: \b os_timer_def is implementation specific in every CMSIS-RTOS. +typedef struct os_timer_def { + os_ptimer ptimer; ///< start address of a timer function + void *timer; ///< pointer to internal data +} osTimerDef_t; + +/// Mutex Definition structure contains setup information for a mutex. +/// \note CAN BE CHANGED: \b os_mutex_def is implementation specific in every CMSIS-RTOS. +typedef struct os_mutex_def { + void *mutex; ///< pointer to internal data +} osMutexDef_t; + +/// Semaphore Definition structure contains setup information for a semaphore. +/// \note CAN BE CHANGED: \b os_semaphore_def is implementation specific in every CMSIS-RTOS. +typedef struct os_semaphore_def { + void *semaphore; ///< pointer to internal data +} osSemaphoreDef_t; + +/// Definition structure for memory block allocation. +/// \note CAN BE CHANGED: \b os_pool_def is implementation specific in every CMSIS-RTOS. +typedef struct os_pool_def { + uint32_t pool_sz; ///< number of items (elements) in the pool + uint32_t item_sz; ///< size of an item + void *pool; ///< pointer to memory for pool +} osPoolDef_t; + +/// Definition structure for message queue. +/// \note CAN BE CHANGED: \b os_messageQ_def is implementation specific in every CMSIS-RTOS. +typedef struct os_messageQ_def { + uint32_t queue_sz; ///< number of elements in the queue + void *pool; ///< memory array for messages +} osMessageQDef_t; + +/// Definition structure for mail queue. +/// \note CAN BE CHANGED: \b os_mailQ_def is implementation specific in every CMSIS-RTOS. +typedef struct os_mailQ_def { + uint32_t queue_sz; ///< number of elements in the queue + uint32_t item_sz; ///< size of an item + void *pool; ///< memory array for mail +} osMailQDef_t; + +/// Event structure contains detailed information about an event. +/// \note MUST REMAIN UNCHANGED: \b os_event shall be consistent in every CMSIS-RTOS. +/// However the struct may be extended at the end. +typedef struct { + osStatus status; ///< status code: event or error information + union { + uint32_t v; ///< message as 32-bit value + void *p; ///< message or mail as void pointer + int32_t signals; ///< signal flags + } value; ///< event value + union { + osMailQId mail_id; ///< mail id obtained by \ref osMailCreate + osMessageQId message_id; ///< message id obtained by \ref osMessageCreate + } def; ///< event definition +} osEvent; + + +// ==== Kernel Control Functions ==== + +/// Initialize the RTOS Kernel for creating objects. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osKernelInitialize shall be consistent in every CMSIS-RTOS. +osStatus osKernelInitialize (void); + +/// Start the RTOS Kernel. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osKernelStart shall be consistent in every CMSIS-RTOS. +osStatus osKernelStart (void); + +/// Check if the RTOS kernel is already started. +/// \note MUST REMAIN UNCHANGED: \b osKernelRunning shall be consistent in every CMSIS-RTOS. +/// \return 0 RTOS is not started, 1 RTOS is started. +int32_t osKernelRunning(void); + + +// ==== Thread Management ==== + +/// Create a Thread Definition with function, priority, and stack requirements. +/// \param name name of the thread function. +/// \param priority initial priority of the thread function. +/// \param stacksz stack size (in bytes) requirements for the thread function. +/// \note CAN BE CHANGED: The parameters to \b osThreadDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osThreadDef(name, priority, stacksz) \ +extern osThreadDef_t os_thread_def_##name +#else // define the object +#define osThreadDef(name, priority, stacksz) \ +unsigned char os_thread_def_stack_##name [stacksz]; \ +osThreadDef_t os_thread_def_##name = \ +{ (name), (priority), (stacksz), (os_thread_def_stack_##name)} +#endif + +/// Access a Thread definition. +/// \param name name of the thread definition object. +/// \note CAN BE CHANGED: The parameter to \b osThread shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osThread(name) \ +&os_thread_def_##name + +/// Create a thread and add it to Active Threads and set it to state READY. +/// \param[in] thread_def thread definition referenced with \ref osThread. +/// \param[in] argument pointer that is passed to the thread function as start argument. +/// \return thread ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osThreadCreate shall be consistent in every CMSIS-RTOS. +osThreadId osThreadCreate (osThreadDef_t *thread_def, void *argument); + +/// Return the thread ID of the current running thread. +/// \return thread ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osThreadGetId shall be consistent in every CMSIS-RTOS. +osThreadId osThreadGetId (void); + +/// Terminate execution of a thread and remove it from Active Threads. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osThreadTerminate shall be consistent in every CMSIS-RTOS. +osStatus osThreadTerminate (osThreadId thread_id); + +/// Pass control to next thread that is in state \b READY. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osThreadYield shall be consistent in every CMSIS-RTOS. +osStatus osThreadYield (void); + +/// Change priority of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] priority new priority value for the thread function. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osThreadSetPriority shall be consistent in every CMSIS-RTOS. +osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority); + +/// Get current priority of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return current priority value of the thread function. +/// \note MUST REMAIN UNCHANGED: \b osThreadGetPriority shall be consistent in every CMSIS-RTOS. +osPriority osThreadGetPriority (osThreadId thread_id); + + +// ==== Generic Wait Functions ==== + +/// Wait for Timeout (Time Delay). +/// \param[in] millisec time delay value +/// \return status code that indicates the execution status of the function. +osStatus osDelay (uint32_t millisec); + +#if (defined (osFeature_Wait) && (osFeature_Wait != 0)) // Generic Wait available + +/// Wait for Signal, Message, Mail, or Timeout. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return event that contains signal, message, or mail information or error code. +/// \note MUST REMAIN UNCHANGED: \b osWait shall be consistent in every CMSIS-RTOS. +os_InRegs osEvent osWait (uint32_t millisec); + +#endif // Generic Wait available + + +// ==== Timer Management Functions ==== +/// Define a Timer object. +/// \param name name of the timer object. +/// \param function name of the timer call back function. +/// \note CAN BE CHANGED: The parameter to \b osTimerDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osTimerDef(name, function) \ +extern osTimerDef_t os_timer_def_##name +#else // define the object +#define osTimerDef(name, function) \ +uint32_t os_timer_cb_##name[5]; \ +osTimerDef_t os_timer_def_##name = \ +{ (function), (os_timer_cb_##name) } +#endif + +/// Access a Timer definition. +/// \param name name of the timer object. +/// \note CAN BE CHANGED: The parameter to \b osTimer shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osTimer(name) \ +&os_timer_def_##name + +/// Create a timer. +/// \param[in] timer_def timer object referenced with \ref osTimer. +/// \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior. +/// \param[in] argument argument to the timer call back function. +/// \return timer ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osTimerCreate shall be consistent in every CMSIS-RTOS. +osTimerId osTimerCreate (osTimerDef_t *timer_def, os_timer_type type, void *argument); + +/// Start or restart a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \param[in] millisec time delay value of the timer. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osTimerStart shall be consistent in every CMSIS-RTOS. +osStatus osTimerStart (osTimerId timer_id, uint32_t millisec); + +/// Stop the timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osTimerStop shall be consistent in every CMSIS-RTOS. +osStatus osTimerStop (osTimerId timer_id); + +/// Delete a timer that was created by \ref osTimerCreate. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osTimerDelete shall be consistent in every CMSIS-RTOS. +osStatus osTimerDelete (osTimerId timer_id); + + +// ==== Signal Management ==== + +/// Set the specified Signal Flags of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] signals specifies the signal flags of the thread that should be set. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSignalSet shall be consistent in every CMSIS-RTOS. +int32_t osSignalSet (osThreadId thread_id, int32_t signals); + +/// Clear the specified Signal Flags of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] signals specifies the signal flags of the thread that shall be cleared. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSignalClear shall be consistent in every CMSIS-RTOS. +int32_t osSignalClear (osThreadId thread_id, int32_t signals); + +/// Get Signal Flags status of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSignalGet shall be consistent in every CMSIS-RTOS. +int32_t osSignalGet (osThreadId thread_id); + +/// Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread. +/// \param[in] signals wait until all specified signal flags set or 0 for any single signal flag. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return event flag information or error code. +/// \note MUST REMAIN UNCHANGED: \b osSignalWait shall be consistent in every CMSIS-RTOS. +os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec); + + +// ==== Mutex Management ==== + +/// Define a Mutex. +/// \param name name of the mutex object. +/// \note CAN BE CHANGED: The parameter to \b osMutexDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMutexDef(name) \ +extern osMutexDef_t os_mutex_def_##name +#else // define the object +#define osMutexDef(name) \ +uint32_t os_mutex_cb_##name[3]; \ +osMutexDef_t os_mutex_def_##name = { (os_mutex_cb_##name) } +#endif + +/// Access a Mutex definition. +/// \param name name of the mutex object. +/// \note CAN BE CHANGED: The parameter to \b osMutex shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMutex(name) \ +&os_mutex_def_##name + +/// Create and Initialize a Mutex object. +/// \param[in] mutex_def mutex definition referenced with \ref osMutex. +/// \return mutex ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMutexCreate shall be consistent in every CMSIS-RTOS. +osMutexId osMutexCreate (osMutexDef_t *mutex_def); + +/// Wait until a Mutex becomes available. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMutexWait shall be consistent in every CMSIS-RTOS. +osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec); + +/// Release a Mutex that was obtained by \ref osMutexWait. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMutexRelease shall be consistent in every CMSIS-RTOS. +osStatus osMutexRelease (osMutexId mutex_id); + +/// Delete a Mutex that was created by \ref osMutexCreate. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMutexDelete shall be consistent in every CMSIS-RTOS. +osStatus osMutexDelete (osMutexId mutex_id); + + +// ==== Semaphore Management Functions ==== + +#if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0)) // Semaphore available + +/// Define a Semaphore object. +/// \param name name of the semaphore object. +/// \note CAN BE CHANGED: The parameter to \b osSemaphoreDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osSemaphoreDef(name) \ +extern osSemaphoreDef_t os_semaphore_def_##name +#else // define the object +#define osSemaphoreDef(name) \ +uint32_t os_semaphore_cb_##name[2]; \ +osSemaphoreDef_t os_semaphore_def_##name = { (os_semaphore_cb_##name) } +#endif + +/// Access a Semaphore definition. +/// \param name name of the semaphore object. +/// \note CAN BE CHANGED: The parameter to \b osSemaphore shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osSemaphore(name) \ +&os_semaphore_def_##name + +/// Create and Initialize a Semaphore object used for managing resources. +/// \param[in] semaphore_def semaphore definition referenced with \ref osSemaphore. +/// \param[in] count number of available resources. +/// \return semaphore ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreCreate shall be consistent in every CMSIS-RTOS. +osSemaphoreId osSemaphoreCreate (osSemaphoreDef_t *semaphore_def, int32_t count); + +/// Wait until a Semaphore token becomes available. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return number of available tokens, or -1 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS. +int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec); + +/// Release a Semaphore token. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreRelease shall be consistent in every CMSIS-RTOS. +osStatus osSemaphoreRelease (osSemaphoreId semaphore_id); + +/// Delete a Semaphore that was created by \ref osSemaphoreCreate. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreDelete shall be consistent in every CMSIS-RTOS. +osStatus osSemaphoreDelete (osSemaphoreId semaphore_id); + +#endif // Semaphore available + + +// ==== Memory Pool Management Functions ==== + +#if (defined (osFeature_Pool) && (osFeature_Pool != 0)) // Memory Pool Management available + +/// \brief Define a Memory Pool. +/// \param name name of the memory pool. +/// \param no maximum number of blocks (objects) in the memory pool. +/// \param type data type of a single block (object). +/// \note CAN BE CHANGED: The parameter to \b osPoolDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osPoolDef(name, no, type) \ +extern osPoolDef_t os_pool_def_##name +#else // define the object +#define osPoolDef(name, no, type) \ +uint32_t os_pool_m_##name[3+((sizeof(type)+3)/4)*(no)]; \ +osPoolDef_t os_pool_def_##name = \ +{ (no), sizeof(type), (os_pool_m_##name) } +#endif + +/// \brief Access a Memory Pool definition. +/// \param name name of the memory pool +/// \note CAN BE CHANGED: The parameter to \b osPool shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osPool(name) \ +&os_pool_def_##name + +/// Create and Initialize a memory pool. +/// \param[in] pool_def memory pool definition referenced with \ref osPool. +/// \return memory pool ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osPoolCreate shall be consistent in every CMSIS-RTOS. +osPoolId osPoolCreate (osPoolDef_t *pool_def); + +/// Allocate a memory block from a memory pool. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \return address of the allocated memory block or NULL in case of no memory available. +/// \note MUST REMAIN UNCHANGED: \b osPoolAlloc shall be consistent in every CMSIS-RTOS. +void *osPoolAlloc (osPoolId pool_id); + +/// Allocate a memory block from a memory pool and set memory block to zero. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \return address of the allocated memory block or NULL in case of no memory available. +/// \note MUST REMAIN UNCHANGED: \b osPoolCAlloc shall be consistent in every CMSIS-RTOS. +void *osPoolCAlloc (osPoolId pool_id); + +/// Return an allocated memory block back to a specific memory pool. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \param[in] block address of the allocated memory block that is returned to the memory pool. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osPoolFree shall be consistent in every CMSIS-RTOS. +osStatus osPoolFree (osPoolId pool_id, void *block); + +#endif // Memory Pool Management available + + +// ==== Message Queue Management Functions ==== + +#if (defined (osFeature_MessageQ) && (osFeature_MessageQ != 0)) // Message Queues available + +/// \brief Create a Message Queue Definition. +/// \param name name of the queue. +/// \param queue_sz maximum number of messages in the queue. +/// \param type data type of a single message element (for debugger). +/// \note CAN BE CHANGED: The parameter to \b osMessageQDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMessageQDef(name, queue_sz, type) \ +extern osMessageQDef_t os_messageQ_def_##name +#else // define the object +#define osMessageQDef(name, queue_sz, type) \ +uint32_t os_messageQ_q_##name[4+(queue_sz)]; \ +osMessageQDef_t os_messageQ_def_##name = \ +{ (queue_sz), (os_messageQ_q_##name) } +#endif + +/// \brief Access a Message Queue Definition. +/// \param name name of the queue +/// \note CAN BE CHANGED: The parameter to \b osMessageQ shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMessageQ(name) \ +&os_messageQ_def_##name + +/// Create and Initialize a Message Queue. +/// \param[in] queue_def queue definition referenced with \ref osMessageQ. +/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. +/// \return message queue ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMessageCreate shall be consistent in every CMSIS-RTOS. +osMessageQId osMessageCreate (osMessageQDef_t *queue_def, osThreadId thread_id); + +/// Put a Message to a Queue. +/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. +/// \param[in] info message information. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMessagePut shall be consistent in every CMSIS-RTOS. +osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec); + +/// Get a Message or Wait for a Message from a Queue. +/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return event information that includes status code. +/// \note MUST REMAIN UNCHANGED: \b osMessageGet shall be consistent in every CMSIS-RTOS. +os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec); + +#endif // Message Queues available + + +// ==== Mail Queue Management Functions ==== + +#if (defined (osFeature_MailQ) && (osFeature_MailQ != 0)) // Mail Queues available + +/// \brief Create a Mail Queue Definition. +/// \param name name of the queue +/// \param queue_sz maximum number of messages in queue +/// \param type data type of a single message element +/// \note CAN BE CHANGED: The parameter to \b osMailQDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMailQDef(name, queue_sz, type) \ +extern osMailQDef_t os_mailQ_def_##name +#else // define the object +#define osMailQDef(name, queue_sz, type) \ +uint32_t os_mailQ_q_##name[4+(queue_sz)]; \ +uint32_t os_mailQ_m_##name[3+((sizeof(type)+3)/4)*(queue_sz)]; \ +void * os_mailQ_p_##name[2] = { (os_mailQ_q_##name), os_mailQ_m_##name }; \ +osMailQDef_t os_mailQ_def_##name = \ +{ (queue_sz), sizeof(type), (os_mailQ_p_##name) } +#endif + +/// \brief Access a Mail Queue Definition. +/// \param name name of the queue +/// \note CAN BE CHANGED: The parameter to \b osMailQ shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMailQ(name) \ +&os_mailQ_def_##name + +/// Create and Initialize mail queue. +/// \param[in] queue_def reference to the mail queue definition obtain with \ref osMailQ +/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. +/// \return mail queue ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMailCreate shall be consistent in every CMSIS-RTOS. +osMailQId osMailCreate (osMailQDef_t *queue_def, osThreadId thread_id); + +/// Allocate a memory block from a mail. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return pointer to memory block that can be filled with mail or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMailAlloc shall be consistent in every CMSIS-RTOS. +void *osMailAlloc (osMailQId queue_id, uint32_t millisec); + +/// Allocate a memory block from a mail and set memory block to zero. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return pointer to memory block that can be filled with mail or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMailCAlloc shall be consistent in every CMSIS-RTOS. +void *osMailCAlloc (osMailQId queue_id, uint32_t millisec); + +/// Put a mail to a queue. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] mail memory block previously allocated with \ref osMailAlloc or \ref osMailCAlloc. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMailPut shall be consistent in every CMSIS-RTOS. +osStatus osMailPut (osMailQId queue_id, void *mail); + +/// Get a mail from a queue. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return event that contains mail information or error code. +/// \note MUST REMAIN UNCHANGED: \b osMailGet shall be consistent in every CMSIS-RTOS. +os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec); + +/// Free a memory block from a mail. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] mail pointer to the memory block that was obtained with \ref osMailGet. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMailFree shall be consistent in every CMSIS-RTOS. +osStatus osMailFree (osMailQId queue_id, void *mail); + +#endif // Mail Queues available + + +#ifdef __cplusplus +} +#endif + +#endif // _CMSIS_OS_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/os_tcb.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,50 @@ +#ifndef OS_TCB_H +#define OS_TCB_H + +/* Types */ +typedef char S8; +typedef unsigned char U8; +typedef short S16; +typedef unsigned short U16; +typedef int S32; +typedef unsigned int U32; +typedef long long S64; +typedef unsigned long long U64; +typedef unsigned char BIT; +typedef unsigned int BOOL; +typedef void (*FUNCP)(void); + +typedef struct OS_TCB { + /* General part: identical for all implementations. */ + U8 cb_type; /* Control Block Type */ + U8 state; /* Task state */ + U8 prio; /* Execution priority */ + U8 task_id; /* Task ID value for optimized TCB access */ + struct OS_TCB *p_lnk; /* Link pointer for ready/sem. wait list */ + struct OS_TCB *p_rlnk; /* Link pointer for sem./mbx lst backwards */ + struct OS_TCB *p_dlnk; /* Link pointer for delay list */ + struct OS_TCB *p_blnk; /* Link pointer for delay list backwards */ + U16 delta_time; /* Time until time out */ + U16 interval_time; /* Time interval for periodic waits */ + U16 events; /* Event flags */ + U16 waits; /* Wait flags */ + void **msg; /* Direct message passing when task waits */ + + /* Hardware dependant part: specific for CM processor */ + U8 stack_frame; /* Stack frame: 0=Basic, 1=Extended */ + U8 reserved; + U16 priv_stack; /* Private stack size in bytes */ + U32 tsk_stack; /* Current task Stack pointer (R13) */ + U32 *stack; /* Pointer to Task Stack memory block */ + + /* Library dependant part */ +#if defined (__CC_ARM) && !defined (__MICROLIB) + /* A memory space for arm standard library. */ + U32 std_libspace[96/4]; +#endif + + /* Task entry point used for uVision debugger */ + FUNCP ptask; /* Task entry address */ +} *P_TCB; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/rt_CMSIS.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,1920 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: rt_CMSIS.c + * Purpose: CMSIS RTOS API + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#define __CMSIS_GENERIC + +#if defined (__CORTEX_M4) || defined (__CORTEX_M4F) + #include "core_cm4.h" +#elif defined (__CORTEX_M3) + #include "core_cm3.h" +#elif defined (__CORTEX_M0) + #include "core_cm0.h" +#elif defined (__CORTEX_M0PLUS) + #include "core_cm0plus.h" +#else + #error "Missing __CORTEX_Mx definition" +#endif + +#include "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_System.h" +#include "rt_Task.h" +#include "rt_Event.h" +#include "rt_List.h" +#include "rt_Time.h" +#include "rt_Mutex.h" +#include "rt_Semaphore.h" +#include "rt_Mailbox.h" +#include "rt_MemBox.h" +#include "rt_HAL_CM.h" + +#define os_thread_cb OS_TCB + +#include "cmsis_os.h" + +#if (osFeature_Signals != 16) +#error Invalid "osFeature_Signals" value! +#endif +#if (osFeature_Semaphore > 65535) +#error Invalid "osFeature_Semaphore" value! +#endif +#if (osFeature_Wait != 0) +#error osWait not supported! +#endif + + +// ==== Enumeration, structures, defines ==== + +// Service Calls defines + +#if defined (__CC_ARM) /* ARM Compiler */ + +#define __NO_RETURN __declspec(noreturn) + +#define osEvent_type osEvent +#define osEvent_ret_status ret +#define osEvent_ret_value ret +#define osEvent_ret_msg ret +#define osEvent_ret_mail ret + +#define osCallback_type osCallback +#define osCallback_ret ret + +#define SVC_0_1(f,t,...) \ +__svc_indirect(0) t _##f (t(*)()); \ + t f (void); \ +__attribute__((always_inline)) \ +static __inline t __##f (void) { \ + return _##f(f); \ +} + +#define SVC_1_1(f,t,t1,...) \ +__svc_indirect(0) t _##f (t(*)(t1),t1); \ + t f (t1 a1); \ +__attribute__((always_inline)) \ +static __inline t __##f (t1 a1) { \ + return _##f(f,a1); \ +} + +#define SVC_2_1(f,t,t1,t2,...) \ +__svc_indirect(0) t _##f (t(*)(t1,t2),t1,t2); \ + t f (t1 a1, t2 a2); \ +__attribute__((always_inline)) \ +static __inline t __##f (t1 a1, t2 a2) { \ + return _##f(f,a1,a2); \ +} + +#define SVC_3_1(f,t,t1,t2,t3,...) \ +__svc_indirect(0) t _##f (t(*)(t1,t2,t3),t1,t2,t3); \ + t f (t1 a1, t2 a2, t3 a3); \ +__attribute__((always_inline)) \ +static __inline t __##f (t1 a1, t2 a2, t3 a3) { \ + return _##f(f,a1,a2,a3); \ +} + +#define SVC_4_1(f,t,t1,t2,t3,t4,...) \ +__svc_indirect(0) t _##f (t(*)(t1,t2,t3,t4),t1,t2,t3,t4); \ + t f (t1 a1, t2 a2, t3 a3, t4 a4); \ +__attribute__((always_inline)) \ +static __inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ + return _##f(f,a1,a2,a3,a4); \ +} + +#define SVC_1_2 SVC_1_1 +#define SVC_1_3 SVC_1_1 +#define SVC_2_3 SVC_2_1 + +#elif defined (__GNUC__) /* GNU Compiler */ + +#define __NO_RETURN __attribute__((noreturn)) + +typedef uint32_t __attribute__((vector_size(8))) ret64; +typedef uint32_t __attribute__((vector_size(16))) ret128; + +#define RET_pointer __r0 +#define RET_int32_t __r0 +#define RET_osStatus __r0 +#define RET_osPriority __r0 +#define RET_osEvent {(osStatus)__r0, {(uint32_t)__r1}, {(void *)__r2}} +#define RET_osCallback {(void *)__r0, (void *)__r1} + +#define osEvent_type ret128 +#define osEvent_ret_status (ret128){ret.status} +#define osEvent_ret_value (ret128){ret.status, ret.value.v} +#define osEvent_ret_msg (ret128){ret.status, ret.value.v, (uint32_t)ret.def.message_id} +#define osEvent_ret_mail (ret128){ret.status, ret.value.v, (uint32_t)ret.def.mail_id} + +#define osCallback_type ret64 +#define osCallback_ret (ret64) {(uint32_t)ret.fp, (uint32_t)ret.arg} + +#define SVC_ArgN(n) \ + register int __r##n __asm("r"#n); + +#define SVC_ArgR(n,t,a) \ + register t __r##n __asm("r"#n) = a; + +#define SVC_Arg0() \ + SVC_ArgN(0) \ + SVC_ArgN(1) \ + SVC_ArgN(2) \ + SVC_ArgN(3) + +#define SVC_Arg1(t1) \ + SVC_ArgR(0,t1,a1) \ + SVC_ArgN(1) \ + SVC_ArgN(2) \ + SVC_ArgN(3) + +#define SVC_Arg2(t1,t2) \ + SVC_ArgR(0,t1,a1) \ + SVC_ArgR(1,t2,a2) \ + SVC_ArgN(2) \ + SVC_ArgN(3) + +#define SVC_Arg3(t1,t2,t3) \ + SVC_ArgR(0,t1,a1) \ + SVC_ArgR(1,t2,a2) \ + SVC_ArgR(2,t3,a3) \ + SVC_ArgN(3) + +#define SVC_Arg4(t1,t2,t3,t4) \ + SVC_ArgR(0,t1,a1) \ + SVC_ArgR(1,t2,a2) \ + SVC_ArgR(2,t3,a3) \ + SVC_ArgR(3,t4,a4) + +#if (defined (__CORTEX_M0)) || defined (__CORTEX_M0PLUS) +#define SVC_Call(f) \ + __asm volatile \ + ( \ + "ldr r7,="#f"\n\t" \ + "mov r12,r7\n\t" \ + "svc 0" \ + : "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3) \ + : "r" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) \ + : "r7", "r12", "lr", "cc" \ + ); +#else +#define SVC_Call(f) \ + __asm volatile \ + ( \ + "ldr r12,="#f"\n\t" \ + "svc 0" \ + : "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3) \ + : "r" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) \ + : "r12", "lr", "cc" \ + ); +#endif + +#define SVC_0_1(f,t,rv) \ +__attribute__((always_inline)) \ +static inline t __##f (void) { \ + SVC_Arg0(); \ + SVC_Call(f); \ + return (t) rv; \ +} + +#define SVC_1_1(f,t,t1,rv) \ +__attribute__((always_inline)) \ +static inline t __##f (t1 a1) { \ + SVC_Arg1(t1); \ + SVC_Call(f); \ + return (t) rv; \ +} + +#define SVC_2_1(f,t,t1,t2,rv) \ +__attribute__((always_inline)) \ +static inline t __##f (t1 a1, t2 a2) { \ + SVC_Arg2(t1,t2); \ + SVC_Call(f); \ + return (t) rv; \ +} + +#define SVC_3_1(f,t,t1,t2,t3,rv) \ +__attribute__((always_inline)) \ +static inline t __##f (t1 a1, t2 a2, t3 a3) { \ + SVC_Arg3(t1,t2,t3); \ + SVC_Call(f); \ + return (t) rv; \ +} + +#define SVC_4_1(f,t,t1,t2,t3,t4,rv) \ +__attribute__((always_inline)) \ +static inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ + SVC_Arg4(t1,t2,t3,t4); \ + SVC_Call(f); \ + return (t) rv; \ +} + +#define SVC_1_2 SVC_1_1 +#define SVC_1_3 SVC_1_1 +#define SVC_2_3 SVC_2_1 + +#elif defined (__ICCARM__) /* IAR Compiler */ + +#define __NO_RETURN __noreturn + +#define RET_osEvent "=r"(ret.status), "=r"(ret.value), "=r"(ret.def) +#define RET_osCallback "=r"(ret.fp), "=r"(ret.arg) + +#define osEvent_type osEvent +#define osEvent_ret_status ret +#define osEvent_ret_value ret +#define osEvent_ret_msg ret +#define osEvent_ret_mail ret + +#define osCallback_type uint64_t +#define osCallback_ret ((uint64_t)ret.fp | ((uint64_t)ret.arg)<<32) + +#define SVC_Setup(f) \ + __asm( \ + "mov r12,%0\n" \ + :: "r"(&f): "r12" \ + ); + +#define SVC_Ret3() \ + __asm( \ + "ldr r0,[sp,#0]\n" \ + "ldr r1,[sp,#4]\n" \ + "ldr r2,[sp,#8]\n" \ + ); + +#define SVC_0_1(f,t,...) \ +t f (void); \ +_Pragma("swi_number=0") __swi t _##f (void); \ +static inline t __##f (void) { \ + SVC_Setup(f); \ + return _##f(); \ +} + +#define SVC_1_1(f,t,t1,...) \ +t f (t1 a1); \ +_Pragma("swi_number=0") __swi t _##f (t1 a1); \ +static inline t __##f (t1 a1) { \ + SVC_Setup(f); \ + return _##f(a1); \ +} + +#define SVC_2_1(f,t,t1,t2,...) \ +t f (t1 a1, t2 a2); \ +_Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2); \ +static inline t __##f (t1 a1, t2 a2) { \ + SVC_Setup(f); \ + return _##f(a1,a2); \ +} + +#define SVC_3_1(f,t,t1,t2,t3,...) \ +t f (t1 a1, t2 a2, t3 a3); \ +_Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2, t3 a3); \ +static inline t __##f (t1 a1, t2 a2, t3 a3) { \ + SVC_Setup(f); \ + return _##f(a1,a2,a3); \ +} + +#define SVC_4_1(f,t,t1,t2,t3,t4,...) \ +t f (t1 a1, t2 a2, t3 a3, t4 a4); \ +_Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2, t3 a3, t4 a4); \ +static inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ + SVC_Setup(f); \ + return _##f(a1,a2,a3,a4); \ +} + +#define SVC_1_2(f,t,t1,rr) \ +uint64_t f (t1 a1); \ +_Pragma("swi_number=0") __swi uint64_t _##f (t1 a1); \ +static inline t __##f (t1 a1) { \ + t ret; \ + SVC_Setup(f); \ + _##f(a1); \ + __asm("" : rr : :); \ + return ret; \ +} + +#define SVC_1_3(f,t,t1,rr) \ +t f (t1 a1); \ +void f##_ (t1 a1) { \ + f(a1); \ + SVC_Ret3(); \ +} \ +_Pragma("swi_number=0") __swi void _##f (t1 a1); \ +static inline t __##f (t1 a1) { \ + t ret; \ + SVC_Setup(f##_); \ + _##f(a1); \ + __asm("" : rr : :); \ + return ret; \ +} + +#define SVC_2_3(f,t,t1,t2,rr) \ +t f (t1 a1, t2 a2); \ +void f##_ (t1 a1, t2 a2) { \ + f(a1,a2); \ + SVC_Ret3(); \ +} \ +_Pragma("swi_number=0") __swi void _##f (t1 a1, t2 a2); \ +static inline t __##f (t1 a1, t2 a2) { \ + t ret; \ + SVC_Setup(f##_); \ + _##f(a1,a2); \ + __asm("" : rr : :); \ + return ret; \ +} + +#endif + + +// Callback structure +typedef struct { + void *fp; // Function pointer + void *arg; // Function argument +} osCallback; + + +// OS Section definitions +#ifdef OS_SECTIONS_LINK_INFO +extern const uint32_t os_section_id$$Base; +extern const uint32_t os_section_id$$Limit; +#endif + +// OS Timers external resources +extern osThreadDef_t os_thread_def_osTimerThread; +extern osThreadId osThreadId_osTimerThread; +extern osMessageQDef_t os_messageQ_def_osTimerMessageQ; +extern osMessageQId osMessageQId_osTimerMessageQ; + + +// ==== Helper Functions ==== + +/// Convert timeout in millisec to system ticks +static uint32_t rt_ms2tick (uint32_t millisec) { + uint32_t tick; + + if (millisec == osWaitForever) return 0xFFFF; // Indefinite timeout + if (millisec > 4000000) return 0xFFFE; // Max ticks supported + + tick = ((1000 * millisec) + os_clockrate - 1) / os_clockrate; + if (tick > 0xFFFE) return 0xFFFE; + + return tick; +} + +/// Convert Thread ID to TCB pointer +static P_TCB rt_tid2ptcb (osThreadId thread_id) { + P_TCB ptcb; + + if (thread_id == NULL) return NULL; + + if ((uint32_t)thread_id & 3) return NULL; + +#ifdef OS_SECTIONS_LINK_INFO + if ((os_section_id$$Base != 0) && (os_section_id$$Limit != 0)) { + if (thread_id < (osThreadId)os_section_id$$Base) return NULL; + if (thread_id >= (osThreadId)os_section_id$$Limit) return NULL; + } +#endif + + ptcb = thread_id; + + if (ptcb->cb_type != TCB) return NULL; + + return ptcb; +} + +/// Convert ID pointer to Object pointer +static void *rt_id2obj (void *id) { + + if ((uint32_t)id & 3) return NULL; + +#ifdef OS_SECTIONS_LINK_INFO + if ((os_section_id$$Base != 0) && (os_section_id$$Limit != 0)) { + if (id < (void *)os_section_id$$Base) return NULL; + if (id >= (void *)os_section_id$$Limit) return NULL; + } +#endif + + return id; +} + + +// ==== Kernel Control ==== + +uint8_t os_initialized; // Kernel Initialized flag +uint8_t os_running; // Kernel Running flag + +// Kernel Control Service Calls declarations +SVC_0_1(svcKernelInitialize, osStatus, RET_osStatus) +SVC_0_1(svcKernelStart, osStatus, RET_osStatus) +SVC_0_1(svcKernelRunning, int32_t, RET_int32_t) + +extern void sysThreadError (osStatus status); +osThreadId svcThreadCreate (osThreadDef_t *thread_def, void *argument); +osMessageQId svcMessageCreate (osMessageQDef_t *queue_def, osThreadId thread_id); + +// Kernel Control Service Calls + +/// Initialize the RTOS Kernel for creating objects +osStatus svcKernelInitialize (void) { + if (os_initialized) return osOK; + + rt_sys_init(); // RTX System Initialization + os_tsk.run->prio = 255; // Highest priority + + sysThreadError(osOK); + + os_initialized = 1; + + return osOK; +} + +/// Start the RTOS Kernel +osStatus svcKernelStart (void) { + + if (os_running) return osOK; + + // Create OS Timers resources (Message Queue & Thread) + osMessageQId_osTimerMessageQ = svcMessageCreate (&os_messageQ_def_osTimerMessageQ, NULL); + osThreadId_osTimerThread = svcThreadCreate(&os_thread_def_osTimerThread, NULL); + + rt_tsk_prio(0, 0); // Lowest priority + __set_PSP(os_tsk.run->tsk_stack + 8*4); // New context + os_tsk.run = NULL; // Force context switch + + rt_sys_start(); + + os_running = 1; + + return osOK; +} + +/// Check if the RTOS kernel is already started +int32_t svcKernelRunning(void) { + return os_running; +} + +// Kernel Control Public API + +/// Initialize the RTOS Kernel for creating objects +osStatus osKernelInitialize (void) { + if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + if ((__get_CONTROL() & 1) == 0) { // Privileged mode + return svcKernelInitialize(); + } else { + return __svcKernelInitialize(); + } +} + +/// Start the RTOS Kernel +osStatus osKernelStart (void) { + uint32_t stack[8]; + + if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + switch (__get_CONTROL() & 0x03) { + case 0x00: // Privileged Thread mode & MSP + __set_PSP((uint32_t)(stack + 8)); // Initial PSP + if (os_flags & 1) { + __set_CONTROL(0x02); // Set Privileged Thread mode & PSP + } else { + __set_CONTROL(0x03); // Set Unprivileged Thread mode & PSP + } + __DSB(); + __ISB(); + break; + case 0x01: // Unprivileged Thread mode & MSP + return osErrorOS; + case 0x02: // Privileged Thread mode & PSP + if ((os_flags & 1) == 0) { // Unprivileged Thread mode requested + __set_CONTROL(0x03); // Set Unprivileged Thread mode & PSP + __DSB(); + __ISB(); + } + break; + case 0x03: // Unprivileged Thread mode & PSP + if (os_flags & 1) return osErrorOS; // Privileged Thread mode requested + break; + } + return __svcKernelStart(); +} + +/// Check if the RTOS kernel is already started +int32_t osKernelRunning(void) { + if ((__get_IPSR() != 0) || ((__get_CONTROL() & 1) == 0)) { + // in ISR or Privileged + return os_running; + } else { + return __svcKernelRunning(); + } +} + + +// ==== Thread Management ==== + +__NO_RETURN void osThreadExit (void); + +// Thread Service Calls declarations +SVC_2_1(svcThreadCreate, osThreadId, osThreadDef_t *, void *, RET_pointer) +SVC_0_1(svcThreadGetId, osThreadId, RET_pointer) +SVC_1_1(svcThreadTerminate, osStatus, osThreadId, RET_osStatus) +SVC_0_1(svcThreadYield, osStatus, RET_osStatus) +SVC_2_1(svcThreadSetPriority, osStatus, osThreadId, osPriority, RET_osStatus) +SVC_1_1(svcThreadGetPriority, osPriority, osThreadId, RET_osPriority) + +// Thread Service Calls +extern OS_TID rt_get_TID (void); +extern void rt_init_context (P_TCB p_TCB, U8 priority, FUNCP task_body); + +/// Create a thread and add it to Active Threads and set it to state READY +osThreadId svcThreadCreate (osThreadDef_t *thread_def, void *argument) { + P_TCB ptcb; + + if ((thread_def == NULL) || + (thread_def->pthread == NULL) || + (thread_def->tpriority < osPriorityIdle) || + (thread_def->tpriority > osPriorityRealtime) || + (thread_def->stacksize == 0) || + (thread_def->stack_pointer == NULL) ) { + sysThreadError(osErrorParameter); + return NULL; + } + + U8 priority = thread_def->tpriority - osPriorityIdle + 1; + P_TCB task_context = &thread_def->tcb; + + /* If "size != 0" use a private user provided stack. */ + task_context->stack = (U32*)thread_def->stack_pointer; + task_context->priv_stack = thread_def->stacksize; + /* Pass parameter 'argv' to 'rt_init_context' */ + task_context->msg = argument; + /* For 'size == 0' system allocates the user stack from the memory pool. */ + rt_init_context (task_context, priority, (FUNCP)thread_def->pthread); + + /* Find a free entry in 'os_active_TCB' table. */ + OS_TID tsk = rt_get_TID (); + os_active_TCB[tsk-1] = task_context; + task_context->task_id = tsk; + DBG_TASK_NOTIFY(task_context, __TRUE); + rt_dispatch (task_context); + + ptcb = (P_TCB)os_active_TCB[tsk - 1]; // TCB pointer + + *((uint32_t *)ptcb->tsk_stack + 13) = (uint32_t)osThreadExit; + + return ptcb; +} + +/// Return the thread ID of the current running thread +osThreadId svcThreadGetId (void) { + OS_TID tsk; + + tsk = rt_tsk_self(); + if (tsk == 0) return NULL; + return (P_TCB)os_active_TCB[tsk - 1]; +} + +/// Terminate execution of a thread and remove it from ActiveThreads +osStatus svcThreadTerminate (osThreadId thread_id) { + OS_RESULT res; + P_TCB ptcb; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return osErrorParameter; + + res = rt_tsk_delete(ptcb->task_id); // Delete task + + if (res == OS_R_NOK) return osErrorResource; // Delete task failed + + return osOK; +} + +/// Pass control to next thread that is in state READY +osStatus svcThreadYield (void) { + rt_tsk_pass(); // Pass control to next task + return osOK; +} + +/// Change priority of an active thread +osStatus svcThreadSetPriority (osThreadId thread_id, osPriority priority) { + OS_RESULT res; + P_TCB ptcb; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return osErrorParameter; + + if ((priority < osPriorityIdle) || (priority > osPriorityRealtime)) { + return osErrorValue; + } + + res = rt_tsk_prio( // Change task priority + ptcb->task_id, // Task ID + priority - osPriorityIdle + 1 // New task priority + ); + + if (res == OS_R_NOK) return osErrorResource; // Change task priority failed + + return osOK; +} + +/// Get current priority of an active thread +osPriority svcThreadGetPriority (osThreadId thread_id) { + P_TCB ptcb; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return osPriorityError; + + return (osPriority)(ptcb->prio - 1 + osPriorityIdle); +} + + +// Thread Public API + +/// Create a thread and add it to Active Threads and set it to state READY +osThreadId osThreadCreate (osThreadDef_t *thread_def, void *argument) { + if (__get_IPSR() != 0) return NULL; // Not allowed in ISR + if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) { + // Privileged and not running + return svcThreadCreate(thread_def, argument); + } else { + return __svcThreadCreate(thread_def, argument); + } +} + +/// Return the thread ID of the current running thread +osThreadId osThreadGetId (void) { + if (__get_IPSR() != 0) return NULL; // Not allowed in ISR + return __svcThreadGetId(); +} + +/// Terminate execution of a thread and remove it from ActiveThreads +osStatus osThreadTerminate (osThreadId thread_id) { + if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + return __svcThreadTerminate(thread_id); +} + +/// Pass control to next thread that is in state READY +osStatus osThreadYield (void) { + if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + return __svcThreadYield(); +} + +/// Change priority of an active thread +osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority) { + if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + return __svcThreadSetPriority(thread_id, priority); +} + +/// Get current priority of an active thread +osPriority osThreadGetPriority (osThreadId thread_id) { + if (__get_IPSR() != 0) return osPriorityError;// Not allowed in ISR + return __svcThreadGetPriority(thread_id); +} + +/// INTERNAL - Not Public +/// Auto Terminate Thread on exit (used implicitly when thread exists) +__NO_RETURN void osThreadExit (void) { + __svcThreadTerminate(__svcThreadGetId()); + for (;;); // Should never come here +} + + +// ==== Generic Wait Functions ==== + +// Generic Wait Service Calls declarations +SVC_1_1(svcDelay, osStatus, uint32_t, RET_osStatus) +#if osFeature_Wait != 0 +SVC_1_3(svcWait, os_InRegs osEvent, uint32_t, RET_osEvent) +#endif + +// Generic Wait Service Calls + +/// Wait for Timeout (Time Delay) +osStatus svcDelay (uint32_t millisec) { + if (millisec == 0) return osOK; + rt_dly_wait(rt_ms2tick(millisec)); + return osEventTimeout; +} + +/// Wait for Signal, Message, Mail, or Timeout +#if osFeature_Wait != 0 +os_InRegs osEvent_type svcWait (uint32_t millisec) { + osEvent ret; + + if (millisec == 0) { + ret.status = osOK; + return osEvent_ret_status; + } + + /* To Do: osEventSignal, osEventMessage, osEventMail */ + rt_dly_wait(rt_ms2tick(millisec)); + ret.status = osEventTimeout; + + return osEvent_ret_status; +} +#endif + + +// Generic Wait API + +/// Wait for Timeout (Time Delay) +osStatus osDelay (uint32_t millisec) { + if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + return __svcDelay(millisec); +} + +/// Wait for Signal, Message, Mail, or Timeout +os_InRegs osEvent osWait (uint32_t millisec) { + osEvent ret; + +#if osFeature_Wait == 0 + ret.status = osErrorOS; + return ret; +#else + if (__get_IPSR() != 0) { // Not allowed in ISR + ret.status = osErrorISR; + return ret; + } + return __svcWait(millisec); +#endif +} + + +// ==== Timer Management ==== + +// Timer definitions +#define osTimerInvalid 0 +#define osTimerStopped 1 +#define osTimerRunning 2 + +// Timer structures + +typedef struct os_timer_cb_ { // Timer Control Block + struct os_timer_cb_ *next; // Pointer to next active Timer + uint8_t state; // Timer State + uint8_t type; // Timer Type (Periodic/One-shot) + uint16_t reserved; // Reserved + uint16_t tcnt; // Timer Delay Count + uint16_t icnt; // Timer Initial Count + void *arg; // Timer Function Argument + osTimerDef_t *timer; // Pointer to Timer definition +} os_timer_cb; + +// Timer variables +os_timer_cb *os_timer_head; // Pointer to first active Timer + + +// Timer Helper Functions + +// Insert Timer into the list sorted by time +static void rt_timer_insert (os_timer_cb *pt, uint32_t tcnt) { + os_timer_cb *p, *prev; + + prev = NULL; + p = os_timer_head; + while (p != NULL) { + if (tcnt < p->tcnt) break; + tcnt -= p->tcnt; + prev = p; + p = p->next; + } + pt->next = p; + pt->tcnt = (uint16_t)tcnt; + if (p != NULL) { + p->tcnt -= pt->tcnt; + } + if (prev != NULL) { + prev->next = pt; + } else { + os_timer_head = pt; + } +} + +// Remove Timer from the list +static int rt_timer_remove (os_timer_cb *pt) { + os_timer_cb *p, *prev; + + prev = NULL; + p = os_timer_head; + while (p != NULL) { + if (p == pt) break; + prev = p; + p = p->next; + } + if (p == NULL) return -1; + if (prev != NULL) { + prev->next = pt->next; + } else { + os_timer_head = pt->next; + } + if (pt->next != NULL) { + pt->next->tcnt += pt->tcnt; + } + + return 0; +} + + +// Timer Service Calls declarations +SVC_3_1(svcTimerCreate, osTimerId, osTimerDef_t *, os_timer_type, void *, RET_pointer) +SVC_2_1(svcTimerStart, osStatus, osTimerId, uint32_t, RET_osStatus) +SVC_1_1(svcTimerStop, osStatus, osTimerId, RET_osStatus) +SVC_1_1(svcTimerDelete, osStatus, osTimerId, RET_osStatus) +SVC_1_2(svcTimerCall, os_InRegs osCallback, osTimerId, RET_osCallback) + +// Timer Management Service Calls + +/// Create timer +osTimerId svcTimerCreate (osTimerDef_t *timer_def, os_timer_type type, void *argument) { + os_timer_cb *pt; + + if ((timer_def == NULL) || (timer_def->ptimer == NULL)) { + sysThreadError(osErrorParameter); + return NULL; + } + + pt = timer_def->timer; + if (pt == NULL) { + sysThreadError(osErrorParameter); + return NULL; + } + + if ((type != osTimerOnce) && (type != osTimerPeriodic)) { + sysThreadError(osErrorValue); + return NULL; + } + + if (osThreadId_osTimerThread == NULL) { + sysThreadError(osErrorResource); + return NULL; + } + + if (pt->state != osTimerInvalid){ + sysThreadError(osErrorResource); + return NULL; + } + + pt->state = osTimerStopped; + pt->type = (uint8_t)type; + pt->arg = argument; + pt->timer = timer_def; + + return (osTimerId)pt; +} + +/// Start or restart timer +osStatus svcTimerStart (osTimerId timer_id, uint32_t millisec) { + os_timer_cb *pt; + uint32_t tcnt; + + pt = rt_id2obj(timer_id); + if (pt == NULL) return osErrorParameter; + + tcnt = rt_ms2tick(millisec); + if (tcnt == 0) return osErrorValue; + + switch (pt->state) { + case osTimerRunning: + if (rt_timer_remove(pt) != 0) { + return osErrorResource; + } + break; + case osTimerStopped: + pt->state = osTimerRunning; + pt->icnt = (uint16_t)tcnt; + break; + default: + return osErrorResource; + } + + rt_timer_insert(pt, tcnt); + + return osOK; +} + +/// Stop timer +osStatus svcTimerStop (osTimerId timer_id) { + os_timer_cb *pt; + + pt = rt_id2obj(timer_id); + if (pt == NULL) return osErrorParameter; + + if (pt->state != osTimerRunning) return osErrorResource; + + pt->state = osTimerStopped; + + if (rt_timer_remove(pt) != 0) { + return osErrorResource; + } + + return osOK; +} + +/// Delete timer +osStatus svcTimerDelete (osTimerId timer_id) { + os_timer_cb *pt; + + pt = rt_id2obj(timer_id); + if (pt == NULL) return osErrorParameter; + + switch (pt->state) { + case osTimerRunning: + rt_timer_remove(pt); + break; + case osTimerStopped: + break; + default: + return osErrorResource; + } + + pt->state = osTimerInvalid; + + return osOK; +} + +/// Get timer callback parameters +os_InRegs osCallback_type svcTimerCall (osTimerId timer_id) { + os_timer_cb *pt; + osCallback ret; + + pt = rt_id2obj(timer_id); + if (pt == NULL) { + ret.fp = NULL; + ret.arg = NULL; + return osCallback_ret; + } + + ret.fp = (void *)pt->timer->ptimer; + ret.arg = pt->arg; + + return osCallback_ret; +} + +static __INLINE osStatus isrMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec); + +/// Timer Tick (called each SysTick) +void sysTimerTick (void) { + os_timer_cb *pt, *p; + + p = os_timer_head; + if (p == NULL) return; + + p->tcnt--; + while ((p != NULL) && (p->tcnt == 0)) { + pt = p; + p = p->next; + os_timer_head = p; + isrMessagePut(osMessageQId_osTimerMessageQ, (uint32_t)pt, 0); + if (pt->type == osTimerPeriodic) { + rt_timer_insert(pt, pt->icnt); + } else { + pt->state = osTimerStopped; + } + } +} + + +// Timer Management Public API + +/// Create timer +osTimerId osTimerCreate (osTimerDef_t *timer_def, os_timer_type type, void *argument) { + if (__get_IPSR() != 0) return NULL; // Not allowed in ISR + if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) { + // Privileged and not running + return svcTimerCreate(timer_def, type, argument); + } else { + return __svcTimerCreate(timer_def, type, argument); + } +} + +/// Start or restart timer +osStatus osTimerStart (osTimerId timer_id, uint32_t millisec) { + if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + return __svcTimerStart(timer_id, millisec); +} + +/// Stop timer +osStatus osTimerStop (osTimerId timer_id) { + if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + return __svcTimerStop(timer_id); +} + +/// Delete timer +osStatus osTimerDelete (osTimerId timer_id) { + if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + return __svcTimerDelete(timer_id); +} + +/// INTERNAL - Not Public +/// Get timer callback parameters (used by OS Timer Thread) +os_InRegs osCallback osTimerCall (osTimerId timer_id) { + return __svcTimerCall(timer_id); +} + + +// Timer Thread +__NO_RETURN void osTimerThread (void const *argument) { + osCallback cb; + osEvent evt; + + for (;;) { + evt = osMessageGet(osMessageQId_osTimerMessageQ, osWaitForever); + if (evt.status == osEventMessage) { + cb = osTimerCall(evt.value.p); + if (cb.fp != NULL) { + (*(os_ptimer)cb.fp)(cb.arg); + } + } + } +} + + +// ==== Signal Management ==== + +// Signal Service Calls declarations +SVC_2_1(svcSignalSet, int32_t, osThreadId, int32_t, RET_int32_t) +SVC_2_1(svcSignalClear, int32_t, osThreadId, int32_t, RET_int32_t) +SVC_1_1(svcSignalGet, int32_t, osThreadId, RET_int32_t) +SVC_2_3(svcSignalWait, os_InRegs osEvent, int32_t, uint32_t, RET_osEvent) + +// Signal Service Calls + +/// Set the specified Signal Flags of an active thread +int32_t svcSignalSet (osThreadId thread_id, int32_t signals) { + P_TCB ptcb; + int32_t sig; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return 0x80000000; + + if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000; + + sig = ptcb->events; // Previous signal flags + + rt_evt_set(signals, ptcb->task_id); // Set event flags + + return sig; +} + +/// Clear the specified Signal Flags of an active thread +int32_t svcSignalClear (osThreadId thread_id, int32_t signals) { + P_TCB ptcb; + int32_t sig; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return 0x80000000; + + if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000; + + sig = ptcb->events; // Previous signal flags + + rt_evt_clr(signals, ptcb->task_id); // Clear event flags + + return sig; +} + +/// Get Signal Flags status of an active thread +int32_t svcSignalGet (osThreadId thread_id) { + P_TCB ptcb; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return 0x80000000; + + return ptcb->events; // Return event flags +} + +/// Wait for one or more Signal Flags to become signaled for the current RUNNING thread +os_InRegs osEvent_type svcSignalWait (int32_t signals, uint32_t millisec) { + OS_RESULT res; + osEvent ret; + + if (signals & (0xFFFFFFFF << osFeature_Signals)) { + ret.status = osErrorValue; + return osEvent_ret_status; + } + + if (signals != 0) { // Wait for all specified signals + res = rt_evt_wait(signals, rt_ms2tick(millisec), __TRUE); + } else { // Wait for any signal + res = rt_evt_wait(0xFFFF, rt_ms2tick(millisec), __FALSE); + } + + if (res == OS_R_EVT) { + ret.status = osEventSignal; + ret.value.signals = signals ? signals : os_tsk.run->waits; + } else { + ret.status = millisec ? osEventTimeout : osOK; + ret.value.signals = 0; + } + + return osEvent_ret_value; +} + + +// Signal ISR Calls + +/// Set the specified Signal Flags of an active thread +static __INLINE int32_t isrSignalSet (osThreadId thread_id, int32_t signals) { + P_TCB ptcb; + int32_t sig; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return 0x80000000; + + if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000; + + sig = ptcb->events; // Previous signal flags + + isr_evt_set(signals, ptcb->task_id); // Set event flags + + return sig; +} + + +// Signal Public API + +/// Set the specified Signal Flags of an active thread +int32_t osSignalSet (osThreadId thread_id, int32_t signals) { + if (__get_IPSR() != 0) { // in ISR + return isrSignalSet(thread_id, signals); + } else { // in Thread + return __svcSignalSet(thread_id, signals); + } +} + +/// Clear the specified Signal Flags of an active thread +int32_t osSignalClear (osThreadId thread_id, int32_t signals) { + if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + return __svcSignalClear(thread_id, signals); +} + +/// Get Signal Flags status of an active thread +int32_t osSignalGet (osThreadId thread_id) { + if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + return __svcSignalGet(thread_id); +} + +/// Wait for one or more Signal Flags to become signaled for the current RUNNING thread +os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec) { + osEvent ret; + + if (__get_IPSR() != 0) { // Not allowed in ISR + ret.status = osErrorISR; + return ret; + } + return __svcSignalWait(signals, millisec); +} + + +// ==== Mutex Management ==== + +// Mutex Service Calls declarations +SVC_1_1(svcMutexCreate, osMutexId, osMutexDef_t *, RET_pointer) +SVC_2_1(svcMutexWait, osStatus, osMutexId, uint32_t, RET_osStatus) +SVC_1_1(svcMutexRelease, osStatus, osMutexId, RET_osStatus) +SVC_1_1(svcMutexDelete, osStatus, osMutexId, RET_osStatus) + +// Mutex Service Calls + +/// Create and Initialize a Mutex object +osMutexId svcMutexCreate (osMutexDef_t *mutex_def) { + OS_ID mut; + + if (mutex_def == NULL) { + sysThreadError(osErrorParameter); + return NULL; + } + + mut = mutex_def->mutex; + if (mut == NULL) { + sysThreadError(osErrorParameter); + return NULL; + } + + if (((P_MUCB)mut)->cb_type != 0) { + sysThreadError(osErrorParameter); + return NULL; + } + + rt_mut_init(mut); // Initialize Mutex + + return mut; +} + +/// Wait until a Mutex becomes available +osStatus svcMutexWait (osMutexId mutex_id, uint32_t millisec) { + OS_ID mut; + OS_RESULT res; + + mut = rt_id2obj(mutex_id); + if (mut == NULL) return osErrorParameter; + + if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter; + + res = rt_mut_wait(mut, rt_ms2tick(millisec)); // Wait for Mutex + + if (res == OS_R_TMO) { + return (millisec ? osErrorTimeoutResource : osErrorResource); + } + + return osOK; +} + +/// Release a Mutex that was obtained with osMutexWait +osStatus svcMutexRelease (osMutexId mutex_id) { + OS_ID mut; + OS_RESULT res; + + mut = rt_id2obj(mutex_id); + if (mut == NULL) return osErrorParameter; + + if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter; + + res = rt_mut_release(mut); // Release Mutex + + if (res == OS_R_NOK) return osErrorResource; // Thread not owner or Zero Counter + + return osOK; +} + +/// Delete a Mutex that was created by osMutexCreate +osStatus svcMutexDelete (osMutexId mutex_id) { + OS_ID mut; + + mut = rt_id2obj(mutex_id); + if (mut == NULL) return osErrorParameter; + + if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter; + + rt_mut_delete(mut); // Release Mutex + + return osOK; +} + + +// Mutex Public API + +/// Create and Initialize a Mutex object +osMutexId osMutexCreate (osMutexDef_t *mutex_def) { + if (__get_IPSR() != 0) return NULL; // Not allowed in ISR + if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) { + // Privileged and not running + return svcMutexCreate(mutex_def); + } else { + return __svcMutexCreate(mutex_def); + } +} + +/// Wait until a Mutex becomes available +osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec) { + if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + return __svcMutexWait(mutex_id, millisec); +} + +/// Release a Mutex that was obtained with osMutexWait +osStatus osMutexRelease (osMutexId mutex_id) { + if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + return __svcMutexRelease(mutex_id); +} + +/// Delete a Mutex that was created by osMutexCreate +osStatus osMutexDelete (osMutexId mutex_id) { + if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + return __svcMutexDelete(mutex_id); +} + + +// ==== Semaphore Management ==== + +// Semaphore Service Calls declarations +SVC_2_1(svcSemaphoreCreate, osSemaphoreId, const osSemaphoreDef_t *, int32_t, RET_pointer) +SVC_2_1(svcSemaphoreWait, int32_t, osSemaphoreId, uint32_t, RET_int32_t) +SVC_1_1(svcSemaphoreRelease, osStatus, osSemaphoreId, RET_osStatus) +SVC_1_1(svcSemaphoreDelete, osStatus, osSemaphoreId, RET_osStatus) + +// Semaphore Service Calls + +/// Create and Initialize a Semaphore object +osSemaphoreId svcSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count) { + OS_ID sem; + + if (semaphore_def == NULL) { + sysThreadError(osErrorParameter); + return NULL; + } + + sem = semaphore_def->semaphore; + if (sem == NULL) { + sysThreadError(osErrorParameter); + return NULL; + } + + if (((P_SCB)sem)->cb_type != 0) { + sysThreadError(osErrorParameter); + return NULL; + } + + if (count > osFeature_Semaphore) { + sysThreadError(osErrorValue); + return NULL; + } + + rt_sem_init(sem, count); // Initialize Semaphore + + return sem; +} + +/// Wait until a Semaphore becomes available +int32_t svcSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) { + OS_ID sem; + OS_RESULT res; + + sem = rt_id2obj(semaphore_id); + if (sem == NULL) return -1; + + if (((P_SCB)sem)->cb_type != SCB) return -1; + + res = rt_sem_wait(sem, rt_ms2tick(millisec)); // Wait for Semaphore + + if (res == OS_R_TMO) return 0; // Timeout + + return (((P_SCB)sem)->tokens + 1); +} + +/// Release a Semaphore +osStatus svcSemaphoreRelease (osSemaphoreId semaphore_id) { + OS_ID sem; + + sem = rt_id2obj(semaphore_id); + if (sem == NULL) return osErrorParameter; + + if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter; + + if (((P_SCB)sem)->tokens == osFeature_Semaphore) return osErrorResource; + + rt_sem_send(sem); // Release Semaphore + + return osOK; +} + +/// Delete a Semaphore that was created by osSemaphoreCreate +osStatus svcSemaphoreDelete (osSemaphoreId semaphore_id) { + OS_ID sem; + + sem = rt_id2obj(semaphore_id); + if (sem == NULL) return osErrorParameter; + + if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter; + + rt_sem_delete(sem); // Delete Semaphore + + return osOK; +} + + +// Semaphore ISR Calls + +/// Release a Semaphore +static __INLINE osStatus isrSemaphoreRelease (osSemaphoreId semaphore_id) { + OS_ID sem; + + sem = rt_id2obj(semaphore_id); + if (sem == NULL) return osErrorParameter; + + if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter; + + if (((P_SCB)sem)->tokens == osFeature_Semaphore) return osErrorResource; + + isr_sem_send(sem); // Release Semaphore + + return osOK; +} + + +// Semaphore Public API + +/// Create and Initialize a Semaphore object +osSemaphoreId osSemaphoreCreate (osSemaphoreDef_t *semaphore_def, int32_t count) { + if (__get_IPSR() != 0) return NULL; // Not allowed in ISR + if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) { + // Privileged and not running + return svcSemaphoreCreate(semaphore_def, count); + } else { + return __svcSemaphoreCreate(semaphore_def, count); + } +} + +/// Wait until a Semaphore becomes available +int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) { + if (__get_IPSR() != 0) return -1; // Not allowed in ISR + return __svcSemaphoreWait(semaphore_id, millisec); +} + +/// Release a Semaphore +osStatus osSemaphoreRelease (osSemaphoreId semaphore_id) { + if (__get_IPSR() != 0) { // in ISR + return isrSemaphoreRelease(semaphore_id); + } else { // in Thread + return __svcSemaphoreRelease(semaphore_id); + } +} + +/// Delete a Semaphore that was created by osSemaphoreCreate +osStatus osSemaphoreDelete (osSemaphoreId semaphore_id) { + if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + return __svcSemaphoreDelete(semaphore_id); +} + + +// ==== Memory Management Functions ==== + +// Memory Management Helper Functions + +// Clear Memory Box (Zero init) +static void rt_clr_box (void *box_mem, void *box) { + uint32_t *p, n; + + if (box) { + p = box; + for (n = ((P_BM)box_mem)->blk_size; n; n -= 4) { + *p++ = 0; + } + } +} + +// Memory Management Service Calls declarations +SVC_1_1(svcPoolCreate, osPoolId, const osPoolDef_t *, RET_pointer) +SVC_2_1(sysPoolAlloc, void *, osPoolId, uint32_t, RET_pointer) +SVC_2_1(sysPoolFree, osStatus, osPoolId, void *, RET_osStatus) + +// Memory Management Service & ISR Calls + +/// Create and Initialize memory pool +osPoolId svcPoolCreate (const osPoolDef_t *pool_def) { + uint32_t blk_sz; + + if ((pool_def == NULL) || + (pool_def->pool_sz == 0) || + (pool_def->item_sz == 0) || + (pool_def->pool == NULL)) { + sysThreadError(osErrorParameter); + return NULL; + } + + blk_sz = (pool_def->item_sz + 3) & ~3; + + _init_box(pool_def->pool, sizeof(struct OS_BM) + pool_def->pool_sz * blk_sz, blk_sz); + + return pool_def->pool; +} + +/// Allocate a memory block from a memory pool +void *sysPoolAlloc (osPoolId pool_id, uint32_t clr) { + void *ptr; + + if (pool_id == NULL) return NULL; + + ptr = rt_alloc_box(pool_id); + if (clr) { + rt_clr_box(pool_id, ptr); + } + + return ptr; +} + +/// Return an allocated memory block back to a specific memory pool +osStatus sysPoolFree (osPoolId pool_id, void *block) { + int32_t res; + + if (pool_id == NULL) return osErrorParameter; + + res = rt_free_box(pool_id, block); + if (res != 0) return osErrorValue; + + return osOK; +} + + +// Memory Management Public API + +/// Create and Initialize memory pool +osPoolId osPoolCreate (osPoolDef_t *pool_def) { + if (__get_IPSR() != 0) return NULL; // Not allowed in ISR + if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) { + // Privileged and not running + return svcPoolCreate(pool_def); + } else { + return __svcPoolCreate(pool_def); + } +} + +/// Allocate a memory block from a memory pool +void *osPoolAlloc (osPoolId pool_id) { + if ((__get_IPSR() != 0) || ((__get_CONTROL() & 1) == 0)) { // in ISR or Privileged + return sysPoolAlloc(pool_id, 0); + } else { // in Thread + return __sysPoolAlloc(pool_id, 0); + } +} + +/// Allocate a memory block from a memory pool and set memory block to zero +void *osPoolCAlloc (osPoolId pool_id) { + if ((__get_IPSR() != 0) || ((__get_CONTROL() & 1) == 0)) { // in ISR or Privileged + return sysPoolAlloc(pool_id, 1); + } else { // in Thread + return __sysPoolAlloc(pool_id, 1); + } +} + +/// Return an allocated memory block back to a specific memory pool +osStatus osPoolFree (osPoolId pool_id, void *block) { + if ((__get_IPSR() != 0) || ((__get_CONTROL() & 1) == 0)) { // in ISR or Privileged + return sysPoolFree(pool_id, block); + } else { // in Thread + return __sysPoolFree(pool_id, block); + } +} + + +// ==== Message Queue Management Functions ==== + +// Message Queue Management Service Calls declarations +SVC_2_1(svcMessageCreate, osMessageQId, osMessageQDef_t *, osThreadId, RET_pointer) +SVC_3_1(svcMessagePut, osStatus, osMessageQId, uint32_t, uint32_t, RET_osStatus) +SVC_2_3(svcMessageGet, os_InRegs osEvent, osMessageQId, uint32_t, RET_osEvent) + +// Message Queue Service Calls + +/// Create and Initialize Message Queue +osMessageQId svcMessageCreate (osMessageQDef_t *queue_def, osThreadId thread_id) { + + if ((queue_def == NULL) || + (queue_def->queue_sz == 0) || + (queue_def->pool == NULL)) { + sysThreadError(osErrorParameter); + return NULL; + } + + if (((P_MCB)queue_def->pool)->cb_type != 0) { + sysThreadError(osErrorParameter); + return NULL; + } + + rt_mbx_init(queue_def->pool, 4*(queue_def->queue_sz + 4)); + + return queue_def->pool; +} + +/// Put a Message to a Queue +osStatus svcMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { + OS_RESULT res; + + if (queue_id == NULL) return osErrorParameter; + + if (((P_MCB)queue_id)->cb_type != MCB) return osErrorParameter; + + res = rt_mbx_send(queue_id, (void *)info, rt_ms2tick(millisec)); + + if (res == OS_R_TMO) { + return (millisec ? osErrorTimeoutResource : osErrorResource); + } + + return osOK; +} + +/// Get a Message or Wait for a Message from a Queue +os_InRegs osEvent_type svcMessageGet (osMessageQId queue_id, uint32_t millisec) { + OS_RESULT res; + osEvent ret; + + if (queue_id == NULL) { + ret.status = osErrorParameter; + return osEvent_ret_status; + } + + if (((P_MCB)queue_id)->cb_type != MCB) { + ret.status = osErrorParameter; + return osEvent_ret_status; + } + + res = rt_mbx_wait(queue_id, &ret.value.p, rt_ms2tick(millisec)); + + if (res == OS_R_TMO) { + ret.status = millisec ? osEventTimeout : osOK; + return osEvent_ret_value; + } + + ret.status = osEventMessage; + + return osEvent_ret_value; +} + + +// Message Queue ISR Calls + +/// Put a Message to a Queue +static __INLINE osStatus isrMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { + + if ((queue_id == NULL) || (millisec != 0)) { + return osErrorParameter; + } + + if (((P_MCB)queue_id)->cb_type != MCB) return osErrorParameter; + + if (rt_mbx_check(queue_id) == 0) { // Check if Queue is full + return osErrorResource; + } + + isr_mbx_send(queue_id, (void *)info); + + return osOK; +} + +/// Get a Message or Wait for a Message from a Queue +static __INLINE os_InRegs osEvent isrMessageGet (osMessageQId queue_id, uint32_t millisec) { + OS_RESULT res; + osEvent ret; + + if ((queue_id == NULL) || (millisec != 0)) { + ret.status = osErrorParameter; + return ret; + } + + if (((P_MCB)queue_id)->cb_type != MCB) { + ret.status = osErrorParameter; + return ret; + } + + res = isr_mbx_receive(queue_id, &ret.value.p); + + if (res != OS_R_MBX) { + ret.status = osOK; + return ret; + } + + ret.status = osEventMessage; + + return ret; +} + + +// Message Queue Management Public API + +/// Create and Initialize Message Queue +osMessageQId osMessageCreate (osMessageQDef_t *queue_def, osThreadId thread_id) { + if (__get_IPSR() != 0) return NULL; // Not allowed in ISR + if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) { + // Privileged and not running + return svcMessageCreate(queue_def, thread_id); + } else { + return __svcMessageCreate(queue_def, thread_id); + } +} + +/// Put a Message to a Queue +osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { + if (__get_IPSR() != 0) { // in ISR + return isrMessagePut(queue_id, info, millisec); + } else { // in Thread + return __svcMessagePut(queue_id, info, millisec); + } +} + +/// Get a Message or Wait for a Message from a Queue +os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec) { + if (__get_IPSR() != 0) { // in ISR + return isrMessageGet(queue_id, millisec); + } else { // in Thread + return __svcMessageGet(queue_id, millisec); + } +} + + +// ==== Mail Queue Management Functions ==== + +// Mail Queue Management Service Calls declarations +SVC_2_1(svcMailCreate, osMailQId, osMailQDef_t *, osThreadId, RET_pointer) +SVC_4_1(sysMailAlloc, void *, osMailQId, uint32_t, uint32_t, uint32_t, RET_pointer) +SVC_3_1(sysMailFree, osStatus, osMailQId, void *, uint32_t, RET_osStatus) + +// Mail Queue Management Service & ISR Calls + +/// Create and Initialize mail queue +osMailQId svcMailCreate (osMailQDef_t *queue_def, osThreadId thread_id) { + uint32_t blk_sz; + P_MCB pmcb; + void *pool; + + if ((queue_def == NULL) || + (queue_def->queue_sz == 0) || + (queue_def->item_sz == 0) || + (queue_def->pool == NULL)) { + sysThreadError(osErrorParameter); + return NULL; + } + + pmcb = *(((void **)queue_def->pool) + 0); + pool = *(((void **)queue_def->pool) + 1); + + if ((pool == NULL) || (pmcb == NULL) || (pmcb->cb_type != 0)) { + sysThreadError(osErrorParameter); + return NULL; + } + + blk_sz = (queue_def->item_sz + 3) & ~3; + + _init_box(pool, sizeof(struct OS_BM) + queue_def->queue_sz * blk_sz, blk_sz); + + rt_mbx_init(pmcb, 4*(queue_def->queue_sz + 4)); + + + return queue_def->pool; +} + +/// Allocate a memory block from a mail +void *sysMailAlloc (osMailQId queue_id, uint32_t millisec, uint32_t isr, uint32_t clr) { + P_MCB pmcb; + void *pool; + void *mem; + + if (queue_id == NULL) return NULL; + + pmcb = *(((void **)queue_id) + 0); + pool = *(((void **)queue_id) + 1); + + if ((pool == NULL) || (pmcb == NULL)) return NULL; + + if (isr && (millisec != 0)) return NULL; + + mem = rt_alloc_box(pool); + if (clr) { + rt_clr_box(pool, mem); + } + + if ((mem == NULL) && (millisec != 0)) { + // Put Task to sleep when Memory not available + if (pmcb->p_lnk != NULL) { + rt_put_prio((P_XCB)pmcb, os_tsk.run); + } else { + pmcb->p_lnk = os_tsk.run; + os_tsk.run->p_lnk = NULL; + os_tsk.run->p_rlnk = (P_TCB)pmcb; + // Task is waiting to allocate a message + pmcb->state = 3; + } + rt_block(rt_ms2tick(millisec), WAIT_MBX); + } + + return mem; +} + +/// Free a memory block from a mail +osStatus sysMailFree (osMailQId queue_id, void *mail, uint32_t isr) { + P_MCB pmcb; + P_TCB ptcb; + void *pool; + void *mem; + int32_t res; + + if (queue_id == NULL) return osErrorParameter; + + pmcb = *(((void **)queue_id) + 0); + pool = *(((void **)queue_id) + 1); + + if ((pmcb == NULL) || (pool == NULL)) return osErrorParameter; + + res = rt_free_box(pool, mail); + + if (res != 0) return osErrorValue; + + if (pmcb->state == 3) { + // Task is waiting to allocate a message + if (isr) { + rt_psq_enq (pmcb, (U32)pool); + rt_psh_req (); + } else { + mem = rt_alloc_box(pool); + if (mem != NULL) { + ptcb = rt_get_first((P_XCB)pmcb); + if (pmcb->p_lnk == NULL) { + pmcb->state = 0; + } + rt_ret_val(ptcb, (U32)mem); + rt_rmv_dly(ptcb); + rt_dispatch(ptcb); + } + } + } + + return osOK; +} + + +// Mail Queue Management Public API + +/// Create and Initialize mail queue +osMailQId osMailCreate (osMailQDef_t *queue_def, osThreadId thread_id) { + if (__get_IPSR() != 0) return NULL; // Not allowed in ISR + if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) { + // Privileged and not running + return svcMailCreate(queue_def, thread_id); + } else { + return __svcMailCreate(queue_def, thread_id); + } +} + +/// Allocate a memory block from a mail +void *osMailAlloc (osMailQId queue_id, uint32_t millisec) { + if (__get_IPSR() != 0) { // in ISR + return sysMailAlloc(queue_id, millisec, 1, 0); + } else { // in Thread + return __sysMailAlloc(queue_id, millisec, 0, 0); + } +} + +/// Allocate a memory block from a mail and set memory block to zero +void *osMailCAlloc (osMailQId queue_id, uint32_t millisec) { + if (__get_IPSR() != 0) { // in ISR + return sysMailAlloc(queue_id, millisec, 1, 1); + } else { // in Thread + return __sysMailAlloc(queue_id, millisec, 0, 1); + } +} + +/// Free a memory block from a mail +osStatus osMailFree (osMailQId queue_id, void *mail) { + if (__get_IPSR() != 0) { // in ISR + return sysMailFree(queue_id, mail, 1); + } else { // in Thread + return __sysMailFree(queue_id, mail, 0); + } +} + +/// Put a mail to a queue +osStatus osMailPut (osMailQId queue_id, void *mail) { + if (queue_id == NULL) return osErrorParameter; + if (mail == NULL) return osErrorValue; + return osMessagePut(*((void **)queue_id), (uint32_t)mail, 0); +} + +/// Get a mail from a queue +os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec) { + osEvent ret; + + if (queue_id == NULL) { + ret.status = osErrorParameter; + return ret; + } + + ret = osMessageGet(*((void **)queue_id), millisec); + if (ret.status == osEventMessage) ret.status = osEventMail; + + return ret; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/rt_Event.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,190 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_EVENT.C + * Purpose: Implements waits and wake-ups for event flags + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_System.h" +#include "rt_Event.h" +#include "rt_List.h" +#include "rt_Task.h" +#include "rt_HAL_CM.h" + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_evt_wait -----------------------------------*/ + +OS_RESULT rt_evt_wait (U16 wait_flags, U16 timeout, BOOL and_wait) { + /* Wait for one or more event flags with optional time-out. */ + /* "wait_flags" identifies the flags to wait for. */ + /* "timeout" is the time-out limit in system ticks (0xffff if no time-out) */ + /* "and_wait" specifies the AND-ing of "wait_flags" as condition to be met */ + /* to complete the wait. (OR-ing if set to 0). */ + U32 block_state; + + if (and_wait) { + /* Check for AND-connected events */ + if ((os_tsk.run->events & wait_flags) == wait_flags) { + os_tsk.run->events &= ~wait_flags; + return (OS_R_EVT); + } + block_state = WAIT_AND; + } + else { + /* Check for OR-connected events */ + if (os_tsk.run->events & wait_flags) { + os_tsk.run->waits = os_tsk.run->events & wait_flags; + os_tsk.run->events &= ~wait_flags; + return (OS_R_EVT); + } + block_state = WAIT_OR; + } + /* Task has to wait */ + os_tsk.run->waits = wait_flags; + rt_block (timeout, (U8)block_state); + return (OS_R_TMO); +} + + +/*--------------------------- rt_evt_set ------------------------------------*/ + +void rt_evt_set (U16 event_flags, OS_TID task_id) { + /* Set one or more event flags of a selectable task. */ + P_TCB p_tcb; + + p_tcb = os_active_TCB[task_id-1]; + if (p_tcb == NULL) { + return; + } + p_tcb->events |= event_flags; + event_flags = p_tcb->waits; + /* If the task is not waiting for an event, it should not be put */ + /* to ready state. */ + if (p_tcb->state == WAIT_AND) { + /* Check for AND-connected events */ + if ((p_tcb->events & event_flags) == event_flags) { + goto wkup; + } + } + if (p_tcb->state == WAIT_OR) { + /* Check for OR-connected events */ + if (p_tcb->events & event_flags) { + p_tcb->waits &= p_tcb->events; +wkup: p_tcb->events &= ~event_flags; + rt_rmv_dly (p_tcb); + p_tcb->state = READY; +#ifdef __CMSIS_RTOS + rt_ret_val2(p_tcb, 0x08/*osEventSignal*/, p_tcb->waits); +#else + rt_ret_val (p_tcb, OS_R_EVT); +#endif + rt_dispatch (p_tcb); + } + } +} + + +/*--------------------------- rt_evt_clr ------------------------------------*/ + +void rt_evt_clr (U16 clear_flags, OS_TID task_id) { + /* Clear one or more event flags (identified by "clear_flags") of a */ + /* selectable task (identified by "task"). */ + P_TCB task = os_active_TCB[task_id-1]; + + if (task == NULL) { + return; + } + task->events &= ~clear_flags; +} + + +/*--------------------------- isr_evt_set -----------------------------------*/ + +void isr_evt_set (U16 event_flags, OS_TID task_id) { + /* Same function as "os_evt_set", but to be called by ISRs. */ + P_TCB p_tcb = os_active_TCB[task_id-1]; + + if (p_tcb == NULL) { + return; + } + rt_psq_enq (p_tcb, event_flags); + rt_psh_req (); +} + + +/*--------------------------- rt_evt_get ------------------------------------*/ + +U16 rt_evt_get (void) { + /* Get events of a running task after waiting for OR connected events. */ + return (os_tsk.run->waits); +} + + +/*--------------------------- rt_evt_psh ------------------------------------*/ + +void rt_evt_psh (P_TCB p_CB, U16 set_flags) { + /* Check if task has to be waken up */ + U16 event_flags; + + p_CB->events |= set_flags; + event_flags = p_CB->waits; + if (p_CB->state == WAIT_AND) { + /* Check for AND-connected events */ + if ((p_CB->events & event_flags) == event_flags) { + goto rdy; + } + } + if (p_CB->state == WAIT_OR) { + /* Check for OR-connected events */ + if (p_CB->events & event_flags) { + p_CB->waits &= p_CB->events; +rdy: p_CB->events &= ~event_flags; + rt_rmv_dly (p_CB); + p_CB->state = READY; +#ifdef __CMSIS_RTOS + rt_ret_val2(p_CB, 0x08/*osEventSignal*/, p_CB->waits); +#else + rt_ret_val (p_CB, OS_R_EVT); +#endif + rt_put_prio (&os_rdy, p_CB); + } + } +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/rt_Event.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,46 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_EVENT.H + * Purpose: Implements waits and wake-ups for event flags + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +/* Functions */ +extern OS_RESULT rt_evt_wait (U16 wait_flags, U16 timeout, BOOL and_wait); +extern void rt_evt_set (U16 event_flags, OS_TID task_id); +extern void rt_evt_clr (U16 clear_flags, OS_TID task_id); +extern void isr_evt_set (U16 event_flags, OS_TID task_id); +extern U16 rt_evt_get (void); +extern void rt_evt_psh (P_TCB p_CB, U16 set_flags); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/rt_HAL_CM.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,276 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_HAL_CM.H + * Purpose: Hardware Abstraction Layer for Cortex-M definitions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +/* Definitions */ +#define INITIAL_xPSR 0x01000000 +#define DEMCR_TRCENA 0x01000000 +#define ITM_ITMENA 0x00000001 +#define MAGIC_WORD 0xE25A2EA5 + +#if defined (__CC_ARM) /* ARM Compiler */ + +#if ((__TARGET_ARCH_7_M || __TARGET_ARCH_7E_M) && !NO_EXCLUSIVE_ACCESS) + #define __USE_EXCLUSIVE_ACCESS +#else + #undef __USE_EXCLUSIVE_ACCESS +#endif + +#elif defined (__GNUC__) /* GNU Compiler */ + +#undef __USE_EXCLUSIVE_ACCESS + +#if defined (__CORTEX_M0) || defined (__CORTEX_M0PLUS) +#define __TARGET_ARCH_6S_M 1 +#else +#define __TARGET_ARCH_6S_M 0 +#endif + +#if defined (__VFP_FP__) && !defined(__SOFTFP__) +#define __TARGET_FPU_VFP 1 +#else +#define __TARGET_FPU_VFP 0 +#endif + +#define __inline inline +#define __weak __attribute__((weak)) + +#ifndef __CMSIS_GENERIC + +__attribute__((always_inline)) static inline void __enable_irq(void) +{ + __asm volatile ("cpsie i"); +} + +__attribute__((always_inline)) static inline U32 __disable_irq(void) +{ + U32 result; + + __asm volatile ("mrs %0, primask" : "=r" (result)); + __asm volatile ("cpsid i"); + return(result & 1); +} + +#endif + +__attribute__(( always_inline)) static inline U8 __clz(U32 value) +{ + U8 result; + + __asm volatile ("clz %0, %1" : "=r" (result) : "r" (value)); + return(result); +} + +#elif defined (__ICCARM__) /* IAR Compiler */ + +#undef __USE_EXCLUSIVE_ACCESS + +#if (__CORE__ == __ARM6M__) +#define __TARGET_ARCH_6S_M 1 +#else +#define __TARGET_ARCH_6S_M 0 +#endif + +#if defined __ARMVFP__ +#define __TARGET_FPU_VFP 1 +#else +#define __TARGET_FPU_VFP 0 +#endif + +#define __inline inline + +#ifndef __CMSIS_GENERIC + +static inline void __enable_irq(void) +{ + __asm volatile ("cpsie i"); +} + +static inline U32 __disable_irq(void) +{ + U32 result; + + __asm volatile ("mrs %0, primask" : "=r" (result)); + __asm volatile ("cpsid i"); + return(result & 1); +} + +#endif + +static inline U8 __clz(U32 value) +{ + U8 result; + + __asm volatile ("clz %0, %1" : "=r" (result) : "r" (value)); + return(result); +} + +#endif + +/* NVIC registers */ +#define NVIC_ST_CTRL (*((volatile U32 *)0xE000E010)) +#define NVIC_ST_RELOAD (*((volatile U32 *)0xE000E014)) +#define NVIC_ST_CURRENT (*((volatile U32 *)0xE000E018)) +#define NVIC_ISER ((volatile U32 *)0xE000E100) +#define NVIC_ICER ((volatile U32 *)0xE000E180) +#if (__TARGET_ARCH_6S_M) +#define NVIC_IP ((volatile U32 *)0xE000E400) +#else +#define NVIC_IP ((volatile U8 *)0xE000E400) +#endif +#define NVIC_INT_CTRL (*((volatile U32 *)0xE000ED04)) +#define NVIC_AIR_CTRL (*((volatile U32 *)0xE000ED0C)) +#define NVIC_SYS_PRI2 (*((volatile U32 *)0xE000ED1C)) +#define NVIC_SYS_PRI3 (*((volatile U32 *)0xE000ED20)) + +#define OS_PEND_IRQ() NVIC_INT_CTRL = (1<<28) +#define OS_PENDING ((NVIC_INT_CTRL >> 26) & (1<<2 | 1)) +#define OS_UNPEND(fl) NVIC_INT_CTRL = (*fl = OS_PENDING) << 25 +#define OS_PEND(fl,p) NVIC_INT_CTRL = (fl | p<<2) << 26 +#define OS_LOCK() NVIC_ST_CTRL = 0x0005 +#define OS_UNLOCK() NVIC_ST_CTRL = 0x0007 + +#define OS_X_PENDING ((NVIC_INT_CTRL >> 28) & 1) +#define OS_X_UNPEND(fl) NVIC_INT_CTRL = (*fl = OS_X_PENDING) << 27 +#define OS_X_PEND(fl,p) NVIC_INT_CTRL = (fl | p) << 28 +#if (__TARGET_ARCH_6S_M) +#define OS_X_INIT(n) NVIC_IP[n>>2] |= 0xFF << (8*(n & 0x03)); \ + NVIC_ISER[n>>5] = 1 << (n & 0x1F) +#else +#define OS_X_INIT(n) NVIC_IP[n] = 0xFF; \ + NVIC_ISER[n>>5] = 1 << (n & 0x1F) +#endif +#define OS_X_LOCK(n) NVIC_ICER[n>>5] = 1 << (n & 0x1F) +#define OS_X_UNLOCK(n) NVIC_ISER[n>>5] = 1 << (n & 0x1F) + +/* Core Debug registers */ +#define DEMCR (*((volatile U32 *)0xE000EDFC)) + +/* ITM registers */ +#define ITM_CONTROL (*((volatile U32 *)0xE0000E80)) +#define ITM_ENABLE (*((volatile U32 *)0xE0000E00)) +#define ITM_PORT30_U32 (*((volatile U32 *)0xE0000078)) +#define ITM_PORT31_U32 (*((volatile U32 *)0xE000007C)) +#define ITM_PORT31_U16 (*((volatile U16 *)0xE000007C)) +#define ITM_PORT31_U8 (*((volatile U8 *)0xE000007C)) + +/* Variables */ +extern BIT dbg_msg; + +/* Functions */ +#ifdef __USE_EXCLUSIVE_ACCESS + #define rt_inc(p) while(__strex((__ldrex(p)+1),p)) + #define rt_dec(p) while(__strex((__ldrex(p)-1),p)) +#else + #define rt_inc(p) __disable_irq();(*p)++;__enable_irq(); + #define rt_dec(p) __disable_irq();(*p)--;__enable_irq(); +#endif + +__inline static U32 rt_inc_qi (U32 size, U8 *count, U8 *first) { + U32 cnt,c2; +#ifdef __USE_EXCLUSIVE_ACCESS + do { + if ((cnt = __ldrex(count)) == size) { + __clrex(); + return (cnt); } + } while (__strex(cnt+1, count)); + do { + c2 = (cnt = __ldrex(first)) + 1; + if (c2 == size) c2 = 0; + } while (__strex(c2, first)); +#else + __disable_irq(); + if ((cnt = *count) < size) { + *count = cnt+1; + c2 = (cnt = *first) + 1; + if (c2 == size) c2 = 0; + *first = c2; + } + __enable_irq (); +#endif + return (cnt); +} + +__inline static void rt_systick_init (void) { + NVIC_ST_RELOAD = os_trv; + NVIC_ST_CURRENT = 0; + NVIC_ST_CTRL = 0x0007; + NVIC_SYS_PRI3 |= 0xFF000000; +} + +__inline static void rt_svc_init (void) { +#if !(__TARGET_ARCH_6S_M) + int sh,prigroup; +#endif + NVIC_SYS_PRI3 |= 0x00FF0000; +#if (__TARGET_ARCH_6S_M) + NVIC_SYS_PRI2 |= (NVIC_SYS_PRI3<<(8+1)) & 0xFC000000; +#else + sh = 8 - __clz (~((NVIC_SYS_PRI3 << 8) & 0xFF000000)); + prigroup = ((NVIC_AIR_CTRL >> 8) & 0x07); + if (prigroup >= sh) { + sh = prigroup + 1; + } + NVIC_SYS_PRI2 = ((0xFEFFFFFF << sh) & 0xFF000000) | (NVIC_SYS_PRI2 & 0x00FFFFFF); +#endif +} + +extern void rt_set_PSP (U32 stack); +extern U32 rt_get_PSP (void); +extern void os_set_env (void); +extern void *_alloc_box (void *box_mem); +extern int _free_box (void *box_mem, void *box); + +extern void rt_init_stack (P_TCB p_TCB, FUNCP task_body); +extern void rt_ret_val (P_TCB p_TCB, U32 v0); +extern void rt_ret_val2 (P_TCB p_TCB, U32 v0, U32 v1); + +extern void dbg_init (void); +extern void dbg_task_notify (P_TCB p_tcb, BOOL create); +extern void dbg_task_switch (U32 task_id); + +#ifdef DBG_MSG +#define DBG_INIT() dbg_init() +#define DBG_TASK_NOTIFY(p_tcb,create) if (dbg_msg) dbg_task_notify(p_tcb,create) +#define DBG_TASK_SWITCH(task_id) if (dbg_msg && (os_tsk.new_tsk != os_tsk.run)) \ + dbg_task_switch(task_id) +#else +#define DBG_INIT() +#define DBG_TASK_NOTIFY(p_tcb,create) +#define DBG_TASK_SWITCH(task_id) +#endif + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/rt_List.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,320 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_LIST.C + * Purpose: Functions for the management of different lists + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_System.h" +#include "rt_List.h" +#include "rt_Task.h" +#include "rt_Time.h" +#include "rt_HAL_CM.h" + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +/* List head of chained ready tasks */ +struct OS_XCB os_rdy; +/* List head of chained delay tasks */ +struct OS_XCB os_dly; + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_put_prio -----------------------------------*/ + +void rt_put_prio (P_XCB p_CB, P_TCB p_task) { + /* Put task identified with "p_task" into list ordered by priority. */ + /* "p_CB" points to head of list; list has always an element at end with */ + /* a priority less than "p_task->prio". */ + P_TCB p_CB2; + U32 prio; + BOOL sem_mbx = __FALSE; + + if (p_CB->cb_type == SCB || p_CB->cb_type == MCB || p_CB->cb_type == MUCB) { + sem_mbx = __TRUE; + } + prio = p_task->prio; + p_CB2 = p_CB->p_lnk; + /* Search for an entry in the list */ + while (p_CB2 != NULL && prio <= p_CB2->prio) { + p_CB = (P_XCB)p_CB2; + p_CB2 = p_CB2->p_lnk; + } + /* Entry found, insert the task into the list */ + p_task->p_lnk = p_CB2; + p_CB->p_lnk = p_task; + if (sem_mbx) { + if (p_CB2 != NULL) { + p_CB2->p_rlnk = p_task; + } + p_task->p_rlnk = (P_TCB)p_CB; + } + else { + p_task->p_rlnk = NULL; + } +} + + +/*--------------------------- rt_get_first ----------------------------------*/ + +P_TCB rt_get_first (P_XCB p_CB) { + /* Get task at head of list: it is the task with highest priority. */ + /* "p_CB" points to head of list. */ + P_TCB p_first; + + p_first = p_CB->p_lnk; + p_CB->p_lnk = p_first->p_lnk; + if (p_CB->cb_type == SCB || p_CB->cb_type == MCB || p_CB->cb_type == MUCB) { + if (p_first->p_lnk != NULL) { + p_first->p_lnk->p_rlnk = (P_TCB)p_CB; + p_first->p_lnk = NULL; + } + p_first->p_rlnk = NULL; + } + else { + p_first->p_lnk = NULL; + } + return (p_first); +} + + +/*--------------------------- rt_put_rdy_first ------------------------------*/ + +void rt_put_rdy_first (P_TCB p_task) { + /* Put task identified with "p_task" at the head of the ready list. The */ + /* task must have at least a priority equal to highest priority in list. */ + p_task->p_lnk = os_rdy.p_lnk; + p_task->p_rlnk = NULL; + os_rdy.p_lnk = p_task; +} + + +/*--------------------------- rt_get_same_rdy_prio --------------------------*/ + +P_TCB rt_get_same_rdy_prio (void) { + /* Remove a task of same priority from ready list if any exists. Other- */ + /* wise return NULL. */ + P_TCB p_first; + + p_first = os_rdy.p_lnk; + if (p_first->prio == os_tsk.run->prio) { + os_rdy.p_lnk = os_rdy.p_lnk->p_lnk; + return (p_first); + } + return (NULL); +} + + +/*--------------------------- rt_resort_prio --------------------------------*/ + +void rt_resort_prio (P_TCB p_task) { + /* Re-sort ordered lists after the priority of 'p_task' has changed. */ + P_TCB p_CB; + + if (p_task->p_rlnk == NULL) { + if (p_task->state == READY) { + /* Task is chained into READY list. */ + p_CB = (P_TCB)&os_rdy; + goto res; + } + } + else { + p_CB = p_task->p_rlnk; + while (p_CB->cb_type == TCB) { + /* Find a header of this task chain list. */ + p_CB = p_CB->p_rlnk; + } +res:rt_rmv_list (p_task); + rt_put_prio ((P_XCB)p_CB, p_task); + } +} + + +/*--------------------------- rt_put_dly ------------------------------------*/ + +void rt_put_dly (P_TCB p_task, U16 delay) { + /* Put a task identified with "p_task" into chained delay wait list using */ + /* a delay value of "delay". */ + P_TCB p; + U32 delta,idelay = delay; + + p = (P_TCB)&os_dly; + if (p->p_dlnk == NULL) { + /* Delay list empty */ + delta = 0; + goto last; + } + delta = os_dly.delta_time; + while (delta < idelay) { + if (p->p_dlnk == NULL) { + /* End of list found */ +last: p_task->p_dlnk = NULL; + p->p_dlnk = p_task; + p_task->p_blnk = p; + p->delta_time = (U16)(idelay - delta); + p_task->delta_time = 0; + return; + } + p = p->p_dlnk; + delta += p->delta_time; + } + /* Right place found */ + p_task->p_dlnk = p->p_dlnk; + p->p_dlnk = p_task; + p_task->p_blnk = p; + if (p_task->p_dlnk != NULL) { + p_task->p_dlnk->p_blnk = p_task; + } + p_task->delta_time = (U16)(delta - idelay); + p->delta_time -= p_task->delta_time; +} + + +/*--------------------------- rt_dec_dly ------------------------------------*/ + +void rt_dec_dly (void) { + /* Decrement delta time of list head: remove tasks having a value of zero.*/ + P_TCB p_rdy; + + if (os_dly.p_dlnk == NULL) { + return; + } + os_dly.delta_time--; + while ((os_dly.delta_time == 0) && (os_dly.p_dlnk != NULL)) { + p_rdy = os_dly.p_dlnk; + if (p_rdy->p_rlnk != NULL) { + /* Task is really enqueued, remove task from semaphore/mailbox */ + /* timeout waiting list. */ + p_rdy->p_rlnk->p_lnk = p_rdy->p_lnk; + if (p_rdy->p_lnk != NULL) { + p_rdy->p_lnk->p_rlnk = p_rdy->p_rlnk; + p_rdy->p_lnk = NULL; + } + p_rdy->p_rlnk = NULL; + } + rt_put_prio (&os_rdy, p_rdy); + os_dly.delta_time = p_rdy->delta_time; + if (p_rdy->state == WAIT_ITV) { + /* Calculate the next time for interval wait. */ + p_rdy->delta_time = p_rdy->interval_time + (U16)os_time; + } + p_rdy->state = READY; + os_dly.p_dlnk = p_rdy->p_dlnk; + if (p_rdy->p_dlnk != NULL) { + p_rdy->p_dlnk->p_blnk = (P_TCB)&os_dly; + p_rdy->p_dlnk = NULL; + } + p_rdy->p_blnk = NULL; + } +} + + +/*--------------------------- rt_rmv_list -----------------------------------*/ + +void rt_rmv_list (P_TCB p_task) { + /* Remove task identified with "p_task" from ready, semaphore or mailbox */ + /* waiting list if enqueued. */ + P_TCB p_b; + + if (p_task->p_rlnk != NULL) { + /* A task is enqueued in semaphore / mailbox waiting list. */ + p_task->p_rlnk->p_lnk = p_task->p_lnk; + if (p_task->p_lnk != NULL) { + p_task->p_lnk->p_rlnk = p_task->p_rlnk; + } + return; + } + + p_b = (P_TCB)&os_rdy; + while (p_b != NULL) { + /* Search the ready list for task "p_task" */ + if (p_b->p_lnk == p_task) { + p_b->p_lnk = p_task->p_lnk; + return; + } + p_b = p_b->p_lnk; + } +} + + +/*--------------------------- rt_rmv_dly ------------------------------------*/ + +void rt_rmv_dly (P_TCB p_task) { + /* Remove task identified with "p_task" from delay list if enqueued. */ + P_TCB p_b; + + p_b = p_task->p_blnk; + if (p_b != NULL) { + /* Task is really enqueued */ + p_b->p_dlnk = p_task->p_dlnk; + if (p_task->p_dlnk != NULL) { + /* 'p_task' is in the middle of list */ + p_b->delta_time += p_task->delta_time; + p_task->p_dlnk->p_blnk = p_b; + p_task->p_dlnk = NULL; + } + else { + /* 'p_task' is at the end of list */ + p_b->delta_time = 0; + } + p_task->p_blnk = NULL; + } +} + + +/*--------------------------- rt_psq_enq ------------------------------------*/ + +void rt_psq_enq (OS_ID entry, U32 arg) { + /* Insert post service request "entry" into ps-queue. */ + U32 idx; + + idx = rt_inc_qi (os_psq->size, &os_psq->count, &os_psq->first); + if (idx < os_psq->size) { + os_psq->q[idx].id = entry; + os_psq->q[idx].arg = arg; + } + else { + os_error (OS_ERR_FIFO_OVF); + } +} + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/rt_List.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,67 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_LIST.H + * Purpose: Functions for the management of different lists + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +/* Definitions */ + +/* Values for 'cb_type' */ +#define TCB 0 +#define MCB 1 +#define SCB 2 +#define MUCB 3 +#define HCB 4 + +/* Variables */ +extern struct OS_XCB os_rdy; +extern struct OS_XCB os_dly; + +/* Functions */ +extern void rt_put_prio (P_XCB p_CB, P_TCB p_task); +extern P_TCB rt_get_first (P_XCB p_CB); +extern void rt_put_rdy_first (P_TCB p_task); +extern P_TCB rt_get_same_rdy_prio (void); +extern void rt_resort_prio (P_TCB p_task); +extern void rt_put_dly (P_TCB p_task, U16 delay); +extern void rt_dec_dly (void); +extern void rt_rmv_list (P_TCB p_task); +extern void rt_rmv_dly (P_TCB p_task); +extern void rt_psq_enq (OS_ID entry, U32 arg); + +/* This is a fast macro generating in-line code */ +#define rt_rdy_prio(void) (os_rdy.p_lnk->prio) + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/rt_Mailbox.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,292 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MAILBOX.C + * Purpose: Implements waits and wake-ups for mailbox messages + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_System.h" +#include "rt_List.h" +#include "rt_Mailbox.h" +#include "rt_MemBox.h" +#include "rt_Task.h" +#include "rt_HAL_CM.h" + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_mbx_init -----------------------------------*/ + +void rt_mbx_init (OS_ID mailbox, U16 mbx_size) { + /* Initialize a mailbox */ + P_MCB p_MCB = mailbox; + + p_MCB->cb_type = MCB; + p_MCB->state = 0; + p_MCB->isr_st = 0; + p_MCB->p_lnk = NULL; + p_MCB->first = 0; + p_MCB->last = 0; + p_MCB->count = 0; + p_MCB->size = (mbx_size + sizeof(void *) - sizeof(struct OS_MCB)) / + (U32)sizeof (void *); +} + + +/*--------------------------- rt_mbx_send -----------------------------------*/ + +OS_RESULT rt_mbx_send (OS_ID mailbox, void *p_msg, U16 timeout) { + /* Send message to a mailbox */ + P_MCB p_MCB = mailbox; + P_TCB p_TCB; + + if ((p_MCB->p_lnk != NULL) && (p_MCB->state == 1)) { + /* A task is waiting for message */ + p_TCB = rt_get_first ((P_XCB)p_MCB); +#ifdef __CMSIS_RTOS + rt_ret_val2(p_TCB, 0x10/*osEventMessage*/, (U32)p_msg); +#else + *p_TCB->msg = p_msg; + rt_ret_val (p_TCB, OS_R_MBX); +#endif + rt_rmv_dly (p_TCB); + rt_dispatch (p_TCB); + } + else { + /* Store message in mailbox queue */ + if (p_MCB->count == p_MCB->size) { + /* No free message entry, wait for one. If message queue is full, */ + /* then no task is waiting for message. The 'p_MCB->p_lnk' list */ + /* pointer can now be reused for send message waits task list. */ + if (timeout == 0) { + return (OS_R_TMO); + } + if (p_MCB->p_lnk != NULL) { + rt_put_prio ((P_XCB)p_MCB, os_tsk.run); + } + else { + p_MCB->p_lnk = os_tsk.run; + os_tsk.run->p_lnk = NULL; + os_tsk.run->p_rlnk = (P_TCB)p_MCB; + /* Task is waiting to send a message */ + p_MCB->state = 2; + } + os_tsk.run->msg = p_msg; + rt_block (timeout, WAIT_MBX); + return (OS_R_TMO); + } + /* Yes, there is a free entry in a mailbox. */ + p_MCB->msg[p_MCB->first] = p_msg; + rt_inc (&p_MCB->count); + if (++p_MCB->first == p_MCB->size) { + p_MCB->first = 0; + } + } + return (OS_R_OK); +} + + +/*--------------------------- rt_mbx_wait -----------------------------------*/ + +OS_RESULT rt_mbx_wait (OS_ID mailbox, void **message, U16 timeout) { + /* Receive a message; possibly wait for it */ + P_MCB p_MCB = mailbox; + P_TCB p_TCB; + + /* If a message is available in the fifo buffer */ + /* remove it from the fifo buffer and return. */ + if (p_MCB->count) { + *message = p_MCB->msg[p_MCB->last]; + if (++p_MCB->last == p_MCB->size) { + p_MCB->last = 0; + } + if ((p_MCB->p_lnk != NULL) && (p_MCB->state == 2)) { + /* A task is waiting to send message */ + p_TCB = rt_get_first ((P_XCB)p_MCB); +#ifdef __CMSIS_RTOS + rt_ret_val(p_TCB, 0/*osOK*/); +#else + rt_ret_val(p_TCB, OS_R_OK); +#endif + p_MCB->msg[p_MCB->first] = p_TCB->msg; + if (++p_MCB->first == p_MCB->size) { + p_MCB->first = 0; + } + rt_rmv_dly (p_TCB); + rt_dispatch (p_TCB); + } + else { + rt_dec (&p_MCB->count); + } + return (OS_R_OK); + } + /* No message available: wait for one */ + if (timeout == 0) { + return (OS_R_TMO); + } + if (p_MCB->p_lnk != NULL) { + rt_put_prio ((P_XCB)p_MCB, os_tsk.run); + } + else { + p_MCB->p_lnk = os_tsk.run; + os_tsk.run->p_lnk = NULL; + os_tsk.run->p_rlnk = (P_TCB)p_MCB; + /* Task is waiting to receive a message */ + p_MCB->state = 1; + } + rt_block(timeout, WAIT_MBX); +#ifndef __CMSIS_RTOS + os_tsk.run->msg = message; +#endif + return (OS_R_TMO); +} + + +/*--------------------------- rt_mbx_check ----------------------------------*/ + +OS_RESULT rt_mbx_check (OS_ID mailbox) { + /* Check for free space in a mailbox. Returns the number of messages */ + /* that can be stored to a mailbox. It returns 0 when mailbox is full. */ + P_MCB p_MCB = mailbox; + + return (p_MCB->size - p_MCB->count); +} + + +/*--------------------------- isr_mbx_send ----------------------------------*/ + +void isr_mbx_send (OS_ID mailbox, void *p_msg) { + /* Same function as "os_mbx_send", but to be called by ISRs. */ + P_MCB p_MCB = mailbox; + + rt_psq_enq (p_MCB, (U32)p_msg); + rt_psh_req (); +} + + +/*--------------------------- isr_mbx_receive -------------------------------*/ + +OS_RESULT isr_mbx_receive (OS_ID mailbox, void **message) { + /* Receive a message in the interrupt function. The interrupt function */ + /* should not wait for a message since this would block the rtx os. */ + P_MCB p_MCB = mailbox; + + if (p_MCB->count) { + /* A message is available in the fifo buffer. */ + *message = p_MCB->msg[p_MCB->last]; + if (p_MCB->state == 2) { + /* A task is locked waiting to send message */ + rt_psq_enq (p_MCB, 0); + rt_psh_req (); + } + rt_dec (&p_MCB->count); + if (++p_MCB->last == p_MCB->size) { + p_MCB->last = 0; + } + return (OS_R_MBX); + } + return (OS_R_OK); +} + + +/*--------------------------- rt_mbx_psh ------------------------------------*/ + +void rt_mbx_psh (P_MCB p_CB, void *p_msg) { + /* Store the message to the mailbox queue or pass it to task directly. */ + P_TCB p_TCB; + void *mem; + + if (p_CB->p_lnk != NULL) switch (p_CB->state) { +#ifdef __CMSIS_RTOS + case 3: + /* Task is waiting to allocate memory, remove it from the waiting list */ + mem = rt_alloc_box(p_msg); + if (mem == NULL) break; + p_TCB = rt_get_first ((P_XCB)p_CB); + rt_ret_val(p_TCB, (U32)mem); + p_TCB->state = READY; + rt_rmv_dly (p_TCB); + rt_put_prio (&os_rdy, p_TCB); + break; +#endif + case 2: + /* Task is waiting to send a message, remove it from the waiting list */ + p_TCB = rt_get_first ((P_XCB)p_CB); +#ifdef __CMSIS_RTOS + rt_ret_val(p_TCB, 0/*osOK*/); +#else + rt_ret_val(p_TCB, OS_R_OK); +#endif + p_CB->msg[p_CB->first] = p_TCB->msg; + rt_inc (&p_CB->count); + if (++p_CB->first == p_CB->size) { + p_CB->first = 0; + } + p_TCB->state = READY; + rt_rmv_dly (p_TCB); + rt_put_prio (&os_rdy, p_TCB); + break; + case 1: + /* Task is waiting for a message, pass the message to the task directly */ + p_TCB = rt_get_first ((P_XCB)p_CB); +#ifdef __CMSIS_RTOS + rt_ret_val2(p_TCB, 0x10/*osEventMessage*/, (U32)p_msg); +#else + *p_TCB->msg = p_msg; + rt_ret_val (p_TCB, OS_R_MBX); +#endif + p_TCB->state = READY; + rt_rmv_dly (p_TCB); + rt_put_prio (&os_rdy, p_TCB); + break; + } else { + /* No task is waiting for a message, store it to the mailbox queue */ + if (p_CB->count < p_CB->size) { + p_CB->msg[p_CB->first] = p_msg; + rt_inc (&p_CB->count); + if (++p_CB->first == p_CB->size) { + p_CB->first = 0; + } + } + else { + os_error (OS_ERR_MBX_OVF); + } + } +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/rt_Mailbox.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,48 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MAILBOX.H + * Purpose: Implements waits and wake-ups for mailbox messages + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +/* Functions */ +extern void rt_mbx_init (OS_ID mailbox, U16 mbx_size); +extern OS_RESULT rt_mbx_send (OS_ID mailbox, void *p_msg, U16 timeout); +extern OS_RESULT rt_mbx_wait (OS_ID mailbox, void **message, U16 timeout); +extern OS_RESULT rt_mbx_check (OS_ID mailbox); +extern void isr_mbx_send (OS_ID mailbox, void *p_msg); +extern OS_RESULT isr_mbx_receive (OS_ID mailbox, void **message); +extern void rt_mbx_psh (P_MCB p_CB, void *p_msg); + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/rt_MemBox.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,166 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MEMBOX.C + * Purpose: Interface functions for fixed memory block management system + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_System.h" +#include "rt_MemBox.h" +#include "rt_HAL_CM.h" + +/*---------------------------------------------------------------------------- + * Global Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- _init_box -------------------------------------*/ + +int _init_box (void *box_mem, U32 box_size, U32 blk_size) { + /* Initialize memory block system, returns 0 if OK, 1 if fails. */ + void *end; + void *blk; + void *next; + U32 sizeof_bm; + + /* Create memory structure. */ + if (blk_size & BOX_ALIGN_8) { + /* Memory blocks 8-byte aligned. */ + blk_size = ((blk_size & ~BOX_ALIGN_8) + 7) & ~7; + sizeof_bm = (sizeof (struct OS_BM) + 7) & ~7; + } + else { + /* Memory blocks 4-byte aligned. */ + blk_size = (blk_size + 3) & ~3; + sizeof_bm = sizeof (struct OS_BM); + } + if (blk_size == 0) { + return (1); + } + if ((blk_size + sizeof_bm) > box_size) { + return (1); + } + /* Create a Memory structure. */ + blk = ((U8 *) box_mem) + sizeof_bm; + ((P_BM) box_mem)->free = blk; + end = ((U8 *) box_mem) + box_size; + ((P_BM) box_mem)->end = end; + ((P_BM) box_mem)->blk_size = blk_size; + + /* Link all free blocks using offsets. */ + end = ((U8 *) end) - blk_size; + while (1) { + next = ((U8 *) blk) + blk_size; + if (next > end) break; + *((void **)blk) = next; + blk = next; + } + /* end marker */ + *((void **)blk) = 0; + return (0); +} + +/*--------------------------- rt_alloc_box ----------------------------------*/ + +void *rt_alloc_box (void *box_mem) { + /* Allocate a memory block and return start address. */ + void **free; +#ifndef __USE_EXCLUSIVE_ACCESS + int irq_dis; + + irq_dis = __disable_irq (); + free = ((P_BM) box_mem)->free; + if (free) { + ((P_BM) box_mem)->free = *free; + } + if (!irq_dis) __enable_irq (); +#else + do { + if ((free = (void **)__ldrex(&((P_BM) box_mem)->free)) == 0) { + __clrex(); + break; + } + } while (__strex((U32)*free, &((P_BM) box_mem)->free)); +#endif + return (free); +} + + +/*--------------------------- _calloc_box -----------------------------------*/ + +void *_calloc_box (void *box_mem) { + /* Allocate a 0-initialized memory block and return start address. */ + void *free; + U32 *p; + U32 i; + + free = _alloc_box (box_mem); + if (free) { + p = free; + for (i = ((P_BM) box_mem)->blk_size; i; i -= 4) { + *p = 0; + p++; + } + } + return (free); +} + + +/*--------------------------- rt_free_box -----------------------------------*/ + +int rt_free_box (void *box_mem, void *box) { + /* Free a memory block, returns 0 if OK, 1 if box does not belong to box_mem */ +#ifndef __USE_EXCLUSIVE_ACCESS + int irq_dis; +#endif + + if (box < box_mem || box >= ((P_BM) box_mem)->end) { + return (1); + } + +#ifndef __USE_EXCLUSIVE_ACCESS + irq_dis = __disable_irq (); + *((void **)box) = ((P_BM) box_mem)->free; + ((P_BM) box_mem)->free = box; + if (!irq_dis) __enable_irq (); +#else + do { + *((void **)box) = (void *)__ldrex(&((P_BM) box_mem)->free); + } while (__strex ((U32)box, &((P_BM) box_mem)->free)); +#endif + return (0); +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/rt_MemBox.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,46 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MEMBOX.H + * Purpose: Interface functions for fixed memory block management system + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +/* Functions */ +#define rt_init_box _init_box +#define rt_calloc_box _calloc_box +extern int _init_box (void *box_mem, U32 box_size, U32 blk_size); +extern void *rt_alloc_box (void *box_mem); +extern void * _calloc_box (void *box_mem); +extern int rt_free_box (void *box_mem, void *box); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/rt_Mutex.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,197 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MUTEX.C + * Purpose: Implements mutex synchronization objects + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_List.h" +#include "rt_Task.h" +#include "rt_Mutex.h" +#include "rt_HAL_CM.h" + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_mut_init -----------------------------------*/ + +void rt_mut_init (OS_ID mutex) { + /* Initialize a mutex object */ + P_MUCB p_MCB = mutex; + + p_MCB->cb_type = MUCB; + p_MCB->prio = 0; + p_MCB->level = 0; + p_MCB->p_lnk = NULL; + p_MCB->owner = NULL; +} + + +/*--------------------------- rt_mut_delete ---------------------------------*/ + +#ifdef __CMSIS_RTOS +OS_RESULT rt_mut_delete (OS_ID mutex) { + /* Delete a mutex object */ + P_MUCB p_MCB = mutex; + P_TCB p_TCB; + + /* Restore owner task's priority. */ + if (p_MCB->level != 0) { + p_MCB->owner->prio = p_MCB->prio; + if (p_MCB->owner != os_tsk.run) { + rt_resort_prio (p_MCB->owner); + } + } + + while (p_MCB->p_lnk != NULL) { + /* A task is waiting for mutex. */ + p_TCB = rt_get_first ((P_XCB)p_MCB); + rt_ret_val(p_TCB, 0/*osOK*/); + rt_rmv_dly(p_TCB); + p_TCB->state = READY; + rt_put_prio (&os_rdy, p_TCB); + } + + if (os_rdy.p_lnk && (os_rdy.p_lnk->prio > os_tsk.run->prio)) { + /* preempt running task */ + rt_put_prio (&os_rdy, os_tsk.run); + os_tsk.run->state = READY; + rt_dispatch (NULL); + } + + p_MCB->cb_type = 0; + + return (OS_R_OK); +} +#endif + + +/*--------------------------- rt_mut_release --------------------------------*/ + +OS_RESULT rt_mut_release (OS_ID mutex) { + /* Release a mutex object */ + P_MUCB p_MCB = mutex; + P_TCB p_TCB; + + if (p_MCB->level == 0 || p_MCB->owner != os_tsk.run) { + /* Unbalanced mutex release or task is not the owner */ + return (OS_R_NOK); + } + if (--p_MCB->level != 0) { + return (OS_R_OK); + } + /* Restore owner task's priority. */ + os_tsk.run->prio = p_MCB->prio; + if (p_MCB->p_lnk != NULL) { + /* A task is waiting for mutex. */ + p_TCB = rt_get_first ((P_XCB)p_MCB); +#ifdef __CMSIS_RTOS + rt_ret_val(p_TCB, 0/*osOK*/); +#else + rt_ret_val(p_TCB, OS_R_MUT); +#endif + rt_rmv_dly (p_TCB); + /* A waiting task becomes the owner of this mutex. */ + p_MCB->level = 1; + p_MCB->owner = p_TCB; + p_MCB->prio = p_TCB->prio; + /* Priority inversion, check which task continues. */ + if (os_tsk.run->prio >= rt_rdy_prio()) { + rt_dispatch (p_TCB); + } + else { + /* Ready task has higher priority than running task. */ + rt_put_prio (&os_rdy, os_tsk.run); + rt_put_prio (&os_rdy, p_TCB); + os_tsk.run->state = READY; + p_TCB->state = READY; + rt_dispatch (NULL); + } + } + else { + /* Check if own priority raised by priority inversion. */ + if (rt_rdy_prio() > os_tsk.run->prio) { + rt_put_prio (&os_rdy, os_tsk.run); + os_tsk.run->state = READY; + rt_dispatch (NULL); + } + } + return (OS_R_OK); +} + + +/*--------------------------- rt_mut_wait -----------------------------------*/ + +OS_RESULT rt_mut_wait (OS_ID mutex, U16 timeout) { + /* Wait for a mutex, continue when mutex is free. */ + P_MUCB p_MCB = mutex; + + if (p_MCB->level == 0) { + p_MCB->owner = os_tsk.run; + p_MCB->prio = os_tsk.run->prio; + goto inc; + } + if (p_MCB->owner == os_tsk.run) { + /* OK, running task is the owner of this mutex. */ +inc:p_MCB->level++; + return (OS_R_OK); + } + /* Mutex owned by another task, wait until released. */ + if (timeout == 0) { + return (OS_R_TMO); + } + /* Raise the owner task priority if lower than current priority. */ + /* This priority inversion is called priority inheritance. */ + if (p_MCB->prio < os_tsk.run->prio) { + p_MCB->owner->prio = os_tsk.run->prio; + rt_resort_prio (p_MCB->owner); + } + if (p_MCB->p_lnk != NULL) { + rt_put_prio ((P_XCB)p_MCB, os_tsk.run); + } + else { + p_MCB->p_lnk = os_tsk.run; + os_tsk.run->p_lnk = NULL; + os_tsk.run->p_rlnk = (P_TCB)p_MCB; + } + rt_block(timeout, WAIT_MUT); + return (OS_R_TMO); +} + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/rt_Mutex.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,44 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MUTEX.H + * Purpose: Implements mutex synchronization objects + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +/* Functions */ +extern void rt_mut_init (OS_ID mutex); +extern OS_RESULT rt_mut_delete (OS_ID mutex); +extern OS_RESULT rt_mut_release (OS_ID mutex); +extern OS_RESULT rt_mut_wait (OS_ID mutex, U16 timeout); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/rt_Robin.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,84 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_ROBIN.C + * Purpose: Round Robin Task switching + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_List.h" +#include "rt_Task.h" +#include "rt_Time.h" +#include "rt_Robin.h" +#include "rt_HAL_CM.h" + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +struct OS_ROBIN os_robin; + + +/*---------------------------------------------------------------------------- + * Global Functions + *---------------------------------------------------------------------------*/ + +/*--------------------------- rt_init_robin ---------------------------------*/ + +__weak void rt_init_robin (void) { + /* Initialize Round Robin variables. */ + os_robin.task = NULL; + os_robin.tout = (U16)os_rrobin; +} + +/*--------------------------- rt_chk_robin ----------------------------------*/ + +__weak void rt_chk_robin (void) { + /* Check if Round Robin timeout expired and switch to the next ready task.*/ + P_TCB p_new; + + if (os_robin.task != os_rdy.p_lnk) { + /* New task was suspended, reset Round Robin timeout. */ + os_robin.task = os_rdy.p_lnk; + os_robin.time = (U16)os_time + os_robin.tout - 1; + } + if (os_robin.time == (U16)os_time) { + /* Round Robin timeout has expired, swap Robin tasks. */ + os_robin.task = NULL; + p_new = rt_get_first (&os_rdy); + rt_put_prio ((P_XCB)&os_rdy, p_new); + } +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/rt_Robin.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,45 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_ROBIN.H + * Purpose: Round Robin Task switching definitions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +/* Variables */ +extern struct OS_ROBIN os_robin; + +/* Functions */ +extern void rt_init_robin (void); +extern void rt_chk_robin (void); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/rt_Semaphore.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,183 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_SEMAPHORE.C + * Purpose: Implements binary and counting semaphores + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_System.h" +#include "rt_List.h" +#include "rt_Task.h" +#include "rt_Semaphore.h" +#include "rt_HAL_CM.h" + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_sem_init -----------------------------------*/ + +void rt_sem_init (OS_ID semaphore, U16 token_count) { + /* Initialize a semaphore */ + P_SCB p_SCB = semaphore; + + p_SCB->cb_type = SCB; + p_SCB->p_lnk = NULL; + p_SCB->tokens = token_count; +} + + +/*--------------------------- rt_sem_delete ---------------------------------*/ + +#ifdef __CMSIS_RTOS +OS_RESULT rt_sem_delete (OS_ID semaphore) { + /* Delete semaphore */ + P_SCB p_SCB = semaphore; + P_TCB p_TCB; + + while (p_SCB->p_lnk != NULL) { + /* A task is waiting for token */ + p_TCB = rt_get_first ((P_XCB)p_SCB); + rt_ret_val(p_TCB, 0); + rt_rmv_dly(p_TCB); + p_TCB->state = READY; + rt_put_prio (&os_rdy, p_TCB); + } + + if (os_rdy.p_lnk && (os_rdy.p_lnk->prio > os_tsk.run->prio)) { + /* preempt running task */ + rt_put_prio (&os_rdy, os_tsk.run); + os_tsk.run->state = READY; + rt_dispatch (NULL); + } + + p_SCB->cb_type = 0; + + return (OS_R_OK); +} +#endif + + +/*--------------------------- rt_sem_send -----------------------------------*/ + +OS_RESULT rt_sem_send (OS_ID semaphore) { + /* Return a token to semaphore */ + P_SCB p_SCB = semaphore; + P_TCB p_TCB; + + if (p_SCB->p_lnk != NULL) { + /* A task is waiting for token */ + p_TCB = rt_get_first ((P_XCB)p_SCB); +#ifdef __CMSIS_RTOS + rt_ret_val(p_TCB, 1); +#else + rt_ret_val(p_TCB, OS_R_SEM); +#endif + rt_rmv_dly (p_TCB); + rt_dispatch (p_TCB); + } + else { + /* Store token. */ + p_SCB->tokens++; + } + return (OS_R_OK); +} + + +/*--------------------------- rt_sem_wait -----------------------------------*/ + +OS_RESULT rt_sem_wait (OS_ID semaphore, U16 timeout) { + /* Obtain a token; possibly wait for it */ + P_SCB p_SCB = semaphore; + + if (p_SCB->tokens) { + p_SCB->tokens--; + return (OS_R_OK); + } + /* No token available: wait for one */ + if (timeout == 0) { + return (OS_R_TMO); + } + if (p_SCB->p_lnk != NULL) { + rt_put_prio ((P_XCB)p_SCB, os_tsk.run); + } + else { + p_SCB->p_lnk = os_tsk.run; + os_tsk.run->p_lnk = NULL; + os_tsk.run->p_rlnk = (P_TCB)p_SCB; + } + rt_block(timeout, WAIT_SEM); + return (OS_R_TMO); +} + + +/*--------------------------- isr_sem_send ----------------------------------*/ + +void isr_sem_send (OS_ID semaphore) { + /* Same function as "os_sem"send", but to be called by ISRs */ + P_SCB p_SCB = semaphore; + + rt_psq_enq (p_SCB, 0); + rt_psh_req (); +} + + +/*--------------------------- rt_sem_psh ------------------------------------*/ + +void rt_sem_psh (P_SCB p_CB) { + /* Check if task has to be waken up */ + P_TCB p_TCB; + + if (p_CB->p_lnk != NULL) { + /* A task is waiting for token */ + p_TCB = rt_get_first ((P_XCB)p_CB); + rt_rmv_dly (p_TCB); + p_TCB->state = READY; +#ifdef __CMSIS_RTOS + rt_ret_val(p_TCB, 1); +#else + rt_ret_val(p_TCB, OS_R_SEM); +#endif + rt_put_prio (&os_rdy, p_TCB); + } + else { + /* Store token */ + p_CB->tokens++; + } +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/rt_Semaphore.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,46 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_SEMAPHORE.H + * Purpose: Implements binary and counting semaphores + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +/* Functions */ +extern void rt_sem_init (OS_ID semaphore, U16 token_count); +extern OS_RESULT rt_sem_delete(OS_ID semaphore); +extern OS_RESULT rt_sem_send (OS_ID semaphore); +extern OS_RESULT rt_sem_wait (OS_ID semaphore, U16 timeout); +extern void isr_sem_send (OS_ID semaphore); +extern void rt_sem_psh (P_SCB p_CB); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/rt_System.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,299 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_SYSTEM.C + * Purpose: System Task Manager + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_Task.h" +#include "rt_System.h" +#include "rt_Event.h" +#include "rt_List.h" +#include "rt_Mailbox.h" +#include "rt_Semaphore.h" +#include "rt_Time.h" +#include "rt_Robin.h" +#include "rt_HAL_CM.h" + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +int os_tick_irqn; + +/*---------------------------------------------------------------------------- + * Local Variables + *---------------------------------------------------------------------------*/ + +static volatile BIT os_lock; +static volatile BIT os_psh_flag; +static U8 pend_flags; + +/*---------------------------------------------------------------------------- + * Global Functions + *---------------------------------------------------------------------------*/ + +#if defined (__CC_ARM) +__asm void $$RTX$$version (void) { + /* Export a version number symbol for a version control. */ + + EXPORT __RL_RTX_VER + +__RL_RTX_VER EQU 0x450 +} +#endif + + +/*--------------------------- rt_suspend ------------------------------------*/ +U32 rt_suspend (void) { + /* Suspend OS scheduler */ + U32 delta = 0xFFFF; + + rt_tsk_lock(); + + if (os_dly.p_dlnk) { + delta = os_dly.delta_time; + } +#ifndef __CMSIS_RTOS + if (os_tmr.next) { + if (os_tmr.tcnt < delta) delta = os_tmr.tcnt; + } +#endif + + return (delta); +} + + +/*--------------------------- rt_resume -------------------------------------*/ +void rt_resume (U32 sleep_time) { + /* Resume OS scheduler after suspend */ + P_TCB next; + U32 delta; + + os_tsk.run->state = READY; + rt_put_rdy_first (os_tsk.run); + + os_robin.task = NULL; + + /* Update delays. */ + if (os_dly.p_dlnk) { + delta = sleep_time; + if (delta >= os_dly.delta_time) { + delta -= os_dly.delta_time; + os_time += os_dly.delta_time; + os_dly.delta_time = 1; + while (os_dly.p_dlnk) { + rt_dec_dly(); + if (delta == 0) break; + delta--; + os_time++; + } + } else { + os_time += delta; + os_dly.delta_time -= delta; + } + } else { + os_time += sleep_time; + } + +#ifndef __CMSIS_RTOS + /* Check the user timers. */ + if (os_tmr.next) { + delta = sleep_time; + if (delta >= os_tmr.tcnt) { + delta -= os_tmr.tcnt; + os_tmr.tcnt = 1; + while (os_tmr.next) { + rt_tmr_tick(); + if (delta == 0) break; + delta--; + } + } else { + os_tmr.tcnt -= delta; + } + } +#endif + + /* Switch back to highest ready task */ + next = rt_get_first (&os_rdy); + rt_switch_req (next); + + rt_tsk_unlock(); +} + + +/*--------------------------- rt_tsk_lock -----------------------------------*/ + +void rt_tsk_lock (void) { + /* Prevent task switching by locking out scheduler */ + if (os_tick_irqn < 0) { + OS_LOCK(); + os_lock = __TRUE; + OS_UNPEND (&pend_flags); + } else { + OS_X_LOCK(os_tick_irqn); + os_lock = __TRUE; + OS_X_UNPEND (&pend_flags); + } +} + + +/*--------------------------- rt_tsk_unlock ---------------------------------*/ + +void rt_tsk_unlock (void) { + /* Unlock scheduler and re-enable task switching */ + if (os_tick_irqn < 0) { + OS_UNLOCK(); + os_lock = __FALSE; + OS_PEND (pend_flags, os_psh_flag); + os_psh_flag = __FALSE; + } else { + OS_X_UNLOCK(os_tick_irqn); + os_lock = __FALSE; + OS_X_PEND (pend_flags, os_psh_flag); + os_psh_flag = __FALSE; + } +} + + +/*--------------------------- rt_psh_req ------------------------------------*/ + +void rt_psh_req (void) { + /* Initiate a post service handling request if required. */ + if (os_lock == __FALSE) { + OS_PEND_IRQ (); + } + else { + os_psh_flag = __TRUE; + } +} + + +/*--------------------------- rt_pop_req ------------------------------------*/ + +void rt_pop_req (void) { + /* Process an ISR post service requests. */ + struct OS_XCB *p_CB; + P_TCB next; + U32 idx; + + os_tsk.run->state = READY; + rt_put_rdy_first (os_tsk.run); + + idx = os_psq->last; + while (os_psq->count) { + p_CB = os_psq->q[idx].id; + if (p_CB->cb_type == TCB) { + /* Is of TCB type */ + rt_evt_psh ((P_TCB)p_CB, (U16)os_psq->q[idx].arg); + } + else if (p_CB->cb_type == MCB) { + /* Is of MCB type */ + rt_mbx_psh ((P_MCB)p_CB, (void *)os_psq->q[idx].arg); + } + else { + /* Must be of SCB type */ + rt_sem_psh ((P_SCB)p_CB); + } + if (++idx == os_psq->size) idx = 0; + rt_dec (&os_psq->count); + } + os_psq->last = idx; + + next = rt_get_first (&os_rdy); + rt_switch_req (next); +} + + +/*--------------------------- os_tick_init ----------------------------------*/ + +__weak int os_tick_init (void) { + /* Initialize SysTick timer as system tick timer. */ + rt_systick_init (); + return (-1); /* Return IRQ number of SysTick timer */ +} + + +/*--------------------------- os_tick_irqack --------------------------------*/ + +__weak void os_tick_irqack (void) { + /* Acknowledge timer interrupt. */ +} + + +/*--------------------------- rt_systick ------------------------------------*/ + +extern void sysTimerTick(void); + +void rt_systick (void) { + /* Check for system clock update, suspend running task. */ + P_TCB next; + + os_tsk.run->state = READY; + rt_put_rdy_first (os_tsk.run); + + /* Check Round Robin timeout. */ + rt_chk_robin (); + + /* Update delays. */ + os_time++; + rt_dec_dly (); + + /* Check the user timers. */ +#ifdef __CMSIS_RTOS + sysTimerTick(); +#else + rt_tmr_tick (); +#endif + + /* Switch back to highest ready task */ + next = rt_get_first (&os_rdy); + rt_switch_req (next); +} + +/*--------------------------- rt_stk_check ----------------------------------*/ +__weak void rt_stk_check (void) { + /* Check for stack overflow. */ + if (os_tsk.run->task_id == 0x01) { + // TODO: For the main thread the check should be done against the main heap pointer + } else { + if ((os_tsk.run->tsk_stack < (U32)os_tsk.run->stack) || + (os_tsk.run->stack[0] != MAGIC_WORD)) { + os_error (OS_ERR_STK_OVF); + } + } +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/rt_System.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,52 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_SYSTEM.H + * Purpose: System Task Manager definitions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +/* Variables */ +#define os_psq ((P_PSQ)&os_fifo) +extern int os_tick_irqn; + +/* Functions */ +extern U32 rt_suspend (void); +extern void rt_resume (U32 sleep_time); +extern void rt_tsk_lock (void); +extern void rt_tsk_unlock (void); +extern void rt_psh_req (void); +extern void rt_pop_req (void); +extern void rt_systick (void); +extern void rt_stk_check (void); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/rt_Task.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,339 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_TASK.C + * Purpose: Task functions and system start up. + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_System.h" +#include "rt_Task.h" +#include "rt_List.h" +#include "rt_MemBox.h" +#include "rt_Robin.h" +#include "rt_HAL_CM.h" + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +/* Running and next task info. */ +struct OS_TSK os_tsk; + +/* Task Control Blocks of idle demon */ +struct OS_TCB os_idle_TCB; + + +/*---------------------------------------------------------------------------- + * Local Functions + *---------------------------------------------------------------------------*/ + +OS_TID rt_get_TID (void) { + U32 tid; + + for (tid = 1; tid <= os_maxtaskrun; tid++) { + if (os_active_TCB[tid-1] == NULL) { + return ((OS_TID)tid); + } + } + return (0); +} + +#if defined (__CC_ARM) && !defined (__MICROLIB) +/*--------------------------- __user_perthread_libspace ---------------------*/ +extern void *__libspace_start; + +void *__user_perthread_libspace (void) { + /* Provide a separate libspace for each task. */ + if (os_tsk.run == NULL) { + /* RTX not running yet. */ + return (&__libspace_start); + } + return (void *)(os_tsk.run->std_libspace); +} +#endif + +/*--------------------------- rt_init_context -------------------------------*/ + +void rt_init_context (P_TCB p_TCB, U8 priority, FUNCP task_body) { + /* Initialize general part of the Task Control Block. */ + p_TCB->cb_type = TCB; + p_TCB->state = READY; + p_TCB->prio = priority; + p_TCB->p_lnk = NULL; + p_TCB->p_rlnk = NULL; + p_TCB->p_dlnk = NULL; + p_TCB->p_blnk = NULL; + p_TCB->delta_time = 0; + p_TCB->interval_time = 0; + p_TCB->events = 0; + p_TCB->waits = 0; + p_TCB->stack_frame = 0; + + rt_init_stack (p_TCB, task_body); +} + + +/*--------------------------- rt_switch_req ---------------------------------*/ + +void rt_switch_req (P_TCB p_new) { + /* Switch to next task (identified by "p_new"). */ + os_tsk.new_tsk = p_new; + p_new->state = RUNNING; + DBG_TASK_SWITCH(p_new->task_id); +} + + +/*--------------------------- rt_dispatch -----------------------------------*/ + +void rt_dispatch (P_TCB next_TCB) { + /* Dispatch next task if any identified or dispatch highest ready task */ + /* "next_TCB" identifies a task to run or has value NULL (=no next task) */ + if (next_TCB == NULL) { + /* Running task was blocked: continue with highest ready task */ + next_TCB = rt_get_first (&os_rdy); + rt_switch_req (next_TCB); + } + else { + /* Check which task continues */ + if (next_TCB->prio > os_tsk.run->prio) { + /* preempt running task */ + rt_put_rdy_first (os_tsk.run); + os_tsk.run->state = READY; + rt_switch_req (next_TCB); + } + else { + /* put next task into ready list, no task switch takes place */ + next_TCB->state = READY; + rt_put_prio (&os_rdy, next_TCB); + } + } +} + + +/*--------------------------- rt_block --------------------------------------*/ + +void rt_block (U16 timeout, U8 block_state) { + /* Block running task and choose next ready task. */ + /* "timeout" sets a time-out value or is 0xffff (=no time-out). */ + /* "block_state" defines the appropriate task state */ + P_TCB next_TCB; + + if (timeout) { + if (timeout < 0xffff) { + rt_put_dly (os_tsk.run, timeout); + } + os_tsk.run->state = block_state; + next_TCB = rt_get_first (&os_rdy); + rt_switch_req (next_TCB); + } +} + + +/*--------------------------- rt_tsk_pass -----------------------------------*/ + +void rt_tsk_pass (void) { + /* Allow tasks of same priority level to run cooperatively.*/ + P_TCB p_new; + + p_new = rt_get_same_rdy_prio(); + if (p_new != NULL) { + rt_put_prio ((P_XCB)&os_rdy, os_tsk.run); + os_tsk.run->state = READY; + rt_switch_req (p_new); + } +} + + +/*--------------------------- rt_tsk_self -----------------------------------*/ + +OS_TID rt_tsk_self (void) { + /* Return own task identifier value. */ + if (os_tsk.run == NULL) { + return (0); + } + return (os_tsk.run->task_id); +} + + +/*--------------------------- rt_tsk_prio -----------------------------------*/ + +OS_RESULT rt_tsk_prio (OS_TID task_id, U8 new_prio) { + /* Change execution priority of a task to "new_prio". */ + P_TCB p_task; + + if (task_id == 0) { + /* Change execution priority of calling task. */ + os_tsk.run->prio = new_prio; +run:if (rt_rdy_prio() > new_prio) { + rt_put_prio (&os_rdy, os_tsk.run); + os_tsk.run->state = READY; + rt_dispatch (NULL); + } + return (OS_R_OK); + } + + /* Find the task in the "os_active_TCB" array. */ + if (task_id > os_maxtaskrun || os_active_TCB[task_id-1] == NULL) { + /* Task with "task_id" not found or not started. */ + return (OS_R_NOK); + } + p_task = os_active_TCB[task_id-1]; + p_task->prio = new_prio; + if (p_task == os_tsk.run) { + goto run; + } + rt_resort_prio (p_task); + if (p_task->state == READY) { + /* Task enqueued in a ready list. */ + p_task = rt_get_first (&os_rdy); + rt_dispatch (p_task); + } + return (OS_R_OK); +} + +/*--------------------------- rt_tsk_delete ---------------------------------*/ + +OS_RESULT rt_tsk_delete (OS_TID task_id) { + /* Terminate the task identified with "task_id". */ + P_TCB task_context; + + if (task_id == 0 || task_id == os_tsk.run->task_id) { + /* Terminate itself. */ + os_tsk.run->state = INACTIVE; + os_tsk.run->tsk_stack = rt_get_PSP (); + rt_stk_check (); + os_active_TCB[os_tsk.run->task_id-1] = NULL; + + os_tsk.run->stack = NULL; + DBG_TASK_NOTIFY(os_tsk.run, __FALSE); + os_tsk.run = NULL; + rt_dispatch (NULL); + /* The program should never come to this point. */ + } + else { + /* Find the task in the "os_active_TCB" array. */ + if (task_id > os_maxtaskrun || os_active_TCB[task_id-1] == NULL) { + /* Task with "task_id" not found or not started. */ + return (OS_R_NOK); + } + task_context = os_active_TCB[task_id-1]; + rt_rmv_list (task_context); + rt_rmv_dly (task_context); + os_active_TCB[task_id-1] = NULL; + + task_context->stack = NULL; + DBG_TASK_NOTIFY(task_context, __FALSE); + } + return (OS_R_OK); +} + + +/*--------------------------- rt_sys_init -----------------------------------*/ + +#ifdef __CMSIS_RTOS +void rt_sys_init (void) { +#else +void rt_sys_init (FUNCP first_task, U32 prio_stksz, void *stk) { +#endif + /* Initialize system and start up task declared with "first_task". */ + U32 i; + + DBG_INIT(); + + /* Initialize dynamic memory and task TCB pointers to NULL. */ + for (i = 0; i < os_maxtaskrun; i++) { + os_active_TCB[i] = NULL; + } + + /* Set up TCB of idle demon */ + os_idle_TCB.task_id = 255; + os_idle_TCB.priv_stack = idle_task_stack_size; + os_idle_TCB.stack = idle_task_stack; + rt_init_context (&os_idle_TCB, 0, os_idle_demon); + + /* Set up ready list: initially empty */ + os_rdy.cb_type = HCB; + os_rdy.p_lnk = NULL; + /* Set up delay list: initially empty */ + os_dly.cb_type = HCB; + os_dly.p_dlnk = NULL; + os_dly.p_blnk = NULL; + os_dly.delta_time = 0; + + /* Fix SP and systemvariables to assume idle task is running */ + /* Transform main program into idle task by assuming idle TCB */ +#ifndef __CMSIS_RTOS + rt_set_PSP (os_idle_TCB.tsk_stack+32); +#endif + os_tsk.run = &os_idle_TCB; + os_tsk.run->state = RUNNING; + + /* Initialize ps queue */ + os_psq->first = 0; + os_psq->last = 0; + os_psq->size = os_fifo_size; + + rt_init_robin (); + + /* Intitialize SVC and PendSV */ + rt_svc_init (); + +#ifndef __CMSIS_RTOS + /* Intitialize and start system clock timer */ + os_tick_irqn = os_tick_init (); + if (os_tick_irqn >= 0) { + OS_X_INIT(os_tick_irqn); + } + + /* Start up first user task before entering the endless loop */ + rt_tsk_create (first_task, prio_stksz, stk, NULL); +#endif +} + + +/*--------------------------- rt_sys_start ----------------------------------*/ + +#ifdef __CMSIS_RTOS +void rt_sys_start (void) { + /* Start system */ + + /* Intitialize and start system clock timer */ + os_tick_irqn = os_tick_init (); + if (os_tick_irqn >= 0) { + OS_X_INIT(os_tick_irqn); + } +} +#endif + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/rt_Task.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,73 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_TASK.H + * Purpose: Task functions and system start up. + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +/* Definitions */ +#define __CMSIS_RTOS 1 + +/* Values for 'state' */ +#define INACTIVE 0 +#define READY 1 +#define RUNNING 2 +#define WAIT_DLY 3 +#define WAIT_ITV 4 +#define WAIT_OR 5 +#define WAIT_AND 6 +#define WAIT_SEM 7 +#define WAIT_MBX 8 +#define WAIT_MUT 9 + +/* Return codes */ +#define OS_R_TMO 0x01 +#define OS_R_EVT 0x02 +#define OS_R_SEM 0x03 +#define OS_R_MBX 0x04 +#define OS_R_MUT 0x05 + +#define OS_R_OK 0x00 +#define OS_R_NOK 0xff + +/* Variables */ +extern struct OS_TSK os_tsk; +extern struct OS_TCB os_idle_TCB; + +/* Functions */ +extern void rt_switch_req (P_TCB p_new); +extern void rt_dispatch (P_TCB next_TCB); +extern void rt_block (U16 timeout, U8 block_state); +extern void rt_tsk_pass (void); +extern OS_TID rt_tsk_self (void); +extern OS_RESULT rt_tsk_prio (OS_TID task_id, U8 new_prio); +extern OS_RESULT rt_tsk_delete (OS_TID task_id); +extern void rt_sys_init (void); +extern void rt_sys_start (void);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/rt_Time.c Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,94 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_TIME.C + * Purpose: Delay and interval wait functions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_Task.h" +#include "rt_Time.h" + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +/* Free running system tick counter */ +U32 os_time; + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_time_get -----------------------------------*/ + +U32 rt_time_get (void) { + /* Get system time tick */ + return (os_time); +} + + +/*--------------------------- rt_dly_wait -----------------------------------*/ + +void rt_dly_wait (U16 delay_time) { + /* Delay task by "delay_time" */ + rt_block (delay_time, WAIT_DLY); +} + + +/*--------------------------- rt_itv_set ------------------------------------*/ + +void rt_itv_set (U16 interval_time) { + /* Set interval length and define start of first interval */ + os_tsk.run->interval_time = interval_time; + os_tsk.run->delta_time = interval_time + (U16)os_time; +} + + +/*--------------------------- rt_itv_wait -----------------------------------*/ + +void rt_itv_wait (void) { + /* Wait for interval end and define start of next one */ + U16 delta; + + delta = os_tsk.run->delta_time - (U16)os_time; + os_tsk.run->delta_time += os_tsk.run->interval_time; + if ((delta & 0x8000) == 0) { + rt_block (delta, WAIT_ITV); + } +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/rt_Time.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,47 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_TIME.H + * Purpose: Delay and interval wait functions definitions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +/* Variables */ +extern U32 os_time; + +/* Functions */ +extern U32 rt_time_get (void); +extern void rt_dly_wait (U16 delay_time); +extern void rt_itv_set (U16 interval_time); +extern void rt_itv_wait (void); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtx/TARGET_CORTEX_M/rt_TypeDef.h Thu Nov 06 13:00:11 2014 +0000 @@ -0,0 +1,128 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_TYPEDEF.H + * Purpose: Type Definitions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ +#ifndef RT_TYPE_DEF_H +#define RT_TYPE_DEF_H + +#include "os_tcb.h" + +typedef U32 OS_TID; +typedef void *OS_ID; +typedef U32 OS_RESULT; + +#define TCB_STACKF 32 /* 'stack_frame' offset */ +#define TCB_TSTACK 36 /* 'tsk_stack' offset */ + +typedef struct OS_PSFE { /* Post Service Fifo Entry */ + void *id; /* Object Identification */ + U32 arg; /* Object Argument */ +} *P_PSFE; + +typedef struct OS_PSQ { /* Post Service Queue */ + U8 first; /* FIFO Head Index */ + U8 last; /* FIFO Tail Index */ + U8 count; /* Number of stored items in FIFO */ + U8 size; /* FIFO Size */ + struct OS_PSFE q[1]; /* FIFO Content */ +} *P_PSQ; + +typedef struct OS_TSK { + P_TCB run; /* Current running task */ + P_TCB new_tsk; /* Scheduled task to run */ +} *P_TSK; + +typedef struct OS_ROBIN { /* Round Robin Control */ + P_TCB task; /* Round Robin task */ + U16 time; /* Round Robin switch time */ + U16 tout; /* Round Robin timeout */ +} *P_ROBIN; + +typedef struct OS_XCB { + U8 cb_type; /* Control Block Type */ + struct OS_TCB *p_lnk; /* Link pointer for ready/sem. wait list */ + struct OS_TCB *p_rlnk; /* Link pointer for sem./mbx lst backwards */ + struct OS_TCB *p_dlnk; /* Link pointer for delay list */ + struct OS_TCB *p_blnk; /* Link pointer for delay list backwards */ + U16 delta_time; /* Time until time out */ +} *P_XCB; + +typedef struct OS_MCB { + U8 cb_type; /* Control Block Type */ + U8 state; /* State flag variable */ + U8 isr_st; /* State flag variable for isr functions */ + struct OS_TCB *p_lnk; /* Chain of tasks waiting for message */ + U16 first; /* Index of the message list begin */ + U16 last; /* Index of the message list end */ + U16 count; /* Actual number of stored messages */ + U16 size; /* Maximum number of stored messages */ + void *msg[1]; /* FIFO for Message pointers 1st element */ +} *P_MCB; + +typedef struct OS_SCB { + U8 cb_type; /* Control Block Type */ + U8 mask; /* Semaphore token mask */ + U16 tokens; /* Semaphore tokens */ + struct OS_TCB *p_lnk; /* Chain of tasks waiting for tokens */ +} *P_SCB; + +typedef struct OS_MUCB { + U8 cb_type; /* Control Block Type */ + U8 prio; /* Owner task default priority */ + U16 level; /* Call nesting level */ + struct OS_TCB *p_lnk; /* Chain of tasks waiting for mutex */ + struct OS_TCB *owner; /* Mutex owner task */ +} *P_MUCB; + +typedef struct OS_XTMR { + struct OS_TMR *next; + U16 tcnt; +} *P_XTMR; + +typedef struct OS_TMR { + struct OS_TMR *next; /* Link pointer to Next timer */ + U16 tcnt; /* Timer delay count */ + U16 info; /* User defined call info */ +} *P_TMR; + +typedef struct OS_BM { + void *free; /* Pointer to first free memory block */ + void *end; /* Pointer to memory block end */ + U32 blk_size; /* Memory block size */ +} *P_BM; + +/* Definitions */ +#define __TRUE 1 +#define __FALSE 0 +#define NULL ((void *) 0) + +#endif
--- a/rtx/TARGET_M0/TOOLCHAIN_ARM/HAL_CM0.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,301 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: HAL_CM0.C - * Purpose: Hardware Abstraction Layer for Cortex-M0 - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Conf.h" -#include "rt_System.h" -#include "rt_HAL_CM.h" -#include "rt_Task.h" -#include "rt_MemBox.h" - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_set_PSP ------------------------------------*/ - -__asm void rt_set_PSP (U32 stack) { - MSR PSP,R0 - BX LR -} - - -/*--------------------------- rt_get_PSP ------------------------------------*/ - -__asm U32 rt_get_PSP (void) { - MRS R0,PSP - BX LR -} - - -/*--------------------------- os_set_env ------------------------------------*/ - -__asm void os_set_env (void) { - /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ - MOV R0,SP ; PSP = MSP - MSR PSP,R0 - LDR R0,=__cpp(&os_flags) - LDRB R0,[R0] - LSLS R0,#31 - BNE PrivilegedE - MOVS R0,#0x03 ; Unprivileged Thread mode, use PSP - MSR CONTROL,R0 - BX LR -PrivilegedE - MOVS R0,#0x02 ; Privileged Thread mode, use PSP - MSR CONTROL,R0 - BX LR - - ALIGN -} - - -/*--------------------------- _alloc_box ------------------------------------*/ - -__asm void *_alloc_box (void *box_mem) { - /* Function wrapper for Unprivileged/Privileged mode. */ - LDR R3,=__cpp(rt_alloc_box) - MOV R12,R3 - MRS R3,IPSR - LSLS R3,#24 - BNE PrivilegedA - MRS R3,CONTROL - LSLS R3,#31 - BEQ PrivilegedA - SVC 0 - BX LR -PrivilegedA - BX R12 - - ALIGN -} - - -/*--------------------------- _free_box -------------------------------------*/ - -__asm int _free_box (void *box_mem, void *box) { - /* Function wrapper for Unprivileged/Privileged mode. */ - LDR R3,=__cpp(rt_free_box) - MOV R12,R3 - MRS R3,IPSR - LSLS R3,#24 - BNE PrivilegedF - MRS R3,CONTROL - LSLS R3,#31 - BEQ PrivilegedF - SVC 0 - BX LR -PrivilegedF - BX R12 - - ALIGN -} - - -/*-------------------------- SVC_Handler ------------------------------------*/ - -__asm void SVC_Handler (void) { - PRESERVE8 - - IMPORT SVC_Count - IMPORT SVC_Table - IMPORT rt_stk_check - - MRS R0,PSP ; Read PSP - LDR R1,[R0,#24] ; Read Saved PC from Stack - SUBS R1,R1,#2 ; Point to SVC Instruction - LDRB R1,[R1] ; Load SVC Number - CMP R1,#0 - BNE SVC_User ; User SVC Number > 0 - - MOV LR,R4 - LDMIA R0,{R0-R3,R4} ; Read R0-R3,R12 from stack - MOV R12,R4 - MOV R4,LR - BLX R12 ; Call SVC Function - - MRS R3,PSP ; Read PSP - STMIA R3!,{R0-R2} ; Store return values - - LDR R3,=__cpp(&os_tsk) - LDMIA R3!,{R1,R2} ; os_tsk.run, os_tsk.new - CMP R1,R2 - BEQ SVC_Exit ; no task switch - - SUBS R3,#8 - CMP R1,#0 ; Runtask deleted? - BEQ SVC_Next - - MRS R0,PSP ; Read PSP - SUBS R0,R0,#32 ; Adjust Start Address - STR R0,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack - STMIA R0!,{R4-R7} ; Save old context (R4-R7) - MOV R4,R8 - MOV R5,R9 - MOV R6,R10 - MOV R7,R11 - STMIA R0!,{R4-R7} ; Save old context (R8-R11) - - PUSH {R2,R3} - BL rt_stk_check ; Check for Stack overflow - POP {R2,R3} - -SVC_Next - STR R2,[R3] ; os_tsk.run = os_tsk.new - - LDR R0,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack - ADDS R0,R0,#16 ; Adjust Start Address - LDMIA R0!,{R4-R7} ; Restore new Context (R8-R11) - MOV R8,R4 - MOV R9,R5 - MOV R10,R6 - MOV R11,R7 - MSR PSP,R0 ; Write PSP - SUBS R0,R0,#32 ; Adjust Start Address - LDMIA R0!,{R4-R7} ; Restore new Context (R4-R7) - -SVC_Exit - MOVS R0,#:NOT:0xFFFFFFFD ; Set EXC_RETURN value - MVNS R0,R0 - BX R0 ; RETI to Thread Mode, use PSP - - /*------------------- User SVC ------------------------------*/ - -SVC_User - PUSH {R4,LR} ; Save Registers - LDR R2,=SVC_Count - LDR R2,[R2] - CMP R1,R2 - BHI SVC_Done ; Overflow - - LDR R4,=SVC_Table-4 - LSLS R1,R1,#2 - LDR R4,[R4,R1] ; Load SVC Function Address - MOV LR,R4 - - LDMIA R0,{R0-R3,R4} ; Read R0-R3,R12 from stack - MOV R12,R4 - BLX LR ; Call SVC Function - - MRS R4,PSP ; Read PSP - STMIA R4!,{R0-R3} ; Function return values -SVC_Done - POP {R4,PC} ; RETI - - ALIGN -} - - -/*-------------------------- PendSV_Handler ---------------------------------*/ - -__asm void PendSV_Handler (void) { - PRESERVE8 - - BL __cpp(rt_pop_req) - -Sys_Switch - LDR R3,=__cpp(&os_tsk) - LDMIA R3!,{R1,R2} ; os_tsk.run, os_tsk.new - CMP R1,R2 - BEQ Sys_Exit ; no task switch - - SUBS R3,#8 - - MRS R0,PSP ; Read PSP - SUBS R0,R0,#32 ; Adjust Start Address - STR R0,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack - STMIA R0!,{R4-R7} ; Save old context (R4-R7) - MOV R4,R8 - MOV R5,R9 - MOV R6,R10 - MOV R7,R11 - STMIA R0!,{R4-R7} ; Save old context (R8-R11) - - PUSH {R2,R3} - BL rt_stk_check ; Check for Stack overflow - POP {R2,R3} - - STR R2,[R3] ; os_tsk.run = os_tsk.new - - LDR R0,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack - ADDS R0,R0,#16 ; Adjust Start Address - LDMIA R0!,{R4-R7} ; Restore new Context (R8-R11) - MOV R8,R4 - MOV R9,R5 - MOV R10,R6 - MOV R11,R7 - MSR PSP,R0 ; Write PSP - SUBS R0,R0,#32 ; Adjust Start Address - LDMIA R0!,{R4-R7} ; Restore new Context (R4-R7) - -Sys_Exit - MOVS R0,#:NOT:0xFFFFFFFD ; Set EXC_RETURN value - MVNS R0,R0 - BX R0 ; RETI to Thread Mode, use PSP - - ALIGN -} - - -/*-------------------------- SysTick_Handler --------------------------------*/ - -__asm void SysTick_Handler (void) { - PRESERVE8 - - BL __cpp(rt_systick) - B Sys_Switch - - ALIGN -} - - -/*-------------------------- OS_Tick_Handler --------------------------------*/ - -__asm void OS_Tick_Handler (void) { - PRESERVE8 - - BL __cpp(os_tick_irqack) - BL __cpp(rt_systick) - B Sys_Switch - - ALIGN -} - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx/TARGET_M0/TOOLCHAIN_ARM/SVC_Table.s Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -;/*---------------------------------------------------------------------------- -; * RL-ARM - RTX -; *---------------------------------------------------------------------------- -; * Name: SVC_TABLE.S -; * Purpose: Pre-defined SVC Table for Cortex-M -; * Rev.: V4.60 -; *---------------------------------------------------------------------------- -; * -; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH -; * All rights reserved. -; * Redistribution and use in source and binary forms, with or without -; * modification, are permitted provided that the following conditions are met: -; * - Redistributions of source code must retain the above copyright -; * notice, this list of conditions and the following disclaimer. -; * - Redistributions in binary form must reproduce the above copyright -; * notice, this list of conditions and the following disclaimer in the -; * documentation and/or other materials provided with the distribution. -; * - Neither the name of ARM nor the names of its contributors may be used -; * to endorse or promote products derived from this software without -; * specific prior written permission. -; * -; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE -; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -; * POSSIBILITY OF SUCH DAMAGE. -; *---------------------------------------------------------------------------*/ - - - AREA SVC_TABLE, CODE, READONLY - - EXPORT SVC_Count - -SVC_Cnt EQU (SVC_End-SVC_Table)/4 -SVC_Count DCD SVC_Cnt - -; Import user SVC functions here. -; IMPORT __SVC_1 - - EXPORT SVC_Table -SVC_Table -; Insert user SVC functions here. SVC 0 used by RTL Kernel. -; DCD __SVC_1 ; user SVC function - -SVC_End - - END - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/rtx/TARGET_M0/TOOLCHAIN_GCC/HAL_CM0.s Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,370 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: HAL_CM0.S - * Purpose: Hardware Abstraction Layer for Cortex-M0 - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - - .file "HAL_CM0.S" - .syntax unified - - .equ TCB_TSTACK, 36 - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - .thumb - - .section ".text" - .align 2 - - -/*--------------------------- rt_set_PSP ------------------------------------*/ - -# void rt_set_PSP (U32 stack); - - .thumb_func - .type rt_set_PSP, %function - .global rt_set_PSP -rt_set_PSP: - .fnstart - .cantunwind - - MSR PSP,R0 - BX LR - - .fnend - .size rt_set_PSP, .-rt_set_PSP - - -/*--------------------------- rt_get_PSP ------------------------------------*/ - -# U32 rt_get_PSP (void); - - .thumb_func - .type rt_get_PSP, %function - .global rt_get_PSP -rt_get_PSP: - .fnstart - .cantunwind - - MRS R0,PSP - BX LR - - .fnend - .size rt_get_PSP, .-rt_get_PSP - - -/*--------------------------- os_set_env ------------------------------------*/ - -# void os_set_env (void); - /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ - - .thumb_func - .type os_set_env, %function - .global os_set_env -os_set_env: - .fnstart - .cantunwind - - MOV R0,SP /* PSP = MSP */ - MSR PSP,R0 - LDR R0,=os_flags - LDRB R0,[R0] - LSLS R0,#31 - BNE PrivilegedE - MOVS R0,#0x03 /* Unprivileged Thread mode, use PSP */ - MSR CONTROL,R0 - BX LR -PrivilegedE: - MOVS R0,#0x02 /* Privileged Thread mode, use PSP */ - MSR CONTROL,R0 - BX LR - - .fnend - .size os_set_env, .-os_set_env - - -/*--------------------------- _alloc_box ------------------------------------*/ - -# void *_alloc_box (void *box_mem); - /* Function wrapper for Unprivileged/Privileged mode. */ - - .thumb_func - .type _alloc_box, %function - .global _alloc_box -_alloc_box: - .fnstart - .cantunwind - - LDR R3,=rt_alloc_box - MOV R12,R3 - MRS R3,IPSR - LSLS R3,#24 - BNE PrivilegedA - MRS R3,CONTROL - LSLS R3,#31 - BEQ PrivilegedA - SVC 0 - BX LR -PrivilegedA: - BX R12 - - .fnend - .size _alloc_box, .-_alloc_box - - -/*--------------------------- _free_box -------------------------------------*/ - -# int _free_box (void *box_mem, void *box); - /* Function wrapper for Unprivileged/Privileged mode. */ - - .thumb_func - .type _free_box, %function - .global _free_box -_free_box: - .fnstart - .cantunwind - - LDR R3,=rt_free_box - MOV R12,R3 - MRS R3,IPSR - LSLS R3,#24 - BNE PrivilegedF - MRS R3,CONTROL - LSLS R3,#31 - BEQ PrivilegedF - SVC 0 - BX LR -PrivilegedF: - BX R12 - - .fnend - .size _free_box, .-_free_box - - -/*-------------------------- SVC_Handler ------------------------------------*/ - -# void SVC_Handler (void); - - .thumb_func - .type SVC_Handler, %function - .global SVC_Handler -SVC_Handler: - .fnstart - .cantunwind - - MRS R0,PSP /* Read PSP */ - LDR R1,[R0,#24] /* Read Saved PC from Stack */ - SUBS R1,R1,#2 /* Point to SVC Instruction */ - LDRB R1,[R1] /* Load SVC Number */ - CMP R1,#0 - BNE SVC_User /* User SVC Number > 0 */ - - MOV LR,R4 - LDMIA R0,{R0-R3,R4} /* Read R0-R3,R12 from stack */ - MOV R12,R4 - MOV R4,LR - BLX R12 /* Call SVC Function */ - - MRS R3,PSP /* Read PSP */ - STMIA R3!,{R0-R2} /* Store return values */ - - LDR R3,=os_tsk - LDMIA R3!,{R1,R2} /* os_tsk.run, os_tsk.new */ - CMP R1,R2 - BEQ SVC_Exit /* no task switch */ - - SUBS R3,#8 - CMP R1,#0 /* Runtask deleted? */ - BEQ SVC_Next - - MRS R0,PSP /* Read PSP */ - SUBS R0,R0,#32 /* Adjust Start Address */ - STR R0,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ - STMIA R0!,{R4-R7} /* Save old context (R4-R7) */ - MOV R4,R8 - MOV R5,R9 - MOV R6,R10 - MOV R7,R11 - STMIA R0!,{R4-R7} /* Save old context (R8-R11) */ - - PUSH {R2,R3} - BL rt_stk_check /* Check for Stack overflow */ - POP {R2,R3} - -SVC_Next: - STR R2,[R3] /* os_tsk.run = os_tsk.new */ - - LDR R0,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ - ADDS R0,R0,#16 /* Adjust Start Address */ - LDMIA R0!,{R4-R7} /* Restore new Context (R8-R11) */ - MOV R8,R4 - MOV R9,R5 - MOV R10,R6 - MOV R11,R7 - MSR PSP,R0 /* Write PSP */ - SUBS R0,R0,#32 /* Adjust Start Address */ - LDMIA R0!,{R4-R7} /* Restore new Context (R4-R7) */ - -SVC_Exit: - MOVS R0,#~0xFFFFFFFD /* Set EXC_RETURN value */ - MVNS R0,R0 - BX R0 /* RETI to Thread Mode, use PSP */ - - /*------------------- User SVC ------------------------------*/ - -SVC_User: - PUSH {R4,LR} /* Save Registers */ - LDR R2,=SVC_Count - LDR R2,[R2] - CMP R1,R2 - BHI SVC_Done /* Overflow */ - - LDR R4,=SVC_Table-4 - LSLS R1,R1,#2 - LDR R4,[R4,R1] /* Load SVC Function Address */ - MOV LR,R4 - - LDMIA R0,{R0-R3,R4} /* Read R0-R3,R12 from stack */ - MOV R12,R4 - BLX LR /* Call SVC Function */ - - MRS R4,PSP /* Read PSP */ - STMIA R4!,{R0-R3} /* Function return values */ -SVC_Done: - POP {R4,PC} /* RETI */ - - .fnend - .size SVC_Handler, .-SVC_Handler - - -/*-------------------------- PendSV_Handler ---------------------------------*/ - -# void PendSV_Handler (void); - - .thumb_func - .type PendSV_Handler, %function - .global PendSV_Handler - .global Sys_Switch -PendSV_Handler: - .fnstart - .cantunwind - - BL rt_pop_req - -Sys_Switch: - LDR R3,=os_tsk - LDMIA R3!,{R1,R2} /* os_tsk.run, os_tsk.new */ - CMP R1,R2 - BEQ Sys_Exit /* no task switch */ - - SUBS R3,#8 - - MRS R0,PSP /* Read PSP */ - SUBS R0,R0,#32 /* Adjust Start Address */ - STR R0,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ - STMIA R0!,{R4-R7} /* Save old context (R4-R7) */ - MOV R4,R8 - MOV R5,R9 - MOV R6,R10 - MOV R7,R11 - STMIA R0!,{R4-R7} /* Save old context (R8-R11) */ - - PUSH {R2,R3} - BL rt_stk_check /* Check for Stack overflow */ - POP {R2,R3} - - STR R2,[R3] /* os_tsk.run = os_tsk.new */ - - LDR R0,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ - ADDS R0,R0,#16 /* Adjust Start Address */ - LDMIA R0!,{R4-R7} /* Restore new Context (R8-R11) */ - MOV R8,R4 - MOV R9,R5 - MOV R10,R6 - MOV R11,R7 - MSR PSP,R0 /* Write PSP */ - SUBS R0,R0,#32 /* Adjust Start Address */ - LDMIA R0!,{R4-R7} /* Restore new Context (R4-R7) */ - -Sys_Exit: - MOVS R0,#~0xFFFFFFFD /* Set EXC_RETURN value */ - MVNS R0,R0 - BX R0 /* RETI to Thread Mode, use PSP */ - - .fnend - .size PendSV_Handler, .-PendSV_Handler - - -/*-------------------------- SysTick_Handler --------------------------------*/ - -# void SysTick_Handler (void); - - .thumb_func - .type SysTick_Handler, %function - .global SysTick_Handler -SysTick_Handler: - .fnstart - .cantunwind - - BL rt_systick - B Sys_Switch - - .fnend - .size SysTick_Handler, .-SysTick_Handler - - -/*-------------------------- OS_Tick_Handler --------------------------------*/ - -# void OS_Tick_Handler (void); - - .thumb_func - .type OS_Tick_Handler, %function - .global OS_Tick_Handler -OS_Tick_Handler: - .fnstart - .cantunwind - - BL os_tick_irqack - BL rt_systick - B Sys_Switch - - .fnend - .size OS_Tick_Handler, .-OS_Tick_Handler - - - .end - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/rtx/TARGET_M0/TOOLCHAIN_GCC/SVC_Table.s Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -;/*---------------------------------------------------------------------------- -; * RL-ARM - RTX -; *---------------------------------------------------------------------------- -; * Name: SVC_TABLE.S -; * Purpose: Pre-defined SVC Table for Cortex-M -; * Rev.: V4.60 -; *---------------------------------------------------------------------------- -; * -; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH -; * All rights reserved. -; * Redistribution and use in source and binary forms, with or without -; * modification, are permitted provided that the following conditions are met: -; * - Redistributions of source code must retain the above copyright -; * notice, this list of conditions and the following disclaimer. -; * - Redistributions in binary form must reproduce the above copyright -; * notice, this list of conditions and the following disclaimer in the -; * documentation and/or other materials provided with the distribution. -; * - Neither the name of ARM nor the names of its contributors may be used -; * to endorse or promote products derived from this software without -; * specific prior written permission. -; * -; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE -; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -; * POSSIBILITY OF SUCH DAMAGE. -; *---------------------------------------------------------------------------*/ - - - .file "SVC_Table.S" - - - .section ".svc_table" - - .global SVC_Table -SVC_Table: -/* Insert user SVC functions here. SVC 0 used by RTL Kernel. */ -# .long __SVC_1 /* user SVC function */ -SVC_End: - - .global SVC_Count -SVC_Count: - .long (SVC_End-SVC_Table)/4 - - - .end - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/rtx/TARGET_M0P/TOOLCHAIN_ARM/HAL_CM0.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,301 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: HAL_CM0.C - * Purpose: Hardware Abstraction Layer for Cortex-M0 - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Conf.h" -#include "rt_System.h" -#include "rt_HAL_CM.h" -#include "rt_Task.h" -#include "rt_MemBox.h" - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_set_PSP ------------------------------------*/ - -__asm void rt_set_PSP (U32 stack) { - MSR PSP,R0 - BX LR -} - - -/*--------------------------- rt_get_PSP ------------------------------------*/ - -__asm U32 rt_get_PSP (void) { - MRS R0,PSP - BX LR -} - - -/*--------------------------- os_set_env ------------------------------------*/ - -__asm void os_set_env (void) { - /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ - MOV R0,SP ; PSP = MSP - MSR PSP,R0 - LDR R0,=__cpp(&os_flags) - LDRB R0,[R0] - LSLS R0,#31 - BNE PrivilegedE - MOVS R0,#0x03 ; Unprivileged Thread mode, use PSP - MSR CONTROL,R0 - BX LR -PrivilegedE - MOVS R0,#0x02 ; Privileged Thread mode, use PSP - MSR CONTROL,R0 - BX LR - - ALIGN -} - - -/*--------------------------- _alloc_box ------------------------------------*/ - -__asm void *_alloc_box (void *box_mem) { - /* Function wrapper for Unprivileged/Privileged mode. */ - LDR R3,=__cpp(rt_alloc_box) - MOV R12,R3 - MRS R3,IPSR - LSLS R3,#24 - BNE PrivilegedA - MRS R3,CONTROL - LSLS R3,#31 - BEQ PrivilegedA - SVC 0 - BX LR -PrivilegedA - BX R12 - - ALIGN -} - - -/*--------------------------- _free_box -------------------------------------*/ - -__asm int _free_box (void *box_mem, void *box) { - /* Function wrapper for Unprivileged/Privileged mode. */ - LDR R3,=__cpp(rt_free_box) - MOV R12,R3 - MRS R3,IPSR - LSLS R3,#24 - BNE PrivilegedF - MRS R3,CONTROL - LSLS R3,#31 - BEQ PrivilegedF - SVC 0 - BX LR -PrivilegedF - BX R12 - - ALIGN -} - - -/*-------------------------- SVC_Handler ------------------------------------*/ - -__asm void SVC_Handler (void) { - PRESERVE8 - - IMPORT SVC_Count - IMPORT SVC_Table - IMPORT rt_stk_check - - MRS R0,PSP ; Read PSP - LDR R1,[R0,#24] ; Read Saved PC from Stack - SUBS R1,R1,#2 ; Point to SVC Instruction - LDRB R1,[R1] ; Load SVC Number - CMP R1,#0 - BNE SVC_User ; User SVC Number > 0 - - MOV LR,R4 - LDMIA R0,{R0-R3,R4} ; Read R0-R3,R12 from stack - MOV R12,R4 - MOV R4,LR - BLX R12 ; Call SVC Function - - MRS R3,PSP ; Read PSP - STMIA R3!,{R0-R2} ; Store return values - - LDR R3,=__cpp(&os_tsk) - LDMIA R3!,{R1,R2} ; os_tsk.run, os_tsk.new - CMP R1,R2 - BEQ SVC_Exit ; no task switch - - SUBS R3,#8 - CMP R1,#0 ; Runtask deleted? - BEQ SVC_Next - - MRS R0,PSP ; Read PSP - SUBS R0,R0,#32 ; Adjust Start Address - STR R0,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack - STMIA R0!,{R4-R7} ; Save old context (R4-R7) - MOV R4,R8 - MOV R5,R9 - MOV R6,R10 - MOV R7,R11 - STMIA R0!,{R4-R7} ; Save old context (R8-R11) - - PUSH {R2,R3} - BL rt_stk_check ; Check for Stack overflow - POP {R2,R3} - -SVC_Next - STR R2,[R3] ; os_tsk.run = os_tsk.new - - LDR R0,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack - ADDS R0,R0,#16 ; Adjust Start Address - LDMIA R0!,{R4-R7} ; Restore new Context (R8-R11) - MOV R8,R4 - MOV R9,R5 - MOV R10,R6 - MOV R11,R7 - MSR PSP,R0 ; Write PSP - SUBS R0,R0,#32 ; Adjust Start Address - LDMIA R0!,{R4-R7} ; Restore new Context (R4-R7) - -SVC_Exit - MOVS R0,#:NOT:0xFFFFFFFD ; Set EXC_RETURN value - MVNS R0,R0 - BX R0 ; RETI to Thread Mode, use PSP - - /*------------------- User SVC ------------------------------*/ - -SVC_User - PUSH {R4,LR} ; Save Registers - LDR R2,=SVC_Count - LDR R2,[R2] - CMP R1,R2 - BHI SVC_Done ; Overflow - - LDR R4,=SVC_Table-4 - LSLS R1,R1,#2 - LDR R4,[R4,R1] ; Load SVC Function Address - MOV LR,R4 - - LDMIA R0,{R0-R3,R4} ; Read R0-R3,R12 from stack - MOV R12,R4 - BLX LR ; Call SVC Function - - MRS R4,PSP ; Read PSP - STMIA R4!,{R0-R3} ; Function return values -SVC_Done - POP {R4,PC} ; RETI - - ALIGN -} - - -/*-------------------------- PendSV_Handler ---------------------------------*/ - -__asm void PendSV_Handler (void) { - PRESERVE8 - - BL __cpp(rt_pop_req) - -Sys_Switch - LDR R3,=__cpp(&os_tsk) - LDMIA R3!,{R1,R2} ; os_tsk.run, os_tsk.new - CMP R1,R2 - BEQ Sys_Exit ; no task switch - - SUBS R3,#8 - - MRS R0,PSP ; Read PSP - SUBS R0,R0,#32 ; Adjust Start Address - STR R0,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack - STMIA R0!,{R4-R7} ; Save old context (R4-R7) - MOV R4,R8 - MOV R5,R9 - MOV R6,R10 - MOV R7,R11 - STMIA R0!,{R4-R7} ; Save old context (R8-R11) - - PUSH {R2,R3} - BL rt_stk_check ; Check for Stack overflow - POP {R2,R3} - - STR R2,[R3] ; os_tsk.run = os_tsk.new - - LDR R0,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack - ADDS R0,R0,#16 ; Adjust Start Address - LDMIA R0!,{R4-R7} ; Restore new Context (R8-R11) - MOV R8,R4 - MOV R9,R5 - MOV R10,R6 - MOV R11,R7 - MSR PSP,R0 ; Write PSP - SUBS R0,R0,#32 ; Adjust Start Address - LDMIA R0!,{R4-R7} ; Restore new Context (R4-R7) - -Sys_Exit - MOVS R0,#:NOT:0xFFFFFFFD ; Set EXC_RETURN value - MVNS R0,R0 - BX R0 ; RETI to Thread Mode, use PSP - - ALIGN -} - - -/*-------------------------- SysTick_Handler --------------------------------*/ - -__asm void SysTick_Handler (void) { - PRESERVE8 - - BL __cpp(rt_systick) - B Sys_Switch - - ALIGN -} - - -/*-------------------------- OS_Tick_Handler --------------------------------*/ - -__asm void OS_Tick_Handler (void) { - PRESERVE8 - - BL __cpp(os_tick_irqack) - BL __cpp(rt_systick) - B Sys_Switch - - ALIGN -} - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx/TARGET_M0P/TOOLCHAIN_ARM/SVC_Table.s Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -;/*---------------------------------------------------------------------------- -; * RL-ARM - RTX -; *---------------------------------------------------------------------------- -; * Name: SVC_TABLE.S -; * Purpose: Pre-defined SVC Table for Cortex-M -; * Rev.: V4.60 -; *---------------------------------------------------------------------------- -; * -; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH -; * All rights reserved. -; * Redistribution and use in source and binary forms, with or without -; * modification, are permitted provided that the following conditions are met: -; * - Redistributions of source code must retain the above copyright -; * notice, this list of conditions and the following disclaimer. -; * - Redistributions in binary form must reproduce the above copyright -; * notice, this list of conditions and the following disclaimer in the -; * documentation and/or other materials provided with the distribution. -; * - Neither the name of ARM nor the names of its contributors may be used -; * to endorse or promote products derived from this software without -; * specific prior written permission. -; * -; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE -; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -; * POSSIBILITY OF SUCH DAMAGE. -; *---------------------------------------------------------------------------*/ - - - AREA SVC_TABLE, CODE, READONLY - - EXPORT SVC_Count - -SVC_Cnt EQU (SVC_End-SVC_Table)/4 -SVC_Count DCD SVC_Cnt - -; Import user SVC functions here. -; IMPORT __SVC_1 - - EXPORT SVC_Table -SVC_Table -; Insert user SVC functions here. SVC 0 used by RTL Kernel. -; DCD __SVC_1 ; user SVC function - -SVC_End - - END - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/rtx/TARGET_M0P/TOOLCHAIN_GCC/HAL_CM0.s Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,370 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: HAL_CM0.S - * Purpose: Hardware Abstraction Layer for Cortex-M0 - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - - .file "HAL_CM0.S" - .syntax unified - - .equ TCB_TSTACK, 36 - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - .thumb - - .section ".text" - .align 2 - - -/*--------------------------- rt_set_PSP ------------------------------------*/ - -# void rt_set_PSP (U32 stack); - - .thumb_func - .type rt_set_PSP, %function - .global rt_set_PSP -rt_set_PSP: - .fnstart - .cantunwind - - MSR PSP,R0 - BX LR - - .fnend - .size rt_set_PSP, .-rt_set_PSP - - -/*--------------------------- rt_get_PSP ------------------------------------*/ - -# U32 rt_get_PSP (void); - - .thumb_func - .type rt_get_PSP, %function - .global rt_get_PSP -rt_get_PSP: - .fnstart - .cantunwind - - MRS R0,PSP - BX LR - - .fnend - .size rt_get_PSP, .-rt_get_PSP - - -/*--------------------------- os_set_env ------------------------------------*/ - -# void os_set_env (void); - /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ - - .thumb_func - .type os_set_env, %function - .global os_set_env -os_set_env: - .fnstart - .cantunwind - - MOV R0,SP /* PSP = MSP */ - MSR PSP,R0 - LDR R0,=os_flags - LDRB R0,[R0] - LSLS R0,#31 - BNE PrivilegedE - MOVS R0,#0x03 /* Unprivileged Thread mode, use PSP */ - MSR CONTROL,R0 - BX LR -PrivilegedE: - MOVS R0,#0x02 /* Privileged Thread mode, use PSP */ - MSR CONTROL,R0 - BX LR - - .fnend - .size os_set_env, .-os_set_env - - -/*--------------------------- _alloc_box ------------------------------------*/ - -# void *_alloc_box (void *box_mem); - /* Function wrapper for Unprivileged/Privileged mode. */ - - .thumb_func - .type _alloc_box, %function - .global _alloc_box -_alloc_box: - .fnstart - .cantunwind - - LDR R3,=rt_alloc_box - MOV R12,R3 - MRS R3,IPSR - LSLS R3,#24 - BNE PrivilegedA - MRS R3,CONTROL - LSLS R3,#31 - BEQ PrivilegedA - SVC 0 - BX LR -PrivilegedA: - BX R12 - - .fnend - .size _alloc_box, .-_alloc_box - - -/*--------------------------- _free_box -------------------------------------*/ - -# int _free_box (void *box_mem, void *box); - /* Function wrapper for Unprivileged/Privileged mode. */ - - .thumb_func - .type _free_box, %function - .global _free_box -_free_box: - .fnstart - .cantunwind - - LDR R3,=rt_free_box - MOV R12,R3 - MRS R3,IPSR - LSLS R3,#24 - BNE PrivilegedF - MRS R3,CONTROL - LSLS R3,#31 - BEQ PrivilegedF - SVC 0 - BX LR -PrivilegedF: - BX R12 - - .fnend - .size _free_box, .-_free_box - - -/*-------------------------- SVC_Handler ------------------------------------*/ - -# void SVC_Handler (void); - - .thumb_func - .type SVC_Handler, %function - .global SVC_Handler -SVC_Handler: - .fnstart - .cantunwind - - MRS R0,PSP /* Read PSP */ - LDR R1,[R0,#24] /* Read Saved PC from Stack */ - SUBS R1,R1,#2 /* Point to SVC Instruction */ - LDRB R1,[R1] /* Load SVC Number */ - CMP R1,#0 - BNE SVC_User /* User SVC Number > 0 */ - - MOV LR,R4 - LDMIA R0,{R0-R3,R4} /* Read R0-R3,R12 from stack */ - MOV R12,R4 - MOV R4,LR - BLX R12 /* Call SVC Function */ - - MRS R3,PSP /* Read PSP */ - STMIA R3!,{R0-R2} /* Store return values */ - - LDR R3,=os_tsk - LDMIA R3!,{R1,R2} /* os_tsk.run, os_tsk.new */ - CMP R1,R2 - BEQ SVC_Exit /* no task switch */ - - SUBS R3,#8 - CMP R1,#0 /* Runtask deleted? */ - BEQ SVC_Next - - MRS R0,PSP /* Read PSP */ - SUBS R0,R0,#32 /* Adjust Start Address */ - STR R0,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ - STMIA R0!,{R4-R7} /* Save old context (R4-R7) */ - MOV R4,R8 - MOV R5,R9 - MOV R6,R10 - MOV R7,R11 - STMIA R0!,{R4-R7} /* Save old context (R8-R11) */ - - PUSH {R2,R3} - BL rt_stk_check /* Check for Stack overflow */ - POP {R2,R3} - -SVC_Next: - STR R2,[R3] /* os_tsk.run = os_tsk.new */ - - LDR R0,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ - ADDS R0,R0,#16 /* Adjust Start Address */ - LDMIA R0!,{R4-R7} /* Restore new Context (R8-R11) */ - MOV R8,R4 - MOV R9,R5 - MOV R10,R6 - MOV R11,R7 - MSR PSP,R0 /* Write PSP */ - SUBS R0,R0,#32 /* Adjust Start Address */ - LDMIA R0!,{R4-R7} /* Restore new Context (R4-R7) */ - -SVC_Exit: - MOVS R0,#~0xFFFFFFFD /* Set EXC_RETURN value */ - MVNS R0,R0 - BX R0 /* RETI to Thread Mode, use PSP */ - - /*------------------- User SVC ------------------------------*/ - -SVC_User: - PUSH {R4,LR} /* Save Registers */ - LDR R2,=SVC_Count - LDR R2,[R2] - CMP R1,R2 - BHI SVC_Done /* Overflow */ - - LDR R4,=SVC_Table-4 - LSLS R1,R1,#2 - LDR R4,[R4,R1] /* Load SVC Function Address */ - MOV LR,R4 - - LDMIA R0,{R0-R3,R4} /* Read R0-R3,R12 from stack */ - MOV R12,R4 - BLX LR /* Call SVC Function */ - - MRS R4,PSP /* Read PSP */ - STMIA R4!,{R0-R3} /* Function return values */ -SVC_Done: - POP {R4,PC} /* RETI */ - - .fnend - .size SVC_Handler, .-SVC_Handler - - -/*-------------------------- PendSV_Handler ---------------------------------*/ - -# void PendSV_Handler (void); - - .thumb_func - .type PendSV_Handler, %function - .global PendSV_Handler - .global Sys_Switch -PendSV_Handler: - .fnstart - .cantunwind - - BL rt_pop_req - -Sys_Switch: - LDR R3,=os_tsk - LDMIA R3!,{R1,R2} /* os_tsk.run, os_tsk.new */ - CMP R1,R2 - BEQ Sys_Exit /* no task switch */ - - SUBS R3,#8 - - MRS R0,PSP /* Read PSP */ - SUBS R0,R0,#32 /* Adjust Start Address */ - STR R0,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ - STMIA R0!,{R4-R7} /* Save old context (R4-R7) */ - MOV R4,R8 - MOV R5,R9 - MOV R6,R10 - MOV R7,R11 - STMIA R0!,{R4-R7} /* Save old context (R8-R11) */ - - PUSH {R2,R3} - BL rt_stk_check /* Check for Stack overflow */ - POP {R2,R3} - - STR R2,[R3] /* os_tsk.run = os_tsk.new */ - - LDR R0,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ - ADDS R0,R0,#16 /* Adjust Start Address */ - LDMIA R0!,{R4-R7} /* Restore new Context (R8-R11) */ - MOV R8,R4 - MOV R9,R5 - MOV R10,R6 - MOV R11,R7 - MSR PSP,R0 /* Write PSP */ - SUBS R0,R0,#32 /* Adjust Start Address */ - LDMIA R0!,{R4-R7} /* Restore new Context (R4-R7) */ - -Sys_Exit: - MOVS R0,#~0xFFFFFFFD /* Set EXC_RETURN value */ - MVNS R0,R0 - BX R0 /* RETI to Thread Mode, use PSP */ - - .fnend - .size PendSV_Handler, .-PendSV_Handler - - -/*-------------------------- SysTick_Handler --------------------------------*/ - -# void SysTick_Handler (void); - - .thumb_func - .type SysTick_Handler, %function - .global SysTick_Handler -SysTick_Handler: - .fnstart - .cantunwind - - BL rt_systick - B Sys_Switch - - .fnend - .size SysTick_Handler, .-SysTick_Handler - - -/*-------------------------- OS_Tick_Handler --------------------------------*/ - -# void OS_Tick_Handler (void); - - .thumb_func - .type OS_Tick_Handler, %function - .global OS_Tick_Handler -OS_Tick_Handler: - .fnstart - .cantunwind - - BL os_tick_irqack - BL rt_systick - B Sys_Switch - - .fnend - .size OS_Tick_Handler, .-OS_Tick_Handler - - - .end - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/rtx/TARGET_M0P/TOOLCHAIN_GCC/SVC_Table.s Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -;/*---------------------------------------------------------------------------- -; * RL-ARM - RTX -; *---------------------------------------------------------------------------- -; * Name: SVC_TABLE.S -; * Purpose: Pre-defined SVC Table for Cortex-M -; * Rev.: V4.60 -; *---------------------------------------------------------------------------- -; * -; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH -; * All rights reserved. -; * Redistribution and use in source and binary forms, with or without -; * modification, are permitted provided that the following conditions are met: -; * - Redistributions of source code must retain the above copyright -; * notice, this list of conditions and the following disclaimer. -; * - Redistributions in binary form must reproduce the above copyright -; * notice, this list of conditions and the following disclaimer in the -; * documentation and/or other materials provided with the distribution. -; * - Neither the name of ARM nor the names of its contributors may be used -; * to endorse or promote products derived from this software without -; * specific prior written permission. -; * -; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE -; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -; * POSSIBILITY OF SUCH DAMAGE. -; *---------------------------------------------------------------------------*/ - - - .file "SVC_Table.S" - - - .section ".svc_table" - - .global SVC_Table -SVC_Table: -/* Insert user SVC functions here. SVC 0 used by RTL Kernel. */ -# .long __SVC_1 /* user SVC function */ -SVC_End: - - .global SVC_Count -SVC_Count: - .long (SVC_End-SVC_Table)/4 - - - .end - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/rtx/TARGET_M3/TOOLCHAIN_ARM/HAL_CM3.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,249 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: HAL_CM3.C - * Purpose: Hardware Abstraction Layer for Cortex-M3 - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Conf.h" -#include "rt_System.h" -#include "rt_HAL_CM.h" -#include "rt_Task.h" -#include "rt_MemBox.h" - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_set_PSP ------------------------------------*/ - -__asm void rt_set_PSP (U32 stack) { - MSR PSP,R0 - BX LR -} - - -/*--------------------------- rt_get_PSP ------------------------------------*/ - -__asm U32 rt_get_PSP (void) { - MRS R0,PSP - BX LR -} - - -/*--------------------------- os_set_env ------------------------------------*/ - -__asm void os_set_env (void) { - /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ - MOV R0,SP ; PSP = MSP - MSR PSP,R0 - LDR R0,=__cpp(&os_flags) - LDRB R0,[R0] - LSLS R0,#31 - MOVNE R0,#0x02 ; Privileged Thread mode, use PSP - MOVEQ R0,#0x03 ; Unprivileged Thread mode, use PSP - MSR CONTROL,R0 - BX LR - - ALIGN -} - - -/*--------------------------- _alloc_box ------------------------------------*/ - -__asm void *_alloc_box (void *box_mem) { - /* Function wrapper for Unprivileged/Privileged mode. */ - LDR R12,=__cpp(rt_alloc_box) - MRS R3,IPSR - LSLS R3,#24 - BXNE R12 - MRS R3,CONTROL - LSLS R3,#31 - BXEQ R12 - SVC 0 - BX LR - - ALIGN -} - - -/*--------------------------- _free_box -------------------------------------*/ - -__asm int _free_box (void *box_mem, void *box) { - /* Function wrapper for Unprivileged/Privileged mode. */ - LDR R12,=__cpp(rt_free_box) - MRS R3,IPSR - LSLS R3,#24 - BXNE R12 - MRS R3,CONTROL - LSLS R3,#31 - BXEQ R12 - SVC 0 - BX LR - - ALIGN -} - - -/*-------------------------- SVC_Handler ------------------------------------*/ - -__asm void SVC_Handler (void) { - PRESERVE8 - - IMPORT SVC_Count - IMPORT SVC_Table - IMPORT rt_stk_check - - MRS R0,PSP ; Read PSP - LDR R1,[R0,#24] ; Read Saved PC from Stack - LDRB R1,[R1,#-2] ; Load SVC Number - CBNZ R1,SVC_User - - LDM R0,{R0-R3,R12} ; Read R0-R3,R12 from stack - BLX R12 ; Call SVC Function - - MRS R12,PSP ; Read PSP - STM R12,{R0-R2} ; Store return values - - LDR R3,=__cpp(&os_tsk) - LDM R3,{R1,R2} ; os_tsk.run, os_tsk.new - CMP R1,R2 - BEQ SVC_Exit ; no task switch - - CBZ R1,SVC_Next ; Runtask deleted? - STMDB R12!,{R4-R11} ; Save Old context - STR R12,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack - - PUSH {R2,R3} - BL rt_stk_check ; Check for Stack overflow - POP {R2,R3} - -SVC_Next - STR R2,[R3] ; os_tsk.run = os_tsk.new - - LDR R12,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack - LDMIA R12!,{R4-R11} ; Restore New Context - MSR PSP,R12 ; Write PSP - -SVC_Exit - MVN LR,#:NOT:0xFFFFFFFD ; set EXC_RETURN value - BX LR - - /*------------------- User SVC ------------------------------*/ - -SVC_User - PUSH {R4,LR} ; Save Registers - LDR R2,=SVC_Count - LDR R2,[R2] - CMP R1,R2 - BHI SVC_Done ; Overflow - - LDR R4,=SVC_Table-4 - LDR R4,[R4,R1,LSL #2] ; Load SVC Function Address - - LDM R0,{R0-R3,R12} ; Read R0-R3,R12 from stack - BLX R4 ; Call SVC Function - - MRS R12,PSP - STM R12,{R0-R3} ; Function return values -SVC_Done - POP {R4,PC} ; RETI - - ALIGN -} - - -/*-------------------------- PendSV_Handler ---------------------------------*/ - -__asm void PendSV_Handler (void) { - PRESERVE8 - - BL __cpp(rt_pop_req) - -Sys_Switch - LDR R3,=__cpp(&os_tsk) - LDM R3,{R1,R2} ; os_tsk.run, os_tsk.new - CMP R1,R2 - BEQ Sys_Exit - - MRS R12,PSP ; Read PSP - STMDB R12!,{R4-R11} ; Save Old context - STR R12,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack - - PUSH {R2,R3} - BL rt_stk_check ; Check for Stack overflow - POP {R2,R3} - - STR R2,[R3] ; os_tsk.run = os_tsk.new - - LDR R12,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack - LDMIA R12!,{R4-R11} ; Restore New Context - MSR PSP,R12 ; Write PSP - -Sys_Exit - MVN LR,#:NOT:0xFFFFFFFD ; set EXC_RETURN value - BX LR ; Return to Thread Mode - - ALIGN -} - - -/*-------------------------- SysTick_Handler --------------------------------*/ - -__asm void SysTick_Handler (void) { - PRESERVE8 - - BL __cpp(rt_systick) - B Sys_Switch - - ALIGN -} - - -/*-------------------------- OS_Tick_Handler --------------------------------*/ - -__asm void OS_Tick_Handler (void) { - PRESERVE8 - - BL __cpp(os_tick_irqack) - BL __cpp(rt_systick) - B Sys_Switch - - ALIGN -} - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx/TARGET_M3/TOOLCHAIN_ARM/SVC_Table.s Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -;/*---------------------------------------------------------------------------- -; * RL-ARM - RTX -; *---------------------------------------------------------------------------- -; * Name: SVC_TABLE.S -; * Purpose: Pre-defined SVC Table for Cortex-M -; * Rev.: V4.60 -; *---------------------------------------------------------------------------- -; * -; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH -; * All rights reserved. -; * Redistribution and use in source and binary forms, with or without -; * modification, are permitted provided that the following conditions are met: -; * - Redistributions of source code must retain the above copyright -; * notice, this list of conditions and the following disclaimer. -; * - Redistributions in binary form must reproduce the above copyright -; * notice, this list of conditions and the following disclaimer in the -; * documentation and/or other materials provided with the distribution. -; * - Neither the name of ARM nor the names of its contributors may be used -; * to endorse or promote products derived from this software without -; * specific prior written permission. -; * -; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE -; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -; * POSSIBILITY OF SUCH DAMAGE. -; *---------------------------------------------------------------------------*/ - - - AREA SVC_TABLE, CODE, READONLY - - EXPORT SVC_Count - -SVC_Cnt EQU (SVC_End-SVC_Table)/4 -SVC_Count DCD SVC_Cnt - -; Import user SVC functions here. -; IMPORT __SVC_1 - - EXPORT SVC_Table -SVC_Table -; Insert user SVC functions here. SVC 0 used by RTL Kernel. -; DCD __SVC_1 ; user SVC function - -SVC_End - - END - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/rtx/TARGET_M3/TOOLCHAIN_GCC/HAL_CM3.s Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,323 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: HAL_CM3.S - * Purpose: Hardware Abstraction Layer for Cortex-M3 - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - - .file "HAL_CM3.S" - .syntax unified - - .equ TCB_TSTACK, 36 - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - .thumb - - .section ".text" - .align 2 - - -/*--------------------------- rt_set_PSP ------------------------------------*/ - -# void rt_set_PSP (U32 stack); - - .thumb_func - .type rt_set_PSP, %function - .global rt_set_PSP -rt_set_PSP: - .fnstart - .cantunwind - - MSR PSP,R0 - BX LR - - .fnend - .size rt_set_PSP, .-rt_set_PSP - - -/*--------------------------- rt_get_PSP ------------------------------------*/ - -# U32 rt_get_PSP (void); - - .thumb_func - .type rt_get_PSP, %function - .global rt_get_PSP -rt_get_PSP: - .fnstart - .cantunwind - - MRS R0,PSP - BX LR - - .fnend - .size rt_get_PSP, .-rt_get_PSP - - -/*--------------------------- os_set_env ------------------------------------*/ - -# void os_set_env (void); - /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ - - .thumb_func - .type os_set_env, %function - .global os_set_env -os_set_env: - .fnstart - .cantunwind - - MOV R0,SP /* PSP = MSP */ - MSR PSP,R0 - LDR R0,=os_flags - LDRB R0,[R0] - LSLS R0,#31 - ITE NE - MOVNE R0,#0x02 /* Privileged Thread mode, use PSP */ - MOVEQ R0,#0x03 /* Unprivileged Thread mode, use PSP */ - MSR CONTROL,R0 - BX LR - - .fnend - .size os_set_env, .-os_set_env - - -/*--------------------------- _alloc_box ------------------------------------*/ - -# void *_alloc_box (void *box_mem); - /* Function wrapper for Unprivileged/Privileged mode. */ - - .thumb_func - .type _alloc_box, %function - .global _alloc_box -_alloc_box: - .fnstart - .cantunwind - - LDR R12,=rt_alloc_box - MRS R3,IPSR - LSLS R3,#24 - IT NE - BXNE R12 - MRS R3,CONTROL - LSLS R3,#31 - IT EQ - BXEQ R12 - SVC 0 - BX LR - - .fnend - .size _alloc_box, .-_alloc_box - - -/*--------------------------- _free_box -------------------------------------*/ - -# int _free_box (void *box_mem, void *box); - /* Function wrapper for Unprivileged/Privileged mode. */ - - .thumb_func - .type _free_box, %function - .global _free_box -_free_box: - .fnstart - .cantunwind - - LDR R12,=rt_free_box - MRS R3,IPSR - LSLS R3,#24 - IT NE - BXNE R12 - MRS R3,CONTROL - LSLS R3,#31 - IT EQ - BXEQ R12 - SVC 0 - BX LR - - .fnend - .size _free_box, .-_free_box - - -/*-------------------------- SVC_Handler ------------------------------------*/ - -# void SVC_Handler (void); - - .thumb_func - .type SVC_Handler, %function - .global SVC_Handler -SVC_Handler: - .fnstart - .cantunwind - - MRS R0,PSP /* Read PSP */ - LDR R1,[R0,#24] /* Read Saved PC from Stack */ - LDRB R1,[R1,#-2] /* Load SVC Number */ - CBNZ R1,SVC_User - - LDM R0,{R0-R3,R12} /* Read R0-R3,R12 from stack */ - BLX R12 /* Call SVC Function */ - - MRS R12,PSP /* Read PSP */ - STM R12,{R0-R2} /* Store return values */ - - LDR R3,=os_tsk - LDM R3,{R1,R2} /* os_tsk.run, os_tsk.new */ - CMP R1,R2 - BEQ SVC_Exit /* no task switch */ - - CBZ R1,SVC_Next /* Runtask deleted? */ - STMDB R12!,{R4-R11} /* Save Old context */ - STR R12,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ - - PUSH {R2,R3} - BL rt_stk_check /* Check for Stack overflow */ - POP {R2,R3} - -SVC_Next: - STR R2,[R3] /* os_tsk.run = os_tsk.new */ - - LDR R12,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ - LDMIA R12!,{R4-R11} /* Restore New Context */ - MSR PSP,R12 /* Write PSP */ - -SVC_Exit: - MVN LR,#~0xFFFFFFFD /* set EXC_RETURN value */ - BX LR - - /*------------------- User SVC ------------------------------*/ - -SVC_User: - PUSH {R4,LR} /* Save Registers */ - LDR R2,=SVC_Count - LDR R2,[R2] - CMP R1,R2 - BHI SVC_Done /* Overflow */ - - LDR R4,=SVC_Table-4 - LDR R4,[R4,R1,LSL #2] /* Load SVC Function Address */ - - LDM R0,{R0-R3,R12} /* Read R0-R3,R12 from stack */ - BLX R4 /* Call SVC Function */ - - MRS R12,PSP - STM R12,{R0-R3} /* Function return values */ -SVC_Done: - POP {R4,PC} /* RETI */ - - .fnend - .size SVC_Handler, .-SVC_Handler - - -/*-------------------------- PendSV_Handler ---------------------------------*/ - -# void PendSV_Handler (void); - - .thumb_func - .type PendSV_Handler, %function - .global PendSV_Handler - .global Sys_Switch -PendSV_Handler: - .fnstart - .cantunwind - - BL rt_pop_req - -Sys_Switch: - LDR R3,=os_tsk - LDM R3,{R1,R2} /* os_tsk.run, os_tsk.new */ - CMP R1,R2 - BEQ Sys_Exit - - MRS R12,PSP /* Read PSP */ - STMDB R12!,{R4-R11} /* Save Old context */ - STR R12,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ - - PUSH {R2,R3} - BL rt_stk_check /* Check for Stack overflow */ - POP {R2,R3} - - STR R2,[R3] /* os_tsk.run = os_tsk.new */ - - LDR R12,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ - LDMIA R12!,{R4-R11} /* Restore New Context */ - MSR PSP,R12 /* Write PSP */ - -Sys_Exit: - MVN LR,#~0xFFFFFFFD /* set EXC_RETURN value */ - BX LR /* Return to Thread Mode */ - - .fnend - .size PendSV_Handler, .-PendSV_Handler - - -/*-------------------------- SysTick_Handler --------------------------------*/ - -# void SysTick_Handler (void); - - .thumb_func - .type SysTick_Handler, %function - .global SysTick_Handler -SysTick_Handler: - .fnstart - .cantunwind - - BL rt_systick - B Sys_Switch - - .fnend - .size SysTick_Handler, .-SysTick_Handler - - -/*-------------------------- OS_Tick_Handler --------------------------------*/ - -# void OS_Tick_Handler (void); - - .thumb_func - .type OS_Tick_Handler, %function - .global OS_Tick_Handler -OS_Tick_Handler: - .fnstart - .cantunwind - - BL os_tick_irqack - BL rt_systick - B Sys_Switch - - .fnend - .size OS_Tick_Handler, .-OS_Tick_Handler - - - .end - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/rtx/TARGET_M3/TOOLCHAIN_GCC/SVC_Table.s Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -;/*---------------------------------------------------------------------------- -; * RL-ARM - RTX -; *---------------------------------------------------------------------------- -; * Name: SVC_TABLE.S -; * Purpose: Pre-defined SVC Table for Cortex-M -; * Rev.: V4.60 -; *---------------------------------------------------------------------------- -; * -; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH -; * All rights reserved. -; * Redistribution and use in source and binary forms, with or without -; * modification, are permitted provided that the following conditions are met: -; * - Redistributions of source code must retain the above copyright -; * notice, this list of conditions and the following disclaimer. -; * - Redistributions in binary form must reproduce the above copyright -; * notice, this list of conditions and the following disclaimer in the -; * documentation and/or other materials provided with the distribution. -; * - Neither the name of ARM nor the names of its contributors may be used -; * to endorse or promote products derived from this software without -; * specific prior written permission. -; * -; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE -; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -; * POSSIBILITY OF SUCH DAMAGE. -; *---------------------------------------------------------------------------*/ - - - .file "SVC_Table.S" - - - .section ".svc_table" - - .global SVC_Table -SVC_Table: -/* Insert user SVC functions here. SVC 0 used by RTL Kernel. */ -# .long __SVC_1 /* user SVC function */ -SVC_End: - - .global SVC_Count -SVC_Count: - .long (SVC_End-SVC_Table)/4 - - - .end - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/rtx/TARGET_M4/TOOLCHAIN_ARM/HAL_CM4.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,309 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: HAL_CM4.C - * Purpose: Hardware Abstraction Layer for Cortex-M4 - * Rev.: V4.70 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Conf.h" -#include "rt_System.h" -#include "rt_HAL_CM.h" -#include "rt_Task.h" -#include "rt_MemBox.h" - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_set_PSP ------------------------------------*/ - -__asm void rt_set_PSP (U32 stack) { - MSR PSP,R0 - BX LR -} - - -/*--------------------------- rt_get_PSP ------------------------------------*/ - -__asm U32 rt_get_PSP (void) { - MRS R0,PSP - BX LR -} - - -/*--------------------------- os_set_env ------------------------------------*/ - -__asm void os_set_env (void) { - /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ - MOV R0,SP ; PSP = MSP - MSR PSP,R0 - LDR R0,=__cpp(&os_flags) - LDRB R0,[R0] - LSLS R0,#31 - MOVNE R0,#0x02 ; Privileged Thread mode, use PSP - MOVEQ R0,#0x03 ; Unprivileged Thread mode, use PSP - MSR CONTROL,R0 - BX LR - - ALIGN -} - - -/*--------------------------- _alloc_box ------------------------------------*/ - -__asm void *_alloc_box (void *box_mem) { - /* Function wrapper for Unprivileged/Privileged mode. */ - LDR R12,=__cpp(rt_alloc_box) - MRS R3,IPSR - LSLS R3,#24 - BXNE R12 - MRS R3,CONTROL - LSLS R3,#31 - BXEQ R12 - SVC 0 - BX LR - - ALIGN -} - - -/*--------------------------- _free_box -------------------------------------*/ - -__asm int _free_box (void *box_mem, void *box) { - /* Function wrapper for Unprivileged/Privileged mode. */ - LDR R12,=__cpp(rt_free_box) - MRS R3,IPSR - LSLS R3,#24 - BXNE R12 - MRS R3,CONTROL - LSLS R3,#31 - BXEQ R12 - SVC 0 - BX LR - - ALIGN -} - - -/*-------------------------- SVC_Handler ------------------------------------*/ - -__asm void SVC_Handler (void) { - PRESERVE8 - - IMPORT SVC_Count - IMPORT SVC_Table - IMPORT rt_stk_check - -#ifdef IFX_XMC4XXX - EXPORT SVC_Handler_Veneer -SVC_Handler_Veneer -#endif - - MRS R0,PSP ; Read PSP - LDR R1,[R0,#24] ; Read Saved PC from Stack - LDRB R1,[R1,#-2] ; Load SVC Number - CBNZ R1,SVC_User - - LDM R0,{R0-R3,R12} ; Read R0-R3,R12 from stack - PUSH {R4,LR} ; Save EXC_RETURN - BLX R12 ; Call SVC Function - POP {R4,LR} ; Restore EXC_RETURN - - MRS R12,PSP ; Read PSP - STM R12,{R0-R2} ; Store return values - - LDR R3,=__cpp(&os_tsk) - LDM R3,{R1,R2} ; os_tsk.run, os_tsk.new - CMP R1,R2 -#ifdef IFX_XMC4XXX - PUSHEQ {LR} - POPEQ {PC} -#else - BXEQ LR ; RETI, no task switch -#endif - - CBZ R1,SVC_Next ; Runtask deleted? - TST LR,#0x10 ; is it extended frame? - VSTMDBEQ R12!,{S16-S31} ; yes, stack also VFP hi-regs - MOVEQ R0,#0x01 ; os_tsk->stack_frame val - MOVNE R0,#0x00 - STRB R0,[R1,#TCB_STACKF] ; os_tsk.run->stack_frame = val - STMDB R12!,{R4-R11} ; Save Old context - STR R12,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack - - PUSH {R2,R3} - BL rt_stk_check ; Check for Stack overflow - POP {R2,R3} - -SVC_Next - STR R2,[R3] ; os_tsk.run = os_tsk.new - - LDR R12,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack - LDMIA R12!,{R4-R11} ; Restore New Context - LDRB R0,[R2,#TCB_STACKF] ; Stack Frame - CMP R0,#0 ; Basic/Extended Stack Frame - VLDMIANE R12!,{S16-S31} ; restore VFP hi-registers - MVNNE LR,#:NOT:0xFFFFFFED ; set EXC_RETURN value - MVNEQ LR,#:NOT:0xFFFFFFFD - MSR PSP,R12 ; Write PSP - -SVC_Exit -#ifdef IFX_XMC4XXX - PUSH {LR} - POP {PC} -#else - BX LR -#endif - - /*------------------- User SVC ------------------------------*/ - -SVC_User - PUSH {R4,LR} ; Save Registers - LDR R2,=SVC_Count - LDR R2,[R2] - CMP R1,R2 - BHI SVC_Done ; Overflow - - LDR R4,=SVC_Table-4 - LDR R4,[R4,R1,LSL #2] ; Load SVC Function Address - - LDM R0,{R0-R3,R12} ; Read R0-R3,R12 from stack - BLX R4 ; Call SVC Function - - MRS R12,PSP - STM R12,{R0-R3} ; Function return values -SVC_Done - POP {R4,PC} ; RETI - - ALIGN -} - - -/*-------------------------- PendSV_Handler ---------------------------------*/ - -__asm void PendSV_Handler (void) { - PRESERVE8 - -#ifdef IFX_XMC4XXX - EXPORT PendSV_Handler_Veneer -PendSV_Handler_Veneer -#endif - - PUSH {R4,LR} ; Save EXC_RETURN - BL __cpp(rt_pop_req) - -Sys_Switch - POP {R4,LR} ; Restore EXC_RETURN - - LDR R3,=__cpp(&os_tsk) - LDM R3,{R1,R2} ; os_tsk.run, os_tsk.new - CMP R1,R2 -#ifdef IFX_XMC4XXX - PUSHEQ {LR} - POPEQ {PC} -#else - BXEQ LR ; RETI, no task switch -#endif - - MRS R12,PSP ; Read PSP - TST LR,#0x10 ; is it extended frame? - VSTMDBEQ R12!,{S16-S31} ; yes, stack also VFP hi-regs - MOVEQ R0,#0x01 ; os_tsk->stack_frame val - MOVNE R0,#0x00 - STRB R0,[R1,#TCB_STACKF] ; os_tsk.run->stack_frame = val - STMDB R12!,{R4-R11} ; Save Old context - STR R12,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack - - PUSH {R2,R3} - BL rt_stk_check ; Check for Stack overflow - POP {R2,R3} - - STR R2,[R3] ; os_tsk.run = os_tsk.new - - LDR R12,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack - LDMIA R12!,{R4-R11} ; Restore New Context - LDRB R0,[R2,#TCB_STACKF] ; Stack Frame - CMP R0,#0 ; Basic/Extended Stack Frame - VLDMIANE R12!,{S16-S31} ; restore VFP hi-regs - MVNNE LR,#:NOT:0xFFFFFFED ; set EXC_RETURN value - MVNEQ LR,#:NOT:0xFFFFFFFD - MSR PSP,R12 ; Write PSP - -Sys_Exit -#ifdef IFX_XMC4XXX - PUSH {LR} - POP {PC} -#else - BX LR ; Return to Thread Mode -#endif - - ALIGN -} - - -/*-------------------------- SysTick_Handler --------------------------------*/ - -__asm void SysTick_Handler (void) { - PRESERVE8 - -#ifdef IFX_XMC4XXX - EXPORT SysTick_Handler_Veneer -SysTick_Handler_Veneer -#endif - - PUSH {R4,LR} ; Save EXC_RETURN - BL __cpp(rt_systick) - B Sys_Switch - - ALIGN -} - - -/*-------------------------- OS_Tick_Handler --------------------------------*/ - -__asm void OS_Tick_Handler (void) { - PRESERVE8 - - PUSH {R4,LR} ; Save EXC_RETURN - BL __cpp(os_tick_irqack) - BL __cpp(rt_systick) - B Sys_Switch - - ALIGN -} - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx/TARGET_M4/TOOLCHAIN_ARM/SVC_Table.s Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -;/*---------------------------------------------------------------------------- -; * RL-ARM - RTX -; *---------------------------------------------------------------------------- -; * Name: SVC_TABLE.S -; * Purpose: Pre-defined SVC Table for Cortex-M -; * Rev.: V4.70 -; *---------------------------------------------------------------------------- -; * -; * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH -; * All rights reserved. -; * Redistribution and use in source and binary forms, with or without -; * modification, are permitted provided that the following conditions are met: -; * - Redistributions of source code must retain the above copyright -; * notice, this list of conditions and the following disclaimer. -; * - Redistributions in binary form must reproduce the above copyright -; * notice, this list of conditions and the following disclaimer in the -; * documentation and/or other materials provided with the distribution. -; * - Neither the name of ARM nor the names of its contributors may be used -; * to endorse or promote products derived from this software without -; * specific prior written permission. -; * -; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE -; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -; * POSSIBILITY OF SUCH DAMAGE. -; *---------------------------------------------------------------------------*/ - - - AREA SVC_TABLE, CODE, READONLY - - EXPORT SVC_Count - -SVC_Cnt EQU (SVC_End-SVC_Table)/4 -SVC_Count DCD SVC_Cnt - -; Import user SVC functions here. -; IMPORT __SVC_1 - - EXPORT SVC_Table -SVC_Table -; Insert user SVC functions here. SVC 0 used by RTL Kernel. -; DCD __SVC_1 ; user SVC function - -SVC_End - - END - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/rtx/TARGET_M4/TOOLCHAIN_GCC/HAL_CM4.s Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,389 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: HAL_CM4.S - * Purpose: Hardware Abstraction Layer for Cortex-M4 - * Rev.: V4.70 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - - .file "HAL_CM4.S" - .syntax unified - - .equ TCB_STACKF, 32 - .equ TCB_TSTACK, 36 - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - .thumb - - .section ".text" - .align 2 - - -/*--------------------------- rt_set_PSP ------------------------------------*/ - -# void rt_set_PSP (U32 stack); - - .thumb_func - .type rt_set_PSP, %function - .global rt_set_PSP -rt_set_PSP: - .fnstart - .cantunwind - - MSR PSP,R0 - BX LR - - .fnend - .size rt_set_PSP, .-rt_set_PSP - - -/*--------------------------- rt_get_PSP ------------------------------------*/ - -# U32 rt_get_PSP (void); - - .thumb_func - .type rt_get_PSP, %function - .global rt_get_PSP -rt_get_PSP: - .fnstart - .cantunwind - - MRS R0,PSP - BX LR - - .fnend - .size rt_get_PSP, .-rt_get_PSP - - -/*--------------------------- os_set_env ------------------------------------*/ - -# void os_set_env (void); - /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ - - .thumb_func - .type os_set_env, %function - .global os_set_env -os_set_env: - .fnstart - .cantunwind - - MOV R0,SP /* PSP = MSP */ - MSR PSP,R0 - LDR R0,=os_flags - LDRB R0,[R0] - LSLS R0,#31 - ITE NE - MOVNE R0,#0x02 /* Privileged Thread mode, use PSP */ - MOVEQ R0,#0x03 /* Unprivileged Thread mode, use PSP */ - MSR CONTROL,R0 - BX LR - - .fnend - .size os_set_env, .-os_set_env - - -/*--------------------------- _alloc_box ------------------------------------*/ - -# void *_alloc_box (void *box_mem); - /* Function wrapper for Unprivileged/Privileged mode. */ - - .thumb_func - .type _alloc_box, %function - .global _alloc_box -_alloc_box: - .fnstart - .cantunwind - - LDR R12,=rt_alloc_box - MRS R3,IPSR - LSLS R3,#24 - IT NE - BXNE R12 - MRS R3,CONTROL - LSLS R3,#31 - IT EQ - BXEQ R12 - SVC 0 - BX LR - - .fnend - .size _alloc_box, .-_alloc_box - - -/*--------------------------- _free_box -------------------------------------*/ - -# int _free_box (void *box_mem, void *box); - /* Function wrapper for Unprivileged/Privileged mode. */ - - .thumb_func - .type _free_box, %function - .global _free_box -_free_box: - .fnstart - .cantunwind - - LDR R12,=rt_free_box - MRS R3,IPSR - LSLS R3,#24 - IT NE - BXNE R12 - MRS R3,CONTROL - LSLS R3,#31 - IT EQ - BXEQ R12 - SVC 0 - BX LR - - .fnend - .size _free_box, .-_free_box - - -/*-------------------------- SVC_Handler ------------------------------------*/ - -# void SVC_Handler (void); - - .thumb_func - .type SVC_Handler, %function - .global SVC_Handler -SVC_Handler: - .ifdef IFX_XMC4XXX - .global SVC_Handler_Veneer -SVC_Handler_Veneer: - .endif - .fnstart - .cantunwind - - MRS R0,PSP /* Read PSP */ - LDR R1,[R0,#24] /* Read Saved PC from Stack */ - LDRB R1,[R1,#-2] /* Load SVC Number */ - CBNZ R1,SVC_User - - LDM R0,{R0-R3,R12} /* Read R0-R3,R12 from stack */ - PUSH {R4,LR} /* Save EXC_RETURN */ - BLX R12 /* Call SVC Function */ - POP {R4,LR} /* Restore EXC_RETURN */ - - MRS R12,PSP /* Read PSP */ - STM R12,{R0-R2} /* Store return values */ - - LDR R3,=os_tsk - LDM R3,{R1,R2} /* os_tsk.run, os_tsk.new */ - CMP R1,R2 - .ifdef IFX_XMC4XXX - ITT EQ - PUSHEQ {LR} - POPEQ {PC} - .else - IT EQ - BXEQ LR /* RETI, no task switch */ - .endif - - CBZ R1,SVC_Next /* Runtask deleted? */ - TST LR,#0x10 /* is it extended frame? */ - ITTE EQ - VSTMDBEQ R12!,{S16-S31} /* yes, stack also VFP hi-regs */ - MOVEQ R0,#0x01 /* os_tsk->stack_frame val */ - MOVNE R0,#0x00 - STRB R0,[R1,#TCB_STACKF] /* os_tsk.run->stack_frame = val */ - STMDB R12!,{R4-R11} /* Save Old context */ - STR R12,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ - - PUSH {R2,R3} - BL rt_stk_check /* Check for Stack overflow */ - POP {R2,R3} - -SVC_Next: - STR R2,[R3] /* os_tsk.run = os_tsk.new */ - - LDR R12,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ - LDMIA R12!,{R4-R11} /* Restore New Context */ - LDRB R0,[R2,#TCB_STACKF] /* Stack Frame */ - CMP R0,#0 /* Basic/Extended Stack Frame */ - ITTE NE - VLDMIANE R12!,{S16-S31} /* restore VFP hi-registers */ - MVNNE LR,#~0xFFFFFFED /* set EXC_RETURN value */ - MVNEQ LR,#~0xFFFFFFFD - MSR PSP,R12 /* Write PSP */ - -SVC_Exit: - .ifdef IFX_XMC4XXX - PUSH {LR} - POP {PC} - .else - BX LR - .endif - - /*------------------- User SVC ------------------------------*/ - -SVC_User: - PUSH {R4,LR} /* Save Registers */ - LDR R2,=SVC_Count - LDR R2,[R2] - CMP R1,R2 - BHI SVC_Done /* Overflow */ - - LDR R4,=SVC_Table-4 - LDR R4,[R4,R1,LSL #2] /* Load SVC Function Address */ - - LDM R0,{R0-R3,R12} /* Read R0-R3,R12 from stack */ - BLX R4 /* Call SVC Function */ - - MRS R12,PSP - STM R12,{R0-R3} /* Function return values */ -SVC_Done: - POP {R4,PC} /* RETI */ - - .fnend - .size SVC_Handler, .-SVC_Handler - - -/*-------------------------- PendSV_Handler ---------------------------------*/ - -# void PendSV_Handler (void); - - .thumb_func - .type PendSV_Handler, %function - .global PendSV_Handler - .global Sys_Switch -PendSV_Handler: - .ifdef IFX_XMC4XXX - .global PendSV_Handler_Veneer -PendSV_Handler_Veneer: - .endif - .fnstart - .cantunwind - - PUSH {R4,LR} /* Save EXC_RETURN */ - BL rt_pop_req - -Sys_Switch: - POP {R4,LR} /* Restore EXC_RETURN */ - - LDR R3,=os_tsk - LDM R3,{R1,R2} /* os_tsk.run, os_tsk.new */ - CMP R1,R2 - .ifdef IFX_XMC4XXX - ITT EQ - PUSHEQ {LR} - POPEQ {PC} - .else - IT EQ - BXEQ LR /* RETI, no task switch */ - .endif - - MRS R12,PSP /* Read PSP */ - TST LR,#0x10 /* is it extended frame? */ - ITTE EQ - VSTMDBEQ R12!,{S16-S31} /* yes, stack also VFP hi-regs */ - MOVEQ R0,#0x01 /* os_tsk->stack_frame val */ - MOVNE R0,#0x00 - STRB R0,[R1,#TCB_STACKF] /* os_tsk.run->stack_frame = val */ - STMDB R12!,{R4-R11} /* Save Old context */ - STR R12,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ - - PUSH {R2,R3} - BL rt_stk_check /* Check for Stack overflow */ - POP {R2,R3} - - STR R2,[R3] /* os_tsk.run = os_tsk.new */ - - LDR R12,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ - LDMIA R12!,{R4-R11} /* Restore New Context */ - LDRB R0,[R2,#TCB_STACKF] /* Stack Frame */ - CMP R0,#0 /* Basic/Extended Stack Frame */ - ITTE NE - VLDMIANE R12!,{S16-S31} /* restore VFP hi-registers */ - MVNNE LR,#~0xFFFFFFED /* set EXC_RETURN value */ - MVNEQ LR,#~0xFFFFFFFD - MSR PSP,R12 /* Write PSP */ - -Sys_Exit: - .ifdef IFX_XMC4XXX - PUSH {LR} - POP {PC} - .else - BX LR /* Return to Thread Mode */ - .endif - - .fnend - .size PendSV_Handler, .-PendSV_Handler - - -/*-------------------------- SysTick_Handler --------------------------------*/ - -# void SysTick_Handler (void); - - .thumb_func - .type SysTick_Handler, %function - .global SysTick_Handler -SysTick_Handler: - .ifdef IFX_XMC4XXX - .global SysTick_Handler_Veneer -SysTick_Handler_Veneer: - .endif - .fnstart - .cantunwind - - PUSH {R4,LR} /* Save EXC_RETURN */ - BL rt_systick - B Sys_Switch - - .fnend - .size SysTick_Handler, .-SysTick_Handler - - -/*-------------------------- OS_Tick_Handler --------------------------------*/ - -# void OS_Tick_Handler (void); - - .thumb_func - .type OS_Tick_Handler, %function - .global OS_Tick_Handler -OS_Tick_Handler: - .fnstart - .cantunwind - - PUSH {R4,LR} /* Save EXC_RETURN */ - BL os_tick_irqack - BL rt_systick - B Sys_Switch - - .fnend - .size OS_Tick_Handler, .-OS_Tick_Handler - - - .end - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/rtx/TARGET_M4/TOOLCHAIN_GCC/SVC_Table.s Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -;/*---------------------------------------------------------------------------- -; * RL-ARM - RTX -; *---------------------------------------------------------------------------- -; * Name: SVC_TABLE.S -; * Purpose: Pre-defined SVC Table for Cortex-M -; * Rev.: V4.70 -; *---------------------------------------------------------------------------- -; * -; * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH -; * All rights reserved. -; * Redistribution and use in source and binary forms, with or without -; * modification, are permitted provided that the following conditions are met: -; * - Redistributions of source code must retain the above copyright -; * notice, this list of conditions and the following disclaimer. -; * - Redistributions in binary form must reproduce the above copyright -; * notice, this list of conditions and the following disclaimer in the -; * documentation and/or other materials provided with the distribution. -; * - Neither the name of ARM nor the names of its contributors may be used -; * to endorse or promote products derived from this software without -; * specific prior written permission. -; * -; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE -; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -; * POSSIBILITY OF SUCH DAMAGE. -; *---------------------------------------------------------------------------*/ - - - .file "SVC_Table.S" - - - .section ".svc_table" - - .global SVC_Table -SVC_Table: -/* Insert user SVC functions here. SVC 0 used by RTL Kernel. */ -# .long __SVC_1 /* user SVC function */ -SVC_End: - - .global SVC_Count -SVC_Count: - .long (SVC_End-SVC_Table)/4 - - - .end - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/rtx/cmsis_os.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,772 +0,0 @@ -/* ---------------------------------------------------------------------- - * Copyright (C) 2012 ARM Limited. All rights reserved. - * - * $Date: 5. June 2012 - * $Revision: V1.01 - * - * Project: CMSIS-RTOS API - * Title: cmsis_os.h RTX header file - * - * Version 0.02 - * Initial Proposal Phase - * Version 0.03 - * osKernelStart added, optional feature: main started as thread - * osSemaphores have standard behavior - * osTimerCreate does not start the timer, added osTimerStart - * osThreadPass is renamed to osThreadYield - * Version 1.01 - * Support for C++ interface - * - const attribute removed from the osXxxxDef_t typedef's - * - const attribute added to the osXxxxDef macros - * Added: osTimerDelete, osMutexDelete, osSemaphoreDelete - * Added: osKernelInitialize - * -------------------------------------------------------------------- */ - -/** -\page cmsis_os_h Header File Template: cmsis_os.h - -The file \b cmsis_os.h is a template header file for a CMSIS-RTOS compliant Real-Time Operating System (RTOS). -Each RTOS that is compliant with CMSIS-RTOS shall provide a specific \b cmsis_os.h header file that represents -its implementation. - -The file cmsis_os.h contains: - - CMSIS-RTOS API function definitions - - struct definitions for parameters and return types - - status and priority values used by CMSIS-RTOS API functions - - macros for defining threads and other kernel objects - - -<b>Name conventions and header file modifications</b> - -All definitions are prefixed with \b os to give an unique name space for CMSIS-RTOS functions. -Definitions that are prefixed \b os_ are not used in the application code but local to this header file. -All definitions and functions that belong to a module are grouped and have a common prefix, i.e. \b osThread. - -Definitions that are marked with <b>CAN BE CHANGED</b> can be adapted towards the needs of the actual CMSIS-RTOS implementation. -These definitions can be specific to the underlying RTOS kernel. - -Definitions that are marked with <b>MUST REMAIN UNCHANGED</b> cannot be altered. Otherwise the CMSIS-RTOS implementation is no longer -compliant to the standard. Note that some functions are optional and need not to be provided by every CMSIS-RTOS implementation. - - -<b>Function calls from interrupt service routines</b> - -The following CMSIS-RTOS functions can be called from threads and interrupt service routines (ISR): - - \ref osSignalSet - - \ref osSemaphoreRelease - - \ref osPoolAlloc, \ref osPoolCAlloc, \ref osPoolFree - - \ref osMessagePut, \ref osMessageGet - - \ref osMailAlloc, \ref osMailCAlloc, \ref osMailGet, \ref osMailPut, \ref osMailFree - -Functions that cannot be called from an ISR are verifying the interrupt status and return in case that they are called -from an ISR context the status code \b osErrorISR. In some implementations this condition might be caught using the HARD FAULT vector. - -Some CMSIS-RTOS implementations support CMSIS-RTOS function calls from multiple ISR at the same time. -If this is impossible, the CMSIS-RTOS rejects calls by nested ISR functions with the status code \b osErrorISRRecursive. - - -<b>Define and reference object definitions</b> - -With <b>\#define osObjectsExternal</b> objects are defined as external symbols. This allows to create a consistent header file -that is used throughout a project as shown below: - -<i>Header File</i> -\code -#include <cmsis_os.h> // CMSIS RTOS header file - -// Thread definition -extern void thread_sample (void const *argument); // function prototype -osThreadDef (thread_sample, osPriorityBelowNormal, 1, 100); - -// Pool definition -osPoolDef(MyPool, 10, long); -\endcode - - -This header file defines all objects when included in a C/C++ source file. When <b>\#define osObjectsExternal</b> is -present before the header file, the objects are defined as external symbols. A single consistent header file can therefore be -used throughout the whole project. - -<i>Example</i> -\code -#include "osObjects.h" // Definition of the CMSIS-RTOS objects -\endcode - -\code -#define osObjectExternal // Objects will be defined as external symbols -#include "osObjects.h" // Reference to the CMSIS-RTOS objects -\endcode - -*/ - -#ifndef _CMSIS_OS_H -#define _CMSIS_OS_H - -/// \note MUST REMAIN UNCHANGED: \b osCMSIS identifies the CMSIS-RTOS API version. -#define osCMSIS 0x10001 ///< API version (main [31:16] .sub [15:0]) - -/// \note CAN BE CHANGED: \b osCMSIS_KERNEL identifies the underlying RTOS kernel and version number. -#define osCMSIS_RTX ((4<<16)|61) ///< RTOS identification and version (main [31:16] .sub [15:0]) - -/// \note MUST REMAIN UNCHANGED: \b osKernelSystemId shall be consistent in every CMSIS-RTOS. -#define osKernelSystemId "RTX V4.61" ///< RTOS identification string - - -#define CMSIS_OS_RTX - -// The stack space occupied is mainly dependent on the underling C standard library -#if defined(TOOLCHAIN_GCC) || defined(TOOLCHAIN_ARM_STD) -# define WORDS_STACK_SIZE 512 -#elif defined(TOOLCHAIN_ARM_MICRO) -# define WORDS_STACK_SIZE 128 -#endif - -#define DEFAULT_STACK_SIZE (WORDS_STACK_SIZE*4) - - -/// \note MUST REMAIN UNCHANGED: \b osFeature_xxx shall be consistent in every CMSIS-RTOS. -#define osFeature_MainThread 1 ///< main thread 1=main can be thread, 0=not available -#define osFeature_Pool 1 ///< Memory Pools: 1=available, 0=not available -#define osFeature_MailQ 1 ///< Mail Queues: 1=available, 0=not available -#define osFeature_MessageQ 1 ///< Message Queues: 1=available, 0=not available -#define osFeature_Signals 16 ///< maximum number of Signal Flags available per thread -#define osFeature_Semaphore 65535 ///< maximum count for \ref osSemaphoreCreate function -#define osFeature_Wait 0 ///< osWait function: 1=available, 0=not available - -#if defined (__CC_ARM) -#define os_InRegs __value_in_regs // Compiler specific: force struct in registers -#else -#define os_InRegs -#endif - -#include <stdint.h> -#include <stddef.h> - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include "os_tcb.h" - -// ==== Enumeration, structures, defines ==== - -/// Priority used for thread control. -/// \note MUST REMAIN UNCHANGED: \b osPriority shall be consistent in every CMSIS-RTOS. -typedef enum { - osPriorityIdle = -3, ///< priority: idle (lowest) - osPriorityLow = -2, ///< priority: low - osPriorityBelowNormal = -1, ///< priority: below normal - osPriorityNormal = 0, ///< priority: normal (default) - osPriorityAboveNormal = +1, ///< priority: above normal - osPriorityHigh = +2, ///< priority: high - osPriorityRealtime = +3, ///< priority: realtime (highest) - osPriorityError = 0x84 ///< system cannot determine priority or thread has illegal priority -} osPriority; - -/// Timeout value. -/// \note MUST REMAIN UNCHANGED: \b osWaitForever shall be consistent in every CMSIS-RTOS. -#define osWaitForever 0xFFFFFFFF ///< wait forever timeout value - -/// Status code values returned by CMSIS-RTOS functions. -/// \note MUST REMAIN UNCHANGED: \b osStatus shall be consistent in every CMSIS-RTOS. -typedef enum { - osOK = 0, ///< function completed; no error or event occurred. - osEventSignal = 0x08, ///< function completed; signal event occurred. - osEventMessage = 0x10, ///< function completed; message event occurred. - osEventMail = 0x20, ///< function completed; mail event occurred. - osEventTimeout = 0x40, ///< function completed; timeout occurred. - osErrorParameter = 0x80, ///< parameter error: a mandatory parameter was missing or specified an incorrect object. - osErrorResource = 0x81, ///< resource not available: a specified resource was not available. - osErrorTimeoutResource = 0xC1, ///< resource not available within given time: a specified resource was not available within the timeout period. - osErrorISR = 0x82, ///< not allowed in ISR context: the function cannot be called from interrupt service routines. - osErrorISRRecursive = 0x83, ///< function called multiple times from ISR with same object. - osErrorPriority = 0x84, ///< system cannot determine priority or thread has illegal priority. - osErrorNoMemory = 0x85, ///< system is out of memory: it was impossible to allocate or reserve memory for the operation. - osErrorValue = 0x86, ///< value of a parameter is out of range. - osErrorOS = 0xFF, ///< unspecified RTOS error: run-time error but no other error message fits. - os_status_reserved = 0x7FFFFFFF ///< prevent from enum down-size compiler optimization. -} osStatus; - - -/// Timer type value for the timer definition. -/// \note MUST REMAIN UNCHANGED: \b os_timer_type shall be consistent in every CMSIS-RTOS. -typedef enum { - osTimerOnce = 0, ///< one-shot timer - osTimerPeriodic = 1 ///< repeating timer -} os_timer_type; - -/// Entry point of a thread. -/// \note MUST REMAIN UNCHANGED: \b os_pthread shall be consistent in every CMSIS-RTOS. -typedef void (*os_pthread) (void const *argument); - -/// Entry point of a timer call back function. -/// \note MUST REMAIN UNCHANGED: \b os_ptimer shall be consistent in every CMSIS-RTOS. -typedef void (*os_ptimer) (void const *argument); - -// >>> the following data type definitions may shall adapted towards a specific RTOS - -/// Thread ID identifies the thread (pointer to a thread control block). -/// \note CAN BE CHANGED: \b os_thread_cb is implementation specific in every CMSIS-RTOS. -typedef struct os_thread_cb *osThreadId; - -/// Timer ID identifies the timer (pointer to a timer control block). -/// \note CAN BE CHANGED: \b os_timer_cb is implementation specific in every CMSIS-RTOS. -typedef struct os_timer_cb *osTimerId; - -/// Mutex ID identifies the mutex (pointer to a mutex control block). -/// \note CAN BE CHANGED: \b os_mutex_cb is implementation specific in every CMSIS-RTOS. -typedef struct os_mutex_cb *osMutexId; - -/// Semaphore ID identifies the semaphore (pointer to a semaphore control block). -/// \note CAN BE CHANGED: \b os_semaphore_cb is implementation specific in every CMSIS-RTOS. -typedef struct os_semaphore_cb *osSemaphoreId; - -/// Pool ID identifies the memory pool (pointer to a memory pool control block). -/// \note CAN BE CHANGED: \b os_pool_cb is implementation specific in every CMSIS-RTOS. -typedef struct os_pool_cb *osPoolId; - -/// Message ID identifies the message queue (pointer to a message queue control block). -/// \note CAN BE CHANGED: \b os_messageQ_cb is implementation specific in every CMSIS-RTOS. -typedef struct os_messageQ_cb *osMessageQId; - -/// Mail ID identifies the mail queue (pointer to a mail queue control block). -/// \note CAN BE CHANGED: \b os_mailQ_cb is implementation specific in every CMSIS-RTOS. -typedef struct os_mailQ_cb *osMailQId; - - -/// Thread Definition structure contains startup information of a thread. -/// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS. -typedef struct os_thread_def { - os_pthread pthread; ///< start address of thread function - osPriority tpriority; ///< initial thread priority - uint32_t stacksize; ///< stack size requirements in bytes - unsigned char *stack_pointer; ///< pointer to the stack memory block - struct OS_TCB tcb; -} osThreadDef_t; - -/// Timer Definition structure contains timer parameters. -/// \note CAN BE CHANGED: \b os_timer_def is implementation specific in every CMSIS-RTOS. -typedef struct os_timer_def { - os_ptimer ptimer; ///< start address of a timer function - void *timer; ///< pointer to internal data -} osTimerDef_t; - -/// Mutex Definition structure contains setup information for a mutex. -/// \note CAN BE CHANGED: \b os_mutex_def is implementation specific in every CMSIS-RTOS. -typedef struct os_mutex_def { - void *mutex; ///< pointer to internal data -} osMutexDef_t; - -/// Semaphore Definition structure contains setup information for a semaphore. -/// \note CAN BE CHANGED: \b os_semaphore_def is implementation specific in every CMSIS-RTOS. -typedef struct os_semaphore_def { - void *semaphore; ///< pointer to internal data -} osSemaphoreDef_t; - -/// Definition structure for memory block allocation. -/// \note CAN BE CHANGED: \b os_pool_def is implementation specific in every CMSIS-RTOS. -typedef struct os_pool_def { - uint32_t pool_sz; ///< number of items (elements) in the pool - uint32_t item_sz; ///< size of an item - void *pool; ///< pointer to memory for pool -} osPoolDef_t; - -/// Definition structure for message queue. -/// \note CAN BE CHANGED: \b os_messageQ_def is implementation specific in every CMSIS-RTOS. -typedef struct os_messageQ_def { - uint32_t queue_sz; ///< number of elements in the queue - void *pool; ///< memory array for messages -} osMessageQDef_t; - -/// Definition structure for mail queue. -/// \note CAN BE CHANGED: \b os_mailQ_def is implementation specific in every CMSIS-RTOS. -typedef struct os_mailQ_def { - uint32_t queue_sz; ///< number of elements in the queue - uint32_t item_sz; ///< size of an item - void *pool; ///< memory array for mail -} osMailQDef_t; - -/// Event structure contains detailed information about an event. -/// \note MUST REMAIN UNCHANGED: \b os_event shall be consistent in every CMSIS-RTOS. -/// However the struct may be extended at the end. -typedef struct { - osStatus status; ///< status code: event or error information - union { - uint32_t v; ///< message as 32-bit value - void *p; ///< message or mail as void pointer - int32_t signals; ///< signal flags - } value; ///< event value - union { - osMailQId mail_id; ///< mail id obtained by \ref osMailCreate - osMessageQId message_id; ///< message id obtained by \ref osMessageCreate - } def; ///< event definition -} osEvent; - - -// ==== Kernel Control Functions ==== - -/// Initialize the RTOS Kernel for creating objects. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osKernelInitialize shall be consistent in every CMSIS-RTOS. -osStatus osKernelInitialize (void); - -/// Start the RTOS Kernel. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osKernelStart shall be consistent in every CMSIS-RTOS. -osStatus osKernelStart (void); - -/// Check if the RTOS kernel is already started. -/// \note MUST REMAIN UNCHANGED: \b osKernelRunning shall be consistent in every CMSIS-RTOS. -/// \return 0 RTOS is not started, 1 RTOS is started. -int32_t osKernelRunning(void); - - -// ==== Thread Management ==== - -/// Create a Thread Definition with function, priority, and stack requirements. -/// \param name name of the thread function. -/// \param priority initial priority of the thread function. -/// \param stacksz stack size (in bytes) requirements for the thread function. -/// \note CAN BE CHANGED: The parameters to \b osThreadDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osThreadDef(name, priority, stacksz) \ -extern osThreadDef_t os_thread_def_##name -#else // define the object -#define osThreadDef(name, priority, stacksz) \ -unsigned char os_thread_def_stack_##name [stacksz]; \ -osThreadDef_t os_thread_def_##name = \ -{ (name), (priority), (stacksz), (os_thread_def_stack_##name)} -#endif - -/// Access a Thread definition. -/// \param name name of the thread definition object. -/// \note CAN BE CHANGED: The parameter to \b osThread shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osThread(name) \ -&os_thread_def_##name - -/// Create a thread and add it to Active Threads and set it to state READY. -/// \param[in] thread_def thread definition referenced with \ref osThread. -/// \param[in] argument pointer that is passed to the thread function as start argument. -/// \return thread ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osThreadCreate shall be consistent in every CMSIS-RTOS. -osThreadId osThreadCreate (osThreadDef_t *thread_def, void *argument); - -/// Return the thread ID of the current running thread. -/// \return thread ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osThreadGetId shall be consistent in every CMSIS-RTOS. -osThreadId osThreadGetId (void); - -/// Terminate execution of a thread and remove it from Active Threads. -/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osThreadTerminate shall be consistent in every CMSIS-RTOS. -osStatus osThreadTerminate (osThreadId thread_id); - -/// Pass control to next thread that is in state \b READY. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osThreadYield shall be consistent in every CMSIS-RTOS. -osStatus osThreadYield (void); - -/// Change priority of an active thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. -/// \param[in] priority new priority value for the thread function. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osThreadSetPriority shall be consistent in every CMSIS-RTOS. -osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority); - -/// Get current priority of an active thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. -/// \return current priority value of the thread function. -/// \note MUST REMAIN UNCHANGED: \b osThreadGetPriority shall be consistent in every CMSIS-RTOS. -osPriority osThreadGetPriority (osThreadId thread_id); - - -// ==== Generic Wait Functions ==== - -/// Wait for Timeout (Time Delay). -/// \param[in] millisec time delay value -/// \return status code that indicates the execution status of the function. -osStatus osDelay (uint32_t millisec); - -#if (defined (osFeature_Wait) && (osFeature_Wait != 0)) // Generic Wait available - -/// Wait for Signal, Message, Mail, or Timeout. -/// \param[in] millisec timeout value or 0 in case of no time-out -/// \return event that contains signal, message, or mail information or error code. -/// \note MUST REMAIN UNCHANGED: \b osWait shall be consistent in every CMSIS-RTOS. -os_InRegs osEvent osWait (uint32_t millisec); - -#endif // Generic Wait available - - -// ==== Timer Management Functions ==== -/// Define a Timer object. -/// \param name name of the timer object. -/// \param function name of the timer call back function. -/// \note CAN BE CHANGED: The parameter to \b osTimerDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osTimerDef(name, function) \ -extern osTimerDef_t os_timer_def_##name -#else // define the object -#define osTimerDef(name, function) \ -uint32_t os_timer_cb_##name[5]; \ -osTimerDef_t os_timer_def_##name = \ -{ (function), (os_timer_cb_##name) } -#endif - -/// Access a Timer definition. -/// \param name name of the timer object. -/// \note CAN BE CHANGED: The parameter to \b osTimer shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osTimer(name) \ -&os_timer_def_##name - -/// Create a timer. -/// \param[in] timer_def timer object referenced with \ref osTimer. -/// \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior. -/// \param[in] argument argument to the timer call back function. -/// \return timer ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osTimerCreate shall be consistent in every CMSIS-RTOS. -osTimerId osTimerCreate (osTimerDef_t *timer_def, os_timer_type type, void *argument); - -/// Start or restart a timer. -/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. -/// \param[in] millisec time delay value of the timer. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osTimerStart shall be consistent in every CMSIS-RTOS. -osStatus osTimerStart (osTimerId timer_id, uint32_t millisec); - -/// Stop the timer. -/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osTimerStop shall be consistent in every CMSIS-RTOS. -osStatus osTimerStop (osTimerId timer_id); - -/// Delete a timer that was created by \ref osTimerCreate. -/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osTimerDelete shall be consistent in every CMSIS-RTOS. -osStatus osTimerDelete (osTimerId timer_id); - - -// ==== Signal Management ==== - -/// Set the specified Signal Flags of an active thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. -/// \param[in] signals specifies the signal flags of the thread that should be set. -/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. -/// \note MUST REMAIN UNCHANGED: \b osSignalSet shall be consistent in every CMSIS-RTOS. -int32_t osSignalSet (osThreadId thread_id, int32_t signals); - -/// Clear the specified Signal Flags of an active thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. -/// \param[in] signals specifies the signal flags of the thread that shall be cleared. -/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. -/// \note MUST REMAIN UNCHANGED: \b osSignalClear shall be consistent in every CMSIS-RTOS. -int32_t osSignalClear (osThreadId thread_id, int32_t signals); - -/// Get Signal Flags status of an active thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. -/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. -/// \note MUST REMAIN UNCHANGED: \b osSignalGet shall be consistent in every CMSIS-RTOS. -int32_t osSignalGet (osThreadId thread_id); - -/// Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread. -/// \param[in] signals wait until all specified signal flags set or 0 for any single signal flag. -/// \param[in] millisec timeout value or 0 in case of no time-out. -/// \return event flag information or error code. -/// \note MUST REMAIN UNCHANGED: \b osSignalWait shall be consistent in every CMSIS-RTOS. -os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec); - - -// ==== Mutex Management ==== - -/// Define a Mutex. -/// \param name name of the mutex object. -/// \note CAN BE CHANGED: The parameter to \b osMutexDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osMutexDef(name) \ -extern osMutexDef_t os_mutex_def_##name -#else // define the object -#define osMutexDef(name) \ -uint32_t os_mutex_cb_##name[3]; \ -osMutexDef_t os_mutex_def_##name = { (os_mutex_cb_##name) } -#endif - -/// Access a Mutex definition. -/// \param name name of the mutex object. -/// \note CAN BE CHANGED: The parameter to \b osMutex shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osMutex(name) \ -&os_mutex_def_##name - -/// Create and Initialize a Mutex object. -/// \param[in] mutex_def mutex definition referenced with \ref osMutex. -/// \return mutex ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osMutexCreate shall be consistent in every CMSIS-RTOS. -osMutexId osMutexCreate (osMutexDef_t *mutex_def); - -/// Wait until a Mutex becomes available. -/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. -/// \param[in] millisec timeout value or 0 in case of no time-out. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMutexWait shall be consistent in every CMSIS-RTOS. -osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec); - -/// Release a Mutex that was obtained by \ref osMutexWait. -/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMutexRelease shall be consistent in every CMSIS-RTOS. -osStatus osMutexRelease (osMutexId mutex_id); - -/// Delete a Mutex that was created by \ref osMutexCreate. -/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMutexDelete shall be consistent in every CMSIS-RTOS. -osStatus osMutexDelete (osMutexId mutex_id); - - -// ==== Semaphore Management Functions ==== - -#if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0)) // Semaphore available - -/// Define a Semaphore object. -/// \param name name of the semaphore object. -/// \note CAN BE CHANGED: The parameter to \b osSemaphoreDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osSemaphoreDef(name) \ -extern osSemaphoreDef_t os_semaphore_def_##name -#else // define the object -#define osSemaphoreDef(name) \ -uint32_t os_semaphore_cb_##name[2]; \ -osSemaphoreDef_t os_semaphore_def_##name = { (os_semaphore_cb_##name) } -#endif - -/// Access a Semaphore definition. -/// \param name name of the semaphore object. -/// \note CAN BE CHANGED: The parameter to \b osSemaphore shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osSemaphore(name) \ -&os_semaphore_def_##name - -/// Create and Initialize a Semaphore object used for managing resources. -/// \param[in] semaphore_def semaphore definition referenced with \ref osSemaphore. -/// \param[in] count number of available resources. -/// \return semaphore ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osSemaphoreCreate shall be consistent in every CMSIS-RTOS. -osSemaphoreId osSemaphoreCreate (osSemaphoreDef_t *semaphore_def, int32_t count); - -/// Wait until a Semaphore token becomes available. -/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. -/// \param[in] millisec timeout value or 0 in case of no time-out. -/// \return number of available tokens, or -1 in case of incorrect parameters. -/// \note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS. -int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec); - -/// Release a Semaphore token. -/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osSemaphoreRelease shall be consistent in every CMSIS-RTOS. -osStatus osSemaphoreRelease (osSemaphoreId semaphore_id); - -/// Delete a Semaphore that was created by \ref osSemaphoreCreate. -/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osSemaphoreDelete shall be consistent in every CMSIS-RTOS. -osStatus osSemaphoreDelete (osSemaphoreId semaphore_id); - -#endif // Semaphore available - - -// ==== Memory Pool Management Functions ==== - -#if (defined (osFeature_Pool) && (osFeature_Pool != 0)) // Memory Pool Management available - -/// \brief Define a Memory Pool. -/// \param name name of the memory pool. -/// \param no maximum number of blocks (objects) in the memory pool. -/// \param type data type of a single block (object). -/// \note CAN BE CHANGED: The parameter to \b osPoolDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osPoolDef(name, no, type) \ -extern osPoolDef_t os_pool_def_##name -#else // define the object -#define osPoolDef(name, no, type) \ -uint32_t os_pool_m_##name[3+((sizeof(type)+3)/4)*(no)]; \ -osPoolDef_t os_pool_def_##name = \ -{ (no), sizeof(type), (os_pool_m_##name) } -#endif - -/// \brief Access a Memory Pool definition. -/// \param name name of the memory pool -/// \note CAN BE CHANGED: The parameter to \b osPool shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osPool(name) \ -&os_pool_def_##name - -/// Create and Initialize a memory pool. -/// \param[in] pool_def memory pool definition referenced with \ref osPool. -/// \return memory pool ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osPoolCreate shall be consistent in every CMSIS-RTOS. -osPoolId osPoolCreate (osPoolDef_t *pool_def); - -/// Allocate a memory block from a memory pool. -/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. -/// \return address of the allocated memory block or NULL in case of no memory available. -/// \note MUST REMAIN UNCHANGED: \b osPoolAlloc shall be consistent in every CMSIS-RTOS. -void *osPoolAlloc (osPoolId pool_id); - -/// Allocate a memory block from a memory pool and set memory block to zero. -/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. -/// \return address of the allocated memory block or NULL in case of no memory available. -/// \note MUST REMAIN UNCHANGED: \b osPoolCAlloc shall be consistent in every CMSIS-RTOS. -void *osPoolCAlloc (osPoolId pool_id); - -/// Return an allocated memory block back to a specific memory pool. -/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. -/// \param[in] block address of the allocated memory block that is returned to the memory pool. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osPoolFree shall be consistent in every CMSIS-RTOS. -osStatus osPoolFree (osPoolId pool_id, void *block); - -#endif // Memory Pool Management available - - -// ==== Message Queue Management Functions ==== - -#if (defined (osFeature_MessageQ) && (osFeature_MessageQ != 0)) // Message Queues available - -/// \brief Create a Message Queue Definition. -/// \param name name of the queue. -/// \param queue_sz maximum number of messages in the queue. -/// \param type data type of a single message element (for debugger). -/// \note CAN BE CHANGED: The parameter to \b osMessageQDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osMessageQDef(name, queue_sz, type) \ -extern osMessageQDef_t os_messageQ_def_##name -#else // define the object -#define osMessageQDef(name, queue_sz, type) \ -uint32_t os_messageQ_q_##name[4+(queue_sz)]; \ -osMessageQDef_t os_messageQ_def_##name = \ -{ (queue_sz), (os_messageQ_q_##name) } -#endif - -/// \brief Access a Message Queue Definition. -/// \param name name of the queue -/// \note CAN BE CHANGED: The parameter to \b osMessageQ shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osMessageQ(name) \ -&os_messageQ_def_##name - -/// Create and Initialize a Message Queue. -/// \param[in] queue_def queue definition referenced with \ref osMessageQ. -/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. -/// \return message queue ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osMessageCreate shall be consistent in every CMSIS-RTOS. -osMessageQId osMessageCreate (osMessageQDef_t *queue_def, osThreadId thread_id); - -/// Put a Message to a Queue. -/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. -/// \param[in] info message information. -/// \param[in] millisec timeout value or 0 in case of no time-out. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMessagePut shall be consistent in every CMSIS-RTOS. -osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec); - -/// Get a Message or Wait for a Message from a Queue. -/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. -/// \param[in] millisec timeout value or 0 in case of no time-out. -/// \return event information that includes status code. -/// \note MUST REMAIN UNCHANGED: \b osMessageGet shall be consistent in every CMSIS-RTOS. -os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec); - -#endif // Message Queues available - - -// ==== Mail Queue Management Functions ==== - -#if (defined (osFeature_MailQ) && (osFeature_MailQ != 0)) // Mail Queues available - -/// \brief Create a Mail Queue Definition. -/// \param name name of the queue -/// \param queue_sz maximum number of messages in queue -/// \param type data type of a single message element -/// \note CAN BE CHANGED: The parameter to \b osMailQDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osMailQDef(name, queue_sz, type) \ -extern osMailQDef_t os_mailQ_def_##name -#else // define the object -#define osMailQDef(name, queue_sz, type) \ -uint32_t os_mailQ_q_##name[4+(queue_sz)]; \ -uint32_t os_mailQ_m_##name[3+((sizeof(type)+3)/4)*(queue_sz)]; \ -void * os_mailQ_p_##name[2] = { (os_mailQ_q_##name), os_mailQ_m_##name }; \ -osMailQDef_t os_mailQ_def_##name = \ -{ (queue_sz), sizeof(type), (os_mailQ_p_##name) } -#endif - -/// \brief Access a Mail Queue Definition. -/// \param name name of the queue -/// \note CAN BE CHANGED: The parameter to \b osMailQ shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osMailQ(name) \ -&os_mailQ_def_##name - -/// Create and Initialize mail queue. -/// \param[in] queue_def reference to the mail queue definition obtain with \ref osMailQ -/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. -/// \return mail queue ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osMailCreate shall be consistent in every CMSIS-RTOS. -osMailQId osMailCreate (osMailQDef_t *queue_def, osThreadId thread_id); - -/// Allocate a memory block from a mail. -/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. -/// \param[in] millisec timeout value or 0 in case of no time-out -/// \return pointer to memory block that can be filled with mail or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osMailAlloc shall be consistent in every CMSIS-RTOS. -void *osMailAlloc (osMailQId queue_id, uint32_t millisec); - -/// Allocate a memory block from a mail and set memory block to zero. -/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. -/// \param[in] millisec timeout value or 0 in case of no time-out -/// \return pointer to memory block that can be filled with mail or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osMailCAlloc shall be consistent in every CMSIS-RTOS. -void *osMailCAlloc (osMailQId queue_id, uint32_t millisec); - -/// Put a mail to a queue. -/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. -/// \param[in] mail memory block previously allocated with \ref osMailAlloc or \ref osMailCAlloc. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMailPut shall be consistent in every CMSIS-RTOS. -osStatus osMailPut (osMailQId queue_id, void *mail); - -/// Get a mail from a queue. -/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. -/// \param[in] millisec timeout value or 0 in case of no time-out -/// \return event that contains mail information or error code. -/// \note MUST REMAIN UNCHANGED: \b osMailGet shall be consistent in every CMSIS-RTOS. -os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec); - -/// Free a memory block from a mail. -/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. -/// \param[in] mail pointer to the memory block that was obtained with \ref osMailGet. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMailFree shall be consistent in every CMSIS-RTOS. -osStatus osMailFree (osMailQId queue_id, void *mail); - -#endif // Mail Queues available - - -#ifdef __cplusplus -} -#endif - -#endif // _CMSIS_OS_H
--- a/rtx/os_tcb.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -#ifndef OS_TCB_H -#define OS_TCB_H - -/* Types */ -typedef char S8; -typedef unsigned char U8; -typedef short S16; -typedef unsigned short U16; -typedef int S32; -typedef unsigned int U32; -typedef long long S64; -typedef unsigned long long U64; -typedef unsigned char BIT; -typedef unsigned int BOOL; -typedef void (*FUNCP)(void); - -typedef struct OS_TCB { - /* General part: identical for all implementations. */ - U8 cb_type; /* Control Block Type */ - U8 state; /* Task state */ - U8 prio; /* Execution priority */ - U8 task_id; /* Task ID value for optimized TCB access */ - struct OS_TCB *p_lnk; /* Link pointer for ready/sem. wait list */ - struct OS_TCB *p_rlnk; /* Link pointer for sem./mbx lst backwards */ - struct OS_TCB *p_dlnk; /* Link pointer for delay list */ - struct OS_TCB *p_blnk; /* Link pointer for delay list backwards */ - U16 delta_time; /* Time until time out */ - U16 interval_time; /* Time interval for periodic waits */ - U16 events; /* Event flags */ - U16 waits; /* Wait flags */ - void **msg; /* Direct message passing when task waits */ - - /* Hardware dependant part: specific for CM processor */ - U8 stack_frame; /* Stack frame: 0=Basic, 1=Extended */ - U8 reserved; - U16 priv_stack; /* Private stack size in bytes */ - U32 tsk_stack; /* Current task Stack pointer (R13) */ - U32 *stack; /* Pointer to Task Stack memory block */ - - /* Library dependant part */ -#if defined (__CC_ARM) && !defined (__MICROLIB) - /* A memory space for arm standard library. */ - U32 std_libspace[96/4]; -#endif - - /* Task entry point used for uVision debugger */ - FUNCP ptask; /* Task entry address */ -} *P_TCB; - -#endif
--- a/rtx/rt_CMSIS.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1920 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: rt_CMSIS.c - * Purpose: CMSIS RTOS API - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#define __CMSIS_GENERIC - -#if defined (__CORTEX_M4) || defined (__CORTEX_M4F) - #include "core_cm4.h" -#elif defined (__CORTEX_M3) - #include "core_cm3.h" -#elif defined (__CORTEX_M0) - #include "core_cm0.h" -#elif defined (__CORTEX_M0PLUS) - #include "core_cm0plus.h" -#else - #error "Missing __CORTEX_Mx definition" -#endif - -#include "rt_TypeDef.h" -#include "RTX_Conf.h" -#include "rt_System.h" -#include "rt_Task.h" -#include "rt_Event.h" -#include "rt_List.h" -#include "rt_Time.h" -#include "rt_Mutex.h" -#include "rt_Semaphore.h" -#include "rt_Mailbox.h" -#include "rt_MemBox.h" -#include "rt_HAL_CM.h" - -#define os_thread_cb OS_TCB - -#include "cmsis_os.h" - -#if (osFeature_Signals != 16) -#error Invalid "osFeature_Signals" value! -#endif -#if (osFeature_Semaphore > 65535) -#error Invalid "osFeature_Semaphore" value! -#endif -#if (osFeature_Wait != 0) -#error osWait not supported! -#endif - - -// ==== Enumeration, structures, defines ==== - -// Service Calls defines - -#if defined (__CC_ARM) /* ARM Compiler */ - -#define __NO_RETURN __declspec(noreturn) - -#define osEvent_type osEvent -#define osEvent_ret_status ret -#define osEvent_ret_value ret -#define osEvent_ret_msg ret -#define osEvent_ret_mail ret - -#define osCallback_type osCallback -#define osCallback_ret ret - -#define SVC_0_1(f,t,...) \ -__svc_indirect(0) t _##f (t(*)()); \ - t f (void); \ -__attribute__((always_inline)) \ -static __inline t __##f (void) { \ - return _##f(f); \ -} - -#define SVC_1_1(f,t,t1,...) \ -__svc_indirect(0) t _##f (t(*)(t1),t1); \ - t f (t1 a1); \ -__attribute__((always_inline)) \ -static __inline t __##f (t1 a1) { \ - return _##f(f,a1); \ -} - -#define SVC_2_1(f,t,t1,t2,...) \ -__svc_indirect(0) t _##f (t(*)(t1,t2),t1,t2); \ - t f (t1 a1, t2 a2); \ -__attribute__((always_inline)) \ -static __inline t __##f (t1 a1, t2 a2) { \ - return _##f(f,a1,a2); \ -} - -#define SVC_3_1(f,t,t1,t2,t3,...) \ -__svc_indirect(0) t _##f (t(*)(t1,t2,t3),t1,t2,t3); \ - t f (t1 a1, t2 a2, t3 a3); \ -__attribute__((always_inline)) \ -static __inline t __##f (t1 a1, t2 a2, t3 a3) { \ - return _##f(f,a1,a2,a3); \ -} - -#define SVC_4_1(f,t,t1,t2,t3,t4,...) \ -__svc_indirect(0) t _##f (t(*)(t1,t2,t3,t4),t1,t2,t3,t4); \ - t f (t1 a1, t2 a2, t3 a3, t4 a4); \ -__attribute__((always_inline)) \ -static __inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ - return _##f(f,a1,a2,a3,a4); \ -} - -#define SVC_1_2 SVC_1_1 -#define SVC_1_3 SVC_1_1 -#define SVC_2_3 SVC_2_1 - -#elif defined (__GNUC__) /* GNU Compiler */ - -#define __NO_RETURN __attribute__((noreturn)) - -typedef uint32_t __attribute__((vector_size(8))) ret64; -typedef uint32_t __attribute__((vector_size(16))) ret128; - -#define RET_pointer __r0 -#define RET_int32_t __r0 -#define RET_osStatus __r0 -#define RET_osPriority __r0 -#define RET_osEvent {(osStatus)__r0, {(uint32_t)__r1}, {(void *)__r2}} -#define RET_osCallback {(void *)__r0, (void *)__r1} - -#define osEvent_type ret128 -#define osEvent_ret_status (ret128){ret.status} -#define osEvent_ret_value (ret128){ret.status, ret.value.v} -#define osEvent_ret_msg (ret128){ret.status, ret.value.v, (uint32_t)ret.def.message_id} -#define osEvent_ret_mail (ret128){ret.status, ret.value.v, (uint32_t)ret.def.mail_id} - -#define osCallback_type ret64 -#define osCallback_ret (ret64) {(uint32_t)ret.fp, (uint32_t)ret.arg} - -#define SVC_ArgN(n) \ - register int __r##n __asm("r"#n); - -#define SVC_ArgR(n,t,a) \ - register t __r##n __asm("r"#n) = a; - -#define SVC_Arg0() \ - SVC_ArgN(0) \ - SVC_ArgN(1) \ - SVC_ArgN(2) \ - SVC_ArgN(3) - -#define SVC_Arg1(t1) \ - SVC_ArgR(0,t1,a1) \ - SVC_ArgN(1) \ - SVC_ArgN(2) \ - SVC_ArgN(3) - -#define SVC_Arg2(t1,t2) \ - SVC_ArgR(0,t1,a1) \ - SVC_ArgR(1,t2,a2) \ - SVC_ArgN(2) \ - SVC_ArgN(3) - -#define SVC_Arg3(t1,t2,t3) \ - SVC_ArgR(0,t1,a1) \ - SVC_ArgR(1,t2,a2) \ - SVC_ArgR(2,t3,a3) \ - SVC_ArgN(3) - -#define SVC_Arg4(t1,t2,t3,t4) \ - SVC_ArgR(0,t1,a1) \ - SVC_ArgR(1,t2,a2) \ - SVC_ArgR(2,t3,a3) \ - SVC_ArgR(3,t4,a4) - -#if (defined (__CORTEX_M0)) || defined (__CORTEX_M0PLUS) -#define SVC_Call(f) \ - __asm volatile \ - ( \ - "ldr r7,="#f"\n\t" \ - "mov r12,r7\n\t" \ - "svc 0" \ - : "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3) \ - : "r" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) \ - : "r7", "r12", "lr", "cc" \ - ); -#else -#define SVC_Call(f) \ - __asm volatile \ - ( \ - "ldr r12,="#f"\n\t" \ - "svc 0" \ - : "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3) \ - : "r" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) \ - : "r12", "lr", "cc" \ - ); -#endif - -#define SVC_0_1(f,t,rv) \ -__attribute__((always_inline)) \ -static inline t __##f (void) { \ - SVC_Arg0(); \ - SVC_Call(f); \ - return (t) rv; \ -} - -#define SVC_1_1(f,t,t1,rv) \ -__attribute__((always_inline)) \ -static inline t __##f (t1 a1) { \ - SVC_Arg1(t1); \ - SVC_Call(f); \ - return (t) rv; \ -} - -#define SVC_2_1(f,t,t1,t2,rv) \ -__attribute__((always_inline)) \ -static inline t __##f (t1 a1, t2 a2) { \ - SVC_Arg2(t1,t2); \ - SVC_Call(f); \ - return (t) rv; \ -} - -#define SVC_3_1(f,t,t1,t2,t3,rv) \ -__attribute__((always_inline)) \ -static inline t __##f (t1 a1, t2 a2, t3 a3) { \ - SVC_Arg3(t1,t2,t3); \ - SVC_Call(f); \ - return (t) rv; \ -} - -#define SVC_4_1(f,t,t1,t2,t3,t4,rv) \ -__attribute__((always_inline)) \ -static inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ - SVC_Arg4(t1,t2,t3,t4); \ - SVC_Call(f); \ - return (t) rv; \ -} - -#define SVC_1_2 SVC_1_1 -#define SVC_1_3 SVC_1_1 -#define SVC_2_3 SVC_2_1 - -#elif defined (__ICCARM__) /* IAR Compiler */ - -#define __NO_RETURN __noreturn - -#define RET_osEvent "=r"(ret.status), "=r"(ret.value), "=r"(ret.def) -#define RET_osCallback "=r"(ret.fp), "=r"(ret.arg) - -#define osEvent_type osEvent -#define osEvent_ret_status ret -#define osEvent_ret_value ret -#define osEvent_ret_msg ret -#define osEvent_ret_mail ret - -#define osCallback_type uint64_t -#define osCallback_ret ((uint64_t)ret.fp | ((uint64_t)ret.arg)<<32) - -#define SVC_Setup(f) \ - __asm( \ - "mov r12,%0\n" \ - :: "r"(&f): "r12" \ - ); - -#define SVC_Ret3() \ - __asm( \ - "ldr r0,[sp,#0]\n" \ - "ldr r1,[sp,#4]\n" \ - "ldr r2,[sp,#8]\n" \ - ); - -#define SVC_0_1(f,t,...) \ -t f (void); \ -_Pragma("swi_number=0") __swi t _##f (void); \ -static inline t __##f (void) { \ - SVC_Setup(f); \ - return _##f(); \ -} - -#define SVC_1_1(f,t,t1,...) \ -t f (t1 a1); \ -_Pragma("swi_number=0") __swi t _##f (t1 a1); \ -static inline t __##f (t1 a1) { \ - SVC_Setup(f); \ - return _##f(a1); \ -} - -#define SVC_2_1(f,t,t1,t2,...) \ -t f (t1 a1, t2 a2); \ -_Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2); \ -static inline t __##f (t1 a1, t2 a2) { \ - SVC_Setup(f); \ - return _##f(a1,a2); \ -} - -#define SVC_3_1(f,t,t1,t2,t3,...) \ -t f (t1 a1, t2 a2, t3 a3); \ -_Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2, t3 a3); \ -static inline t __##f (t1 a1, t2 a2, t3 a3) { \ - SVC_Setup(f); \ - return _##f(a1,a2,a3); \ -} - -#define SVC_4_1(f,t,t1,t2,t3,t4,...) \ -t f (t1 a1, t2 a2, t3 a3, t4 a4); \ -_Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2, t3 a3, t4 a4); \ -static inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ - SVC_Setup(f); \ - return _##f(a1,a2,a3,a4); \ -} - -#define SVC_1_2(f,t,t1,rr) \ -uint64_t f (t1 a1); \ -_Pragma("swi_number=0") __swi uint64_t _##f (t1 a1); \ -static inline t __##f (t1 a1) { \ - t ret; \ - SVC_Setup(f); \ - _##f(a1); \ - __asm("" : rr : :); \ - return ret; \ -} - -#define SVC_1_3(f,t,t1,rr) \ -t f (t1 a1); \ -void f##_ (t1 a1) { \ - f(a1); \ - SVC_Ret3(); \ -} \ -_Pragma("swi_number=0") __swi void _##f (t1 a1); \ -static inline t __##f (t1 a1) { \ - t ret; \ - SVC_Setup(f##_); \ - _##f(a1); \ - __asm("" : rr : :); \ - return ret; \ -} - -#define SVC_2_3(f,t,t1,t2,rr) \ -t f (t1 a1, t2 a2); \ -void f##_ (t1 a1, t2 a2) { \ - f(a1,a2); \ - SVC_Ret3(); \ -} \ -_Pragma("swi_number=0") __swi void _##f (t1 a1, t2 a2); \ -static inline t __##f (t1 a1, t2 a2) { \ - t ret; \ - SVC_Setup(f##_); \ - _##f(a1,a2); \ - __asm("" : rr : :); \ - return ret; \ -} - -#endif - - -// Callback structure -typedef struct { - void *fp; // Function pointer - void *arg; // Function argument -} osCallback; - - -// OS Section definitions -#ifdef OS_SECTIONS_LINK_INFO -extern const uint32_t os_section_id$$Base; -extern const uint32_t os_section_id$$Limit; -#endif - -// OS Timers external resources -extern osThreadDef_t os_thread_def_osTimerThread; -extern osThreadId osThreadId_osTimerThread; -extern osMessageQDef_t os_messageQ_def_osTimerMessageQ; -extern osMessageQId osMessageQId_osTimerMessageQ; - - -// ==== Helper Functions ==== - -/// Convert timeout in millisec to system ticks -static uint32_t rt_ms2tick (uint32_t millisec) { - uint32_t tick; - - if (millisec == osWaitForever) return 0xFFFF; // Indefinite timeout - if (millisec > 4000000) return 0xFFFE; // Max ticks supported - - tick = ((1000 * millisec) + os_clockrate - 1) / os_clockrate; - if (tick > 0xFFFE) return 0xFFFE; - - return tick; -} - -/// Convert Thread ID to TCB pointer -static P_TCB rt_tid2ptcb (osThreadId thread_id) { - P_TCB ptcb; - - if (thread_id == NULL) return NULL; - - if ((uint32_t)thread_id & 3) return NULL; - -#ifdef OS_SECTIONS_LINK_INFO - if ((os_section_id$$Base != 0) && (os_section_id$$Limit != 0)) { - if (thread_id < (osThreadId)os_section_id$$Base) return NULL; - if (thread_id >= (osThreadId)os_section_id$$Limit) return NULL; - } -#endif - - ptcb = thread_id; - - if (ptcb->cb_type != TCB) return NULL; - - return ptcb; -} - -/// Convert ID pointer to Object pointer -static void *rt_id2obj (void *id) { - - if ((uint32_t)id & 3) return NULL; - -#ifdef OS_SECTIONS_LINK_INFO - if ((os_section_id$$Base != 0) && (os_section_id$$Limit != 0)) { - if (id < (void *)os_section_id$$Base) return NULL; - if (id >= (void *)os_section_id$$Limit) return NULL; - } -#endif - - return id; -} - - -// ==== Kernel Control ==== - -uint8_t os_initialized; // Kernel Initialized flag -uint8_t os_running; // Kernel Running flag - -// Kernel Control Service Calls declarations -SVC_0_1(svcKernelInitialize, osStatus, RET_osStatus) -SVC_0_1(svcKernelStart, osStatus, RET_osStatus) -SVC_0_1(svcKernelRunning, int32_t, RET_int32_t) - -extern void sysThreadError (osStatus status); -osThreadId svcThreadCreate (osThreadDef_t *thread_def, void *argument); -osMessageQId svcMessageCreate (osMessageQDef_t *queue_def, osThreadId thread_id); - -// Kernel Control Service Calls - -/// Initialize the RTOS Kernel for creating objects -osStatus svcKernelInitialize (void) { - if (os_initialized) return osOK; - - rt_sys_init(); // RTX System Initialization - os_tsk.run->prio = 255; // Highest priority - - sysThreadError(osOK); - - os_initialized = 1; - - return osOK; -} - -/// Start the RTOS Kernel -osStatus svcKernelStart (void) { - - if (os_running) return osOK; - - // Create OS Timers resources (Message Queue & Thread) - osMessageQId_osTimerMessageQ = svcMessageCreate (&os_messageQ_def_osTimerMessageQ, NULL); - osThreadId_osTimerThread = svcThreadCreate(&os_thread_def_osTimerThread, NULL); - - rt_tsk_prio(0, 0); // Lowest priority - __set_PSP(os_tsk.run->tsk_stack + 8*4); // New context - os_tsk.run = NULL; // Force context switch - - rt_sys_start(); - - os_running = 1; - - return osOK; -} - -/// Check if the RTOS kernel is already started -int32_t svcKernelRunning(void) { - return os_running; -} - -// Kernel Control Public API - -/// Initialize the RTOS Kernel for creating objects -osStatus osKernelInitialize (void) { - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR - if ((__get_CONTROL() & 1) == 0) { // Privileged mode - return svcKernelInitialize(); - } else { - return __svcKernelInitialize(); - } -} - -/// Start the RTOS Kernel -osStatus osKernelStart (void) { - uint32_t stack[8]; - - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR - switch (__get_CONTROL() & 0x03) { - case 0x00: // Privileged Thread mode & MSP - __set_PSP((uint32_t)(stack + 8)); // Initial PSP - if (os_flags & 1) { - __set_CONTROL(0x02); // Set Privileged Thread mode & PSP - } else { - __set_CONTROL(0x03); // Set Unprivileged Thread mode & PSP - } - __DSB(); - __ISB(); - break; - case 0x01: // Unprivileged Thread mode & MSP - return osErrorOS; - case 0x02: // Privileged Thread mode & PSP - if ((os_flags & 1) == 0) { // Unprivileged Thread mode requested - __set_CONTROL(0x03); // Set Unprivileged Thread mode & PSP - __DSB(); - __ISB(); - } - break; - case 0x03: // Unprivileged Thread mode & PSP - if (os_flags & 1) return osErrorOS; // Privileged Thread mode requested - break; - } - return __svcKernelStart(); -} - -/// Check if the RTOS kernel is already started -int32_t osKernelRunning(void) { - if ((__get_IPSR() != 0) || ((__get_CONTROL() & 1) == 0)) { - // in ISR or Privileged - return os_running; - } else { - return __svcKernelRunning(); - } -} - - -// ==== Thread Management ==== - -__NO_RETURN void osThreadExit (void); - -// Thread Service Calls declarations -SVC_2_1(svcThreadCreate, osThreadId, osThreadDef_t *, void *, RET_pointer) -SVC_0_1(svcThreadGetId, osThreadId, RET_pointer) -SVC_1_1(svcThreadTerminate, osStatus, osThreadId, RET_osStatus) -SVC_0_1(svcThreadYield, osStatus, RET_osStatus) -SVC_2_1(svcThreadSetPriority, osStatus, osThreadId, osPriority, RET_osStatus) -SVC_1_1(svcThreadGetPriority, osPriority, osThreadId, RET_osPriority) - -// Thread Service Calls -extern OS_TID rt_get_TID (void); -extern void rt_init_context (P_TCB p_TCB, U8 priority, FUNCP task_body); - -/// Create a thread and add it to Active Threads and set it to state READY -osThreadId svcThreadCreate (osThreadDef_t *thread_def, void *argument) { - P_TCB ptcb; - - if ((thread_def == NULL) || - (thread_def->pthread == NULL) || - (thread_def->tpriority < osPriorityIdle) || - (thread_def->tpriority > osPriorityRealtime) || - (thread_def->stacksize == 0) || - (thread_def->stack_pointer == NULL) ) { - sysThreadError(osErrorParameter); - return NULL; - } - - U8 priority = thread_def->tpriority - osPriorityIdle + 1; - P_TCB task_context = &thread_def->tcb; - - /* If "size != 0" use a private user provided stack. */ - task_context->stack = (U32*)thread_def->stack_pointer; - task_context->priv_stack = thread_def->stacksize; - /* Pass parameter 'argv' to 'rt_init_context' */ - task_context->msg = argument; - /* For 'size == 0' system allocates the user stack from the memory pool. */ - rt_init_context (task_context, priority, (FUNCP)thread_def->pthread); - - /* Find a free entry in 'os_active_TCB' table. */ - OS_TID tsk = rt_get_TID (); - os_active_TCB[tsk-1] = task_context; - task_context->task_id = tsk; - DBG_TASK_NOTIFY(task_context, __TRUE); - rt_dispatch (task_context); - - ptcb = (P_TCB)os_active_TCB[tsk - 1]; // TCB pointer - - *((uint32_t *)ptcb->tsk_stack + 13) = (uint32_t)osThreadExit; - - return ptcb; -} - -/// Return the thread ID of the current running thread -osThreadId svcThreadGetId (void) { - OS_TID tsk; - - tsk = rt_tsk_self(); - if (tsk == 0) return NULL; - return (P_TCB)os_active_TCB[tsk - 1]; -} - -/// Terminate execution of a thread and remove it from ActiveThreads -osStatus svcThreadTerminate (osThreadId thread_id) { - OS_RESULT res; - P_TCB ptcb; - - ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) return osErrorParameter; - - res = rt_tsk_delete(ptcb->task_id); // Delete task - - if (res == OS_R_NOK) return osErrorResource; // Delete task failed - - return osOK; -} - -/// Pass control to next thread that is in state READY -osStatus svcThreadYield (void) { - rt_tsk_pass(); // Pass control to next task - return osOK; -} - -/// Change priority of an active thread -osStatus svcThreadSetPriority (osThreadId thread_id, osPriority priority) { - OS_RESULT res; - P_TCB ptcb; - - ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) return osErrorParameter; - - if ((priority < osPriorityIdle) || (priority > osPriorityRealtime)) { - return osErrorValue; - } - - res = rt_tsk_prio( // Change task priority - ptcb->task_id, // Task ID - priority - osPriorityIdle + 1 // New task priority - ); - - if (res == OS_R_NOK) return osErrorResource; // Change task priority failed - - return osOK; -} - -/// Get current priority of an active thread -osPriority svcThreadGetPriority (osThreadId thread_id) { - P_TCB ptcb; - - ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) return osPriorityError; - - return (osPriority)(ptcb->prio - 1 + osPriorityIdle); -} - - -// Thread Public API - -/// Create a thread and add it to Active Threads and set it to state READY -osThreadId osThreadCreate (osThreadDef_t *thread_def, void *argument) { - if (__get_IPSR() != 0) return NULL; // Not allowed in ISR - if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) { - // Privileged and not running - return svcThreadCreate(thread_def, argument); - } else { - return __svcThreadCreate(thread_def, argument); - } -} - -/// Return the thread ID of the current running thread -osThreadId osThreadGetId (void) { - if (__get_IPSR() != 0) return NULL; // Not allowed in ISR - return __svcThreadGetId(); -} - -/// Terminate execution of a thread and remove it from ActiveThreads -osStatus osThreadTerminate (osThreadId thread_id) { - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR - return __svcThreadTerminate(thread_id); -} - -/// Pass control to next thread that is in state READY -osStatus osThreadYield (void) { - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR - return __svcThreadYield(); -} - -/// Change priority of an active thread -osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority) { - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR - return __svcThreadSetPriority(thread_id, priority); -} - -/// Get current priority of an active thread -osPriority osThreadGetPriority (osThreadId thread_id) { - if (__get_IPSR() != 0) return osPriorityError;// Not allowed in ISR - return __svcThreadGetPriority(thread_id); -} - -/// INTERNAL - Not Public -/// Auto Terminate Thread on exit (used implicitly when thread exists) -__NO_RETURN void osThreadExit (void) { - __svcThreadTerminate(__svcThreadGetId()); - for (;;); // Should never come here -} - - -// ==== Generic Wait Functions ==== - -// Generic Wait Service Calls declarations -SVC_1_1(svcDelay, osStatus, uint32_t, RET_osStatus) -#if osFeature_Wait != 0 -SVC_1_3(svcWait, os_InRegs osEvent, uint32_t, RET_osEvent) -#endif - -// Generic Wait Service Calls - -/// Wait for Timeout (Time Delay) -osStatus svcDelay (uint32_t millisec) { - if (millisec == 0) return osOK; - rt_dly_wait(rt_ms2tick(millisec)); - return osEventTimeout; -} - -/// Wait for Signal, Message, Mail, or Timeout -#if osFeature_Wait != 0 -os_InRegs osEvent_type svcWait (uint32_t millisec) { - osEvent ret; - - if (millisec == 0) { - ret.status = osOK; - return osEvent_ret_status; - } - - /* To Do: osEventSignal, osEventMessage, osEventMail */ - rt_dly_wait(rt_ms2tick(millisec)); - ret.status = osEventTimeout; - - return osEvent_ret_status; -} -#endif - - -// Generic Wait API - -/// Wait for Timeout (Time Delay) -osStatus osDelay (uint32_t millisec) { - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR - return __svcDelay(millisec); -} - -/// Wait for Signal, Message, Mail, or Timeout -os_InRegs osEvent osWait (uint32_t millisec) { - osEvent ret; - -#if osFeature_Wait == 0 - ret.status = osErrorOS; - return ret; -#else - if (__get_IPSR() != 0) { // Not allowed in ISR - ret.status = osErrorISR; - return ret; - } - return __svcWait(millisec); -#endif -} - - -// ==== Timer Management ==== - -// Timer definitions -#define osTimerInvalid 0 -#define osTimerStopped 1 -#define osTimerRunning 2 - -// Timer structures - -typedef struct os_timer_cb_ { // Timer Control Block - struct os_timer_cb_ *next; // Pointer to next active Timer - uint8_t state; // Timer State - uint8_t type; // Timer Type (Periodic/One-shot) - uint16_t reserved; // Reserved - uint16_t tcnt; // Timer Delay Count - uint16_t icnt; // Timer Initial Count - void *arg; // Timer Function Argument - osTimerDef_t *timer; // Pointer to Timer definition -} os_timer_cb; - -// Timer variables -os_timer_cb *os_timer_head; // Pointer to first active Timer - - -// Timer Helper Functions - -// Insert Timer into the list sorted by time -static void rt_timer_insert (os_timer_cb *pt, uint32_t tcnt) { - os_timer_cb *p, *prev; - - prev = NULL; - p = os_timer_head; - while (p != NULL) { - if (tcnt < p->tcnt) break; - tcnt -= p->tcnt; - prev = p; - p = p->next; - } - pt->next = p; - pt->tcnt = (uint16_t)tcnt; - if (p != NULL) { - p->tcnt -= pt->tcnt; - } - if (prev != NULL) { - prev->next = pt; - } else { - os_timer_head = pt; - } -} - -// Remove Timer from the list -static int rt_timer_remove (os_timer_cb *pt) { - os_timer_cb *p, *prev; - - prev = NULL; - p = os_timer_head; - while (p != NULL) { - if (p == pt) break; - prev = p; - p = p->next; - } - if (p == NULL) return -1; - if (prev != NULL) { - prev->next = pt->next; - } else { - os_timer_head = pt->next; - } - if (pt->next != NULL) { - pt->next->tcnt += pt->tcnt; - } - - return 0; -} - - -// Timer Service Calls declarations -SVC_3_1(svcTimerCreate, osTimerId, osTimerDef_t *, os_timer_type, void *, RET_pointer) -SVC_2_1(svcTimerStart, osStatus, osTimerId, uint32_t, RET_osStatus) -SVC_1_1(svcTimerStop, osStatus, osTimerId, RET_osStatus) -SVC_1_1(svcTimerDelete, osStatus, osTimerId, RET_osStatus) -SVC_1_2(svcTimerCall, os_InRegs osCallback, osTimerId, RET_osCallback) - -// Timer Management Service Calls - -/// Create timer -osTimerId svcTimerCreate (osTimerDef_t *timer_def, os_timer_type type, void *argument) { - os_timer_cb *pt; - - if ((timer_def == NULL) || (timer_def->ptimer == NULL)) { - sysThreadError(osErrorParameter); - return NULL; - } - - pt = timer_def->timer; - if (pt == NULL) { - sysThreadError(osErrorParameter); - return NULL; - } - - if ((type != osTimerOnce) && (type != osTimerPeriodic)) { - sysThreadError(osErrorValue); - return NULL; - } - - if (osThreadId_osTimerThread == NULL) { - sysThreadError(osErrorResource); - return NULL; - } - - if (pt->state != osTimerInvalid){ - sysThreadError(osErrorResource); - return NULL; - } - - pt->state = osTimerStopped; - pt->type = (uint8_t)type; - pt->arg = argument; - pt->timer = timer_def; - - return (osTimerId)pt; -} - -/// Start or restart timer -osStatus svcTimerStart (osTimerId timer_id, uint32_t millisec) { - os_timer_cb *pt; - uint32_t tcnt; - - pt = rt_id2obj(timer_id); - if (pt == NULL) return osErrorParameter; - - tcnt = rt_ms2tick(millisec); - if (tcnt == 0) return osErrorValue; - - switch (pt->state) { - case osTimerRunning: - if (rt_timer_remove(pt) != 0) { - return osErrorResource; - } - break; - case osTimerStopped: - pt->state = osTimerRunning; - pt->icnt = (uint16_t)tcnt; - break; - default: - return osErrorResource; - } - - rt_timer_insert(pt, tcnt); - - return osOK; -} - -/// Stop timer -osStatus svcTimerStop (osTimerId timer_id) { - os_timer_cb *pt; - - pt = rt_id2obj(timer_id); - if (pt == NULL) return osErrorParameter; - - if (pt->state != osTimerRunning) return osErrorResource; - - pt->state = osTimerStopped; - - if (rt_timer_remove(pt) != 0) { - return osErrorResource; - } - - return osOK; -} - -/// Delete timer -osStatus svcTimerDelete (osTimerId timer_id) { - os_timer_cb *pt; - - pt = rt_id2obj(timer_id); - if (pt == NULL) return osErrorParameter; - - switch (pt->state) { - case osTimerRunning: - rt_timer_remove(pt); - break; - case osTimerStopped: - break; - default: - return osErrorResource; - } - - pt->state = osTimerInvalid; - - return osOK; -} - -/// Get timer callback parameters -os_InRegs osCallback_type svcTimerCall (osTimerId timer_id) { - os_timer_cb *pt; - osCallback ret; - - pt = rt_id2obj(timer_id); - if (pt == NULL) { - ret.fp = NULL; - ret.arg = NULL; - return osCallback_ret; - } - - ret.fp = (void *)pt->timer->ptimer; - ret.arg = pt->arg; - - return osCallback_ret; -} - -static __INLINE osStatus isrMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec); - -/// Timer Tick (called each SysTick) -void sysTimerTick (void) { - os_timer_cb *pt, *p; - - p = os_timer_head; - if (p == NULL) return; - - p->tcnt--; - while ((p != NULL) && (p->tcnt == 0)) { - pt = p; - p = p->next; - os_timer_head = p; - isrMessagePut(osMessageQId_osTimerMessageQ, (uint32_t)pt, 0); - if (pt->type == osTimerPeriodic) { - rt_timer_insert(pt, pt->icnt); - } else { - pt->state = osTimerStopped; - } - } -} - - -// Timer Management Public API - -/// Create timer -osTimerId osTimerCreate (osTimerDef_t *timer_def, os_timer_type type, void *argument) { - if (__get_IPSR() != 0) return NULL; // Not allowed in ISR - if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) { - // Privileged and not running - return svcTimerCreate(timer_def, type, argument); - } else { - return __svcTimerCreate(timer_def, type, argument); - } -} - -/// Start or restart timer -osStatus osTimerStart (osTimerId timer_id, uint32_t millisec) { - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR - return __svcTimerStart(timer_id, millisec); -} - -/// Stop timer -osStatus osTimerStop (osTimerId timer_id) { - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR - return __svcTimerStop(timer_id); -} - -/// Delete timer -osStatus osTimerDelete (osTimerId timer_id) { - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR - return __svcTimerDelete(timer_id); -} - -/// INTERNAL - Not Public -/// Get timer callback parameters (used by OS Timer Thread) -os_InRegs osCallback osTimerCall (osTimerId timer_id) { - return __svcTimerCall(timer_id); -} - - -// Timer Thread -__NO_RETURN void osTimerThread (void const *argument) { - osCallback cb; - osEvent evt; - - for (;;) { - evt = osMessageGet(osMessageQId_osTimerMessageQ, osWaitForever); - if (evt.status == osEventMessage) { - cb = osTimerCall(evt.value.p); - if (cb.fp != NULL) { - (*(os_ptimer)cb.fp)(cb.arg); - } - } - } -} - - -// ==== Signal Management ==== - -// Signal Service Calls declarations -SVC_2_1(svcSignalSet, int32_t, osThreadId, int32_t, RET_int32_t) -SVC_2_1(svcSignalClear, int32_t, osThreadId, int32_t, RET_int32_t) -SVC_1_1(svcSignalGet, int32_t, osThreadId, RET_int32_t) -SVC_2_3(svcSignalWait, os_InRegs osEvent, int32_t, uint32_t, RET_osEvent) - -// Signal Service Calls - -/// Set the specified Signal Flags of an active thread -int32_t svcSignalSet (osThreadId thread_id, int32_t signals) { - P_TCB ptcb; - int32_t sig; - - ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) return 0x80000000; - - if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000; - - sig = ptcb->events; // Previous signal flags - - rt_evt_set(signals, ptcb->task_id); // Set event flags - - return sig; -} - -/// Clear the specified Signal Flags of an active thread -int32_t svcSignalClear (osThreadId thread_id, int32_t signals) { - P_TCB ptcb; - int32_t sig; - - ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) return 0x80000000; - - if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000; - - sig = ptcb->events; // Previous signal flags - - rt_evt_clr(signals, ptcb->task_id); // Clear event flags - - return sig; -} - -/// Get Signal Flags status of an active thread -int32_t svcSignalGet (osThreadId thread_id) { - P_TCB ptcb; - - ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) return 0x80000000; - - return ptcb->events; // Return event flags -} - -/// Wait for one or more Signal Flags to become signaled for the current RUNNING thread -os_InRegs osEvent_type svcSignalWait (int32_t signals, uint32_t millisec) { - OS_RESULT res; - osEvent ret; - - if (signals & (0xFFFFFFFF << osFeature_Signals)) { - ret.status = osErrorValue; - return osEvent_ret_status; - } - - if (signals != 0) { // Wait for all specified signals - res = rt_evt_wait(signals, rt_ms2tick(millisec), __TRUE); - } else { // Wait for any signal - res = rt_evt_wait(0xFFFF, rt_ms2tick(millisec), __FALSE); - } - - if (res == OS_R_EVT) { - ret.status = osEventSignal; - ret.value.signals = signals ? signals : os_tsk.run->waits; - } else { - ret.status = millisec ? osEventTimeout : osOK; - ret.value.signals = 0; - } - - return osEvent_ret_value; -} - - -// Signal ISR Calls - -/// Set the specified Signal Flags of an active thread -static __INLINE int32_t isrSignalSet (osThreadId thread_id, int32_t signals) { - P_TCB ptcb; - int32_t sig; - - ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) return 0x80000000; - - if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000; - - sig = ptcb->events; // Previous signal flags - - isr_evt_set(signals, ptcb->task_id); // Set event flags - - return sig; -} - - -// Signal Public API - -/// Set the specified Signal Flags of an active thread -int32_t osSignalSet (osThreadId thread_id, int32_t signals) { - if (__get_IPSR() != 0) { // in ISR - return isrSignalSet(thread_id, signals); - } else { // in Thread - return __svcSignalSet(thread_id, signals); - } -} - -/// Clear the specified Signal Flags of an active thread -int32_t osSignalClear (osThreadId thread_id, int32_t signals) { - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR - return __svcSignalClear(thread_id, signals); -} - -/// Get Signal Flags status of an active thread -int32_t osSignalGet (osThreadId thread_id) { - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR - return __svcSignalGet(thread_id); -} - -/// Wait for one or more Signal Flags to become signaled for the current RUNNING thread -os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec) { - osEvent ret; - - if (__get_IPSR() != 0) { // Not allowed in ISR - ret.status = osErrorISR; - return ret; - } - return __svcSignalWait(signals, millisec); -} - - -// ==== Mutex Management ==== - -// Mutex Service Calls declarations -SVC_1_1(svcMutexCreate, osMutexId, osMutexDef_t *, RET_pointer) -SVC_2_1(svcMutexWait, osStatus, osMutexId, uint32_t, RET_osStatus) -SVC_1_1(svcMutexRelease, osStatus, osMutexId, RET_osStatus) -SVC_1_1(svcMutexDelete, osStatus, osMutexId, RET_osStatus) - -// Mutex Service Calls - -/// Create and Initialize a Mutex object -osMutexId svcMutexCreate (osMutexDef_t *mutex_def) { - OS_ID mut; - - if (mutex_def == NULL) { - sysThreadError(osErrorParameter); - return NULL; - } - - mut = mutex_def->mutex; - if (mut == NULL) { - sysThreadError(osErrorParameter); - return NULL; - } - - if (((P_MUCB)mut)->cb_type != 0) { - sysThreadError(osErrorParameter); - return NULL; - } - - rt_mut_init(mut); // Initialize Mutex - - return mut; -} - -/// Wait until a Mutex becomes available -osStatus svcMutexWait (osMutexId mutex_id, uint32_t millisec) { - OS_ID mut; - OS_RESULT res; - - mut = rt_id2obj(mutex_id); - if (mut == NULL) return osErrorParameter; - - if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter; - - res = rt_mut_wait(mut, rt_ms2tick(millisec)); // Wait for Mutex - - if (res == OS_R_TMO) { - return (millisec ? osErrorTimeoutResource : osErrorResource); - } - - return osOK; -} - -/// Release a Mutex that was obtained with osMutexWait -osStatus svcMutexRelease (osMutexId mutex_id) { - OS_ID mut; - OS_RESULT res; - - mut = rt_id2obj(mutex_id); - if (mut == NULL) return osErrorParameter; - - if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter; - - res = rt_mut_release(mut); // Release Mutex - - if (res == OS_R_NOK) return osErrorResource; // Thread not owner or Zero Counter - - return osOK; -} - -/// Delete a Mutex that was created by osMutexCreate -osStatus svcMutexDelete (osMutexId mutex_id) { - OS_ID mut; - - mut = rt_id2obj(mutex_id); - if (mut == NULL) return osErrorParameter; - - if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter; - - rt_mut_delete(mut); // Release Mutex - - return osOK; -} - - -// Mutex Public API - -/// Create and Initialize a Mutex object -osMutexId osMutexCreate (osMutexDef_t *mutex_def) { - if (__get_IPSR() != 0) return NULL; // Not allowed in ISR - if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) { - // Privileged and not running - return svcMutexCreate(mutex_def); - } else { - return __svcMutexCreate(mutex_def); - } -} - -/// Wait until a Mutex becomes available -osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec) { - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR - return __svcMutexWait(mutex_id, millisec); -} - -/// Release a Mutex that was obtained with osMutexWait -osStatus osMutexRelease (osMutexId mutex_id) { - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR - return __svcMutexRelease(mutex_id); -} - -/// Delete a Mutex that was created by osMutexCreate -osStatus osMutexDelete (osMutexId mutex_id) { - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR - return __svcMutexDelete(mutex_id); -} - - -// ==== Semaphore Management ==== - -// Semaphore Service Calls declarations -SVC_2_1(svcSemaphoreCreate, osSemaphoreId, const osSemaphoreDef_t *, int32_t, RET_pointer) -SVC_2_1(svcSemaphoreWait, int32_t, osSemaphoreId, uint32_t, RET_int32_t) -SVC_1_1(svcSemaphoreRelease, osStatus, osSemaphoreId, RET_osStatus) -SVC_1_1(svcSemaphoreDelete, osStatus, osSemaphoreId, RET_osStatus) - -// Semaphore Service Calls - -/// Create and Initialize a Semaphore object -osSemaphoreId svcSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count) { - OS_ID sem; - - if (semaphore_def == NULL) { - sysThreadError(osErrorParameter); - return NULL; - } - - sem = semaphore_def->semaphore; - if (sem == NULL) { - sysThreadError(osErrorParameter); - return NULL; - } - - if (((P_SCB)sem)->cb_type != 0) { - sysThreadError(osErrorParameter); - return NULL; - } - - if (count > osFeature_Semaphore) { - sysThreadError(osErrorValue); - return NULL; - } - - rt_sem_init(sem, count); // Initialize Semaphore - - return sem; -} - -/// Wait until a Semaphore becomes available -int32_t svcSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) { - OS_ID sem; - OS_RESULT res; - - sem = rt_id2obj(semaphore_id); - if (sem == NULL) return -1; - - if (((P_SCB)sem)->cb_type != SCB) return -1; - - res = rt_sem_wait(sem, rt_ms2tick(millisec)); // Wait for Semaphore - - if (res == OS_R_TMO) return 0; // Timeout - - return (((P_SCB)sem)->tokens + 1); -} - -/// Release a Semaphore -osStatus svcSemaphoreRelease (osSemaphoreId semaphore_id) { - OS_ID sem; - - sem = rt_id2obj(semaphore_id); - if (sem == NULL) return osErrorParameter; - - if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter; - - if (((P_SCB)sem)->tokens == osFeature_Semaphore) return osErrorResource; - - rt_sem_send(sem); // Release Semaphore - - return osOK; -} - -/// Delete a Semaphore that was created by osSemaphoreCreate -osStatus svcSemaphoreDelete (osSemaphoreId semaphore_id) { - OS_ID sem; - - sem = rt_id2obj(semaphore_id); - if (sem == NULL) return osErrorParameter; - - if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter; - - rt_sem_delete(sem); // Delete Semaphore - - return osOK; -} - - -// Semaphore ISR Calls - -/// Release a Semaphore -static __INLINE osStatus isrSemaphoreRelease (osSemaphoreId semaphore_id) { - OS_ID sem; - - sem = rt_id2obj(semaphore_id); - if (sem == NULL) return osErrorParameter; - - if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter; - - if (((P_SCB)sem)->tokens == osFeature_Semaphore) return osErrorResource; - - isr_sem_send(sem); // Release Semaphore - - return osOK; -} - - -// Semaphore Public API - -/// Create and Initialize a Semaphore object -osSemaphoreId osSemaphoreCreate (osSemaphoreDef_t *semaphore_def, int32_t count) { - if (__get_IPSR() != 0) return NULL; // Not allowed in ISR - if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) { - // Privileged and not running - return svcSemaphoreCreate(semaphore_def, count); - } else { - return __svcSemaphoreCreate(semaphore_def, count); - } -} - -/// Wait until a Semaphore becomes available -int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) { - if (__get_IPSR() != 0) return -1; // Not allowed in ISR - return __svcSemaphoreWait(semaphore_id, millisec); -} - -/// Release a Semaphore -osStatus osSemaphoreRelease (osSemaphoreId semaphore_id) { - if (__get_IPSR() != 0) { // in ISR - return isrSemaphoreRelease(semaphore_id); - } else { // in Thread - return __svcSemaphoreRelease(semaphore_id); - } -} - -/// Delete a Semaphore that was created by osSemaphoreCreate -osStatus osSemaphoreDelete (osSemaphoreId semaphore_id) { - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR - return __svcSemaphoreDelete(semaphore_id); -} - - -// ==== Memory Management Functions ==== - -// Memory Management Helper Functions - -// Clear Memory Box (Zero init) -static void rt_clr_box (void *box_mem, void *box) { - uint32_t *p, n; - - if (box) { - p = box; - for (n = ((P_BM)box_mem)->blk_size; n; n -= 4) { - *p++ = 0; - } - } -} - -// Memory Management Service Calls declarations -SVC_1_1(svcPoolCreate, osPoolId, const osPoolDef_t *, RET_pointer) -SVC_2_1(sysPoolAlloc, void *, osPoolId, uint32_t, RET_pointer) -SVC_2_1(sysPoolFree, osStatus, osPoolId, void *, RET_osStatus) - -// Memory Management Service & ISR Calls - -/// Create and Initialize memory pool -osPoolId svcPoolCreate (const osPoolDef_t *pool_def) { - uint32_t blk_sz; - - if ((pool_def == NULL) || - (pool_def->pool_sz == 0) || - (pool_def->item_sz == 0) || - (pool_def->pool == NULL)) { - sysThreadError(osErrorParameter); - return NULL; - } - - blk_sz = (pool_def->item_sz + 3) & ~3; - - _init_box(pool_def->pool, sizeof(struct OS_BM) + pool_def->pool_sz * blk_sz, blk_sz); - - return pool_def->pool; -} - -/// Allocate a memory block from a memory pool -void *sysPoolAlloc (osPoolId pool_id, uint32_t clr) { - void *ptr; - - if (pool_id == NULL) return NULL; - - ptr = rt_alloc_box(pool_id); - if (clr) { - rt_clr_box(pool_id, ptr); - } - - return ptr; -} - -/// Return an allocated memory block back to a specific memory pool -osStatus sysPoolFree (osPoolId pool_id, void *block) { - int32_t res; - - if (pool_id == NULL) return osErrorParameter; - - res = rt_free_box(pool_id, block); - if (res != 0) return osErrorValue; - - return osOK; -} - - -// Memory Management Public API - -/// Create and Initialize memory pool -osPoolId osPoolCreate (osPoolDef_t *pool_def) { - if (__get_IPSR() != 0) return NULL; // Not allowed in ISR - if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) { - // Privileged and not running - return svcPoolCreate(pool_def); - } else { - return __svcPoolCreate(pool_def); - } -} - -/// Allocate a memory block from a memory pool -void *osPoolAlloc (osPoolId pool_id) { - if ((__get_IPSR() != 0) || ((__get_CONTROL() & 1) == 0)) { // in ISR or Privileged - return sysPoolAlloc(pool_id, 0); - } else { // in Thread - return __sysPoolAlloc(pool_id, 0); - } -} - -/// Allocate a memory block from a memory pool and set memory block to zero -void *osPoolCAlloc (osPoolId pool_id) { - if ((__get_IPSR() != 0) || ((__get_CONTROL() & 1) == 0)) { // in ISR or Privileged - return sysPoolAlloc(pool_id, 1); - } else { // in Thread - return __sysPoolAlloc(pool_id, 1); - } -} - -/// Return an allocated memory block back to a specific memory pool -osStatus osPoolFree (osPoolId pool_id, void *block) { - if ((__get_IPSR() != 0) || ((__get_CONTROL() & 1) == 0)) { // in ISR or Privileged - return sysPoolFree(pool_id, block); - } else { // in Thread - return __sysPoolFree(pool_id, block); - } -} - - -// ==== Message Queue Management Functions ==== - -// Message Queue Management Service Calls declarations -SVC_2_1(svcMessageCreate, osMessageQId, osMessageQDef_t *, osThreadId, RET_pointer) -SVC_3_1(svcMessagePut, osStatus, osMessageQId, uint32_t, uint32_t, RET_osStatus) -SVC_2_3(svcMessageGet, os_InRegs osEvent, osMessageQId, uint32_t, RET_osEvent) - -// Message Queue Service Calls - -/// Create and Initialize Message Queue -osMessageQId svcMessageCreate (osMessageQDef_t *queue_def, osThreadId thread_id) { - - if ((queue_def == NULL) || - (queue_def->queue_sz == 0) || - (queue_def->pool == NULL)) { - sysThreadError(osErrorParameter); - return NULL; - } - - if (((P_MCB)queue_def->pool)->cb_type != 0) { - sysThreadError(osErrorParameter); - return NULL; - } - - rt_mbx_init(queue_def->pool, 4*(queue_def->queue_sz + 4)); - - return queue_def->pool; -} - -/// Put a Message to a Queue -osStatus svcMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { - OS_RESULT res; - - if (queue_id == NULL) return osErrorParameter; - - if (((P_MCB)queue_id)->cb_type != MCB) return osErrorParameter; - - res = rt_mbx_send(queue_id, (void *)info, rt_ms2tick(millisec)); - - if (res == OS_R_TMO) { - return (millisec ? osErrorTimeoutResource : osErrorResource); - } - - return osOK; -} - -/// Get a Message or Wait for a Message from a Queue -os_InRegs osEvent_type svcMessageGet (osMessageQId queue_id, uint32_t millisec) { - OS_RESULT res; - osEvent ret; - - if (queue_id == NULL) { - ret.status = osErrorParameter; - return osEvent_ret_status; - } - - if (((P_MCB)queue_id)->cb_type != MCB) { - ret.status = osErrorParameter; - return osEvent_ret_status; - } - - res = rt_mbx_wait(queue_id, &ret.value.p, rt_ms2tick(millisec)); - - if (res == OS_R_TMO) { - ret.status = millisec ? osEventTimeout : osOK; - return osEvent_ret_value; - } - - ret.status = osEventMessage; - - return osEvent_ret_value; -} - - -// Message Queue ISR Calls - -/// Put a Message to a Queue -static __INLINE osStatus isrMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { - - if ((queue_id == NULL) || (millisec != 0)) { - return osErrorParameter; - } - - if (((P_MCB)queue_id)->cb_type != MCB) return osErrorParameter; - - if (rt_mbx_check(queue_id) == 0) { // Check if Queue is full - return osErrorResource; - } - - isr_mbx_send(queue_id, (void *)info); - - return osOK; -} - -/// Get a Message or Wait for a Message from a Queue -static __INLINE os_InRegs osEvent isrMessageGet (osMessageQId queue_id, uint32_t millisec) { - OS_RESULT res; - osEvent ret; - - if ((queue_id == NULL) || (millisec != 0)) { - ret.status = osErrorParameter; - return ret; - } - - if (((P_MCB)queue_id)->cb_type != MCB) { - ret.status = osErrorParameter; - return ret; - } - - res = isr_mbx_receive(queue_id, &ret.value.p); - - if (res != OS_R_MBX) { - ret.status = osOK; - return ret; - } - - ret.status = osEventMessage; - - return ret; -} - - -// Message Queue Management Public API - -/// Create and Initialize Message Queue -osMessageQId osMessageCreate (osMessageQDef_t *queue_def, osThreadId thread_id) { - if (__get_IPSR() != 0) return NULL; // Not allowed in ISR - if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) { - // Privileged and not running - return svcMessageCreate(queue_def, thread_id); - } else { - return __svcMessageCreate(queue_def, thread_id); - } -} - -/// Put a Message to a Queue -osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { - if (__get_IPSR() != 0) { // in ISR - return isrMessagePut(queue_id, info, millisec); - } else { // in Thread - return __svcMessagePut(queue_id, info, millisec); - } -} - -/// Get a Message or Wait for a Message from a Queue -os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec) { - if (__get_IPSR() != 0) { // in ISR - return isrMessageGet(queue_id, millisec); - } else { // in Thread - return __svcMessageGet(queue_id, millisec); - } -} - - -// ==== Mail Queue Management Functions ==== - -// Mail Queue Management Service Calls declarations -SVC_2_1(svcMailCreate, osMailQId, osMailQDef_t *, osThreadId, RET_pointer) -SVC_4_1(sysMailAlloc, void *, osMailQId, uint32_t, uint32_t, uint32_t, RET_pointer) -SVC_3_1(sysMailFree, osStatus, osMailQId, void *, uint32_t, RET_osStatus) - -// Mail Queue Management Service & ISR Calls - -/// Create and Initialize mail queue -osMailQId svcMailCreate (osMailQDef_t *queue_def, osThreadId thread_id) { - uint32_t blk_sz; - P_MCB pmcb; - void *pool; - - if ((queue_def == NULL) || - (queue_def->queue_sz == 0) || - (queue_def->item_sz == 0) || - (queue_def->pool == NULL)) { - sysThreadError(osErrorParameter); - return NULL; - } - - pmcb = *(((void **)queue_def->pool) + 0); - pool = *(((void **)queue_def->pool) + 1); - - if ((pool == NULL) || (pmcb == NULL) || (pmcb->cb_type != 0)) { - sysThreadError(osErrorParameter); - return NULL; - } - - blk_sz = (queue_def->item_sz + 3) & ~3; - - _init_box(pool, sizeof(struct OS_BM) + queue_def->queue_sz * blk_sz, blk_sz); - - rt_mbx_init(pmcb, 4*(queue_def->queue_sz + 4)); - - - return queue_def->pool; -} - -/// Allocate a memory block from a mail -void *sysMailAlloc (osMailQId queue_id, uint32_t millisec, uint32_t isr, uint32_t clr) { - P_MCB pmcb; - void *pool; - void *mem; - - if (queue_id == NULL) return NULL; - - pmcb = *(((void **)queue_id) + 0); - pool = *(((void **)queue_id) + 1); - - if ((pool == NULL) || (pmcb == NULL)) return NULL; - - if (isr && (millisec != 0)) return NULL; - - mem = rt_alloc_box(pool); - if (clr) { - rt_clr_box(pool, mem); - } - - if ((mem == NULL) && (millisec != 0)) { - // Put Task to sleep when Memory not available - if (pmcb->p_lnk != NULL) { - rt_put_prio((P_XCB)pmcb, os_tsk.run); - } else { - pmcb->p_lnk = os_tsk.run; - os_tsk.run->p_lnk = NULL; - os_tsk.run->p_rlnk = (P_TCB)pmcb; - // Task is waiting to allocate a message - pmcb->state = 3; - } - rt_block(rt_ms2tick(millisec), WAIT_MBX); - } - - return mem; -} - -/// Free a memory block from a mail -osStatus sysMailFree (osMailQId queue_id, void *mail, uint32_t isr) { - P_MCB pmcb; - P_TCB ptcb; - void *pool; - void *mem; - int32_t res; - - if (queue_id == NULL) return osErrorParameter; - - pmcb = *(((void **)queue_id) + 0); - pool = *(((void **)queue_id) + 1); - - if ((pmcb == NULL) || (pool == NULL)) return osErrorParameter; - - res = rt_free_box(pool, mail); - - if (res != 0) return osErrorValue; - - if (pmcb->state == 3) { - // Task is waiting to allocate a message - if (isr) { - rt_psq_enq (pmcb, (U32)pool); - rt_psh_req (); - } else { - mem = rt_alloc_box(pool); - if (mem != NULL) { - ptcb = rt_get_first((P_XCB)pmcb); - if (pmcb->p_lnk == NULL) { - pmcb->state = 0; - } - rt_ret_val(ptcb, (U32)mem); - rt_rmv_dly(ptcb); - rt_dispatch(ptcb); - } - } - } - - return osOK; -} - - -// Mail Queue Management Public API - -/// Create and Initialize mail queue -osMailQId osMailCreate (osMailQDef_t *queue_def, osThreadId thread_id) { - if (__get_IPSR() != 0) return NULL; // Not allowed in ISR - if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) { - // Privileged and not running - return svcMailCreate(queue_def, thread_id); - } else { - return __svcMailCreate(queue_def, thread_id); - } -} - -/// Allocate a memory block from a mail -void *osMailAlloc (osMailQId queue_id, uint32_t millisec) { - if (__get_IPSR() != 0) { // in ISR - return sysMailAlloc(queue_id, millisec, 1, 0); - } else { // in Thread - return __sysMailAlloc(queue_id, millisec, 0, 0); - } -} - -/// Allocate a memory block from a mail and set memory block to zero -void *osMailCAlloc (osMailQId queue_id, uint32_t millisec) { - if (__get_IPSR() != 0) { // in ISR - return sysMailAlloc(queue_id, millisec, 1, 1); - } else { // in Thread - return __sysMailAlloc(queue_id, millisec, 0, 1); - } -} - -/// Free a memory block from a mail -osStatus osMailFree (osMailQId queue_id, void *mail) { - if (__get_IPSR() != 0) { // in ISR - return sysMailFree(queue_id, mail, 1); - } else { // in Thread - return __sysMailFree(queue_id, mail, 0); - } -} - -/// Put a mail to a queue -osStatus osMailPut (osMailQId queue_id, void *mail) { - if (queue_id == NULL) return osErrorParameter; - if (mail == NULL) return osErrorValue; - return osMessagePut(*((void **)queue_id), (uint32_t)mail, 0); -} - -/// Get a mail from a queue -os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec) { - osEvent ret; - - if (queue_id == NULL) { - ret.status = osErrorParameter; - return ret; - } - - ret = osMessageGet(*((void **)queue_id), millisec); - if (ret.status == osEventMessage) ret.status = osEventMail; - - return ret; -}
--- a/rtx/rt_Event.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,190 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_EVENT.C - * Purpose: Implements waits and wake-ups for event flags - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Conf.h" -#include "rt_System.h" -#include "rt_Event.h" -#include "rt_List.h" -#include "rt_Task.h" -#include "rt_HAL_CM.h" - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_evt_wait -----------------------------------*/ - -OS_RESULT rt_evt_wait (U16 wait_flags, U16 timeout, BOOL and_wait) { - /* Wait for one or more event flags with optional time-out. */ - /* "wait_flags" identifies the flags to wait for. */ - /* "timeout" is the time-out limit in system ticks (0xffff if no time-out) */ - /* "and_wait" specifies the AND-ing of "wait_flags" as condition to be met */ - /* to complete the wait. (OR-ing if set to 0). */ - U32 block_state; - - if (and_wait) { - /* Check for AND-connected events */ - if ((os_tsk.run->events & wait_flags) == wait_flags) { - os_tsk.run->events &= ~wait_flags; - return (OS_R_EVT); - } - block_state = WAIT_AND; - } - else { - /* Check for OR-connected events */ - if (os_tsk.run->events & wait_flags) { - os_tsk.run->waits = os_tsk.run->events & wait_flags; - os_tsk.run->events &= ~wait_flags; - return (OS_R_EVT); - } - block_state = WAIT_OR; - } - /* Task has to wait */ - os_tsk.run->waits = wait_flags; - rt_block (timeout, (U8)block_state); - return (OS_R_TMO); -} - - -/*--------------------------- rt_evt_set ------------------------------------*/ - -void rt_evt_set (U16 event_flags, OS_TID task_id) { - /* Set one or more event flags of a selectable task. */ - P_TCB p_tcb; - - p_tcb = os_active_TCB[task_id-1]; - if (p_tcb == NULL) { - return; - } - p_tcb->events |= event_flags; - event_flags = p_tcb->waits; - /* If the task is not waiting for an event, it should not be put */ - /* to ready state. */ - if (p_tcb->state == WAIT_AND) { - /* Check for AND-connected events */ - if ((p_tcb->events & event_flags) == event_flags) { - goto wkup; - } - } - if (p_tcb->state == WAIT_OR) { - /* Check for OR-connected events */ - if (p_tcb->events & event_flags) { - p_tcb->waits &= p_tcb->events; -wkup: p_tcb->events &= ~event_flags; - rt_rmv_dly (p_tcb); - p_tcb->state = READY; -#ifdef __CMSIS_RTOS - rt_ret_val2(p_tcb, 0x08/*osEventSignal*/, p_tcb->waits); -#else - rt_ret_val (p_tcb, OS_R_EVT); -#endif - rt_dispatch (p_tcb); - } - } -} - - -/*--------------------------- rt_evt_clr ------------------------------------*/ - -void rt_evt_clr (U16 clear_flags, OS_TID task_id) { - /* Clear one or more event flags (identified by "clear_flags") of a */ - /* selectable task (identified by "task"). */ - P_TCB task = os_active_TCB[task_id-1]; - - if (task == NULL) { - return; - } - task->events &= ~clear_flags; -} - - -/*--------------------------- isr_evt_set -----------------------------------*/ - -void isr_evt_set (U16 event_flags, OS_TID task_id) { - /* Same function as "os_evt_set", but to be called by ISRs. */ - P_TCB p_tcb = os_active_TCB[task_id-1]; - - if (p_tcb == NULL) { - return; - } - rt_psq_enq (p_tcb, event_flags); - rt_psh_req (); -} - - -/*--------------------------- rt_evt_get ------------------------------------*/ - -U16 rt_evt_get (void) { - /* Get events of a running task after waiting for OR connected events. */ - return (os_tsk.run->waits); -} - - -/*--------------------------- rt_evt_psh ------------------------------------*/ - -void rt_evt_psh (P_TCB p_CB, U16 set_flags) { - /* Check if task has to be waken up */ - U16 event_flags; - - p_CB->events |= set_flags; - event_flags = p_CB->waits; - if (p_CB->state == WAIT_AND) { - /* Check for AND-connected events */ - if ((p_CB->events & event_flags) == event_flags) { - goto rdy; - } - } - if (p_CB->state == WAIT_OR) { - /* Check for OR-connected events */ - if (p_CB->events & event_flags) { - p_CB->waits &= p_CB->events; -rdy: p_CB->events &= ~event_flags; - rt_rmv_dly (p_CB); - p_CB->state = READY; -#ifdef __CMSIS_RTOS - rt_ret_val2(p_CB, 0x08/*osEventSignal*/, p_CB->waits); -#else - rt_ret_val (p_CB, OS_R_EVT); -#endif - rt_put_prio (&os_rdy, p_CB); - } - } -} - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/rtx/rt_Event.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_EVENT.H - * Purpose: Implements waits and wake-ups for event flags - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Functions */ -extern OS_RESULT rt_evt_wait (U16 wait_flags, U16 timeout, BOOL and_wait); -extern void rt_evt_set (U16 event_flags, OS_TID task_id); -extern void rt_evt_clr (U16 clear_flags, OS_TID task_id); -extern void isr_evt_set (U16 event_flags, OS_TID task_id); -extern U16 rt_evt_get (void); -extern void rt_evt_psh (P_TCB p_CB, U16 set_flags); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx/rt_HAL_CM.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,276 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_HAL_CM.H - * Purpose: Hardware Abstraction Layer for Cortex-M definitions - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Definitions */ -#define INITIAL_xPSR 0x01000000 -#define DEMCR_TRCENA 0x01000000 -#define ITM_ITMENA 0x00000001 -#define MAGIC_WORD 0xE25A2EA5 - -#if defined (__CC_ARM) /* ARM Compiler */ - -#if ((__TARGET_ARCH_7_M || __TARGET_ARCH_7E_M) && !NO_EXCLUSIVE_ACCESS) - #define __USE_EXCLUSIVE_ACCESS -#else - #undef __USE_EXCLUSIVE_ACCESS -#endif - -#elif defined (__GNUC__) /* GNU Compiler */ - -#undef __USE_EXCLUSIVE_ACCESS - -#if defined (__CORTEX_M0) || defined (__CORTEX_M0PLUS) -#define __TARGET_ARCH_6S_M 1 -#else -#define __TARGET_ARCH_6S_M 0 -#endif - -#if defined (__VFP_FP__) && !defined(__SOFTFP__) -#define __TARGET_FPU_VFP 1 -#else -#define __TARGET_FPU_VFP 0 -#endif - -#define __inline inline -#define __weak __attribute__((weak)) - -#ifndef __CMSIS_GENERIC - -__attribute__((always_inline)) static inline void __enable_irq(void) -{ - __asm volatile ("cpsie i"); -} - -__attribute__((always_inline)) static inline U32 __disable_irq(void) -{ - U32 result; - - __asm volatile ("mrs %0, primask" : "=r" (result)); - __asm volatile ("cpsid i"); - return(result & 1); -} - -#endif - -__attribute__(( always_inline)) static inline U8 __clz(U32 value) -{ - U8 result; - - __asm volatile ("clz %0, %1" : "=r" (result) : "r" (value)); - return(result); -} - -#elif defined (__ICCARM__) /* IAR Compiler */ - -#undef __USE_EXCLUSIVE_ACCESS - -#if (__CORE__ == __ARM6M__) -#define __TARGET_ARCH_6S_M 1 -#else -#define __TARGET_ARCH_6S_M 0 -#endif - -#if defined __ARMVFP__ -#define __TARGET_FPU_VFP 1 -#else -#define __TARGET_FPU_VFP 0 -#endif - -#define __inline inline - -#ifndef __CMSIS_GENERIC - -static inline void __enable_irq(void) -{ - __asm volatile ("cpsie i"); -} - -static inline U32 __disable_irq(void) -{ - U32 result; - - __asm volatile ("mrs %0, primask" : "=r" (result)); - __asm volatile ("cpsid i"); - return(result & 1); -} - -#endif - -static inline U8 __clz(U32 value) -{ - U8 result; - - __asm volatile ("clz %0, %1" : "=r" (result) : "r" (value)); - return(result); -} - -#endif - -/* NVIC registers */ -#define NVIC_ST_CTRL (*((volatile U32 *)0xE000E010)) -#define NVIC_ST_RELOAD (*((volatile U32 *)0xE000E014)) -#define NVIC_ST_CURRENT (*((volatile U32 *)0xE000E018)) -#define NVIC_ISER ((volatile U32 *)0xE000E100) -#define NVIC_ICER ((volatile U32 *)0xE000E180) -#if (__TARGET_ARCH_6S_M) -#define NVIC_IP ((volatile U32 *)0xE000E400) -#else -#define NVIC_IP ((volatile U8 *)0xE000E400) -#endif -#define NVIC_INT_CTRL (*((volatile U32 *)0xE000ED04)) -#define NVIC_AIR_CTRL (*((volatile U32 *)0xE000ED0C)) -#define NVIC_SYS_PRI2 (*((volatile U32 *)0xE000ED1C)) -#define NVIC_SYS_PRI3 (*((volatile U32 *)0xE000ED20)) - -#define OS_PEND_IRQ() NVIC_INT_CTRL = (1<<28) -#define OS_PENDING ((NVIC_INT_CTRL >> 26) & (1<<2 | 1)) -#define OS_UNPEND(fl) NVIC_INT_CTRL = (*fl = OS_PENDING) << 25 -#define OS_PEND(fl,p) NVIC_INT_CTRL = (fl | p<<2) << 26 -#define OS_LOCK() NVIC_ST_CTRL = 0x0005 -#define OS_UNLOCK() NVIC_ST_CTRL = 0x0007 - -#define OS_X_PENDING ((NVIC_INT_CTRL >> 28) & 1) -#define OS_X_UNPEND(fl) NVIC_INT_CTRL = (*fl = OS_X_PENDING) << 27 -#define OS_X_PEND(fl,p) NVIC_INT_CTRL = (fl | p) << 28 -#if (__TARGET_ARCH_6S_M) -#define OS_X_INIT(n) NVIC_IP[n>>2] |= 0xFF << (8*(n & 0x03)); \ - NVIC_ISER[n>>5] = 1 << (n & 0x1F) -#else -#define OS_X_INIT(n) NVIC_IP[n] = 0xFF; \ - NVIC_ISER[n>>5] = 1 << (n & 0x1F) -#endif -#define OS_X_LOCK(n) NVIC_ICER[n>>5] = 1 << (n & 0x1F) -#define OS_X_UNLOCK(n) NVIC_ISER[n>>5] = 1 << (n & 0x1F) - -/* Core Debug registers */ -#define DEMCR (*((volatile U32 *)0xE000EDFC)) - -/* ITM registers */ -#define ITM_CONTROL (*((volatile U32 *)0xE0000E80)) -#define ITM_ENABLE (*((volatile U32 *)0xE0000E00)) -#define ITM_PORT30_U32 (*((volatile U32 *)0xE0000078)) -#define ITM_PORT31_U32 (*((volatile U32 *)0xE000007C)) -#define ITM_PORT31_U16 (*((volatile U16 *)0xE000007C)) -#define ITM_PORT31_U8 (*((volatile U8 *)0xE000007C)) - -/* Variables */ -extern BIT dbg_msg; - -/* Functions */ -#ifdef __USE_EXCLUSIVE_ACCESS - #define rt_inc(p) while(__strex((__ldrex(p)+1),p)) - #define rt_dec(p) while(__strex((__ldrex(p)-1),p)) -#else - #define rt_inc(p) __disable_irq();(*p)++;__enable_irq(); - #define rt_dec(p) __disable_irq();(*p)--;__enable_irq(); -#endif - -__inline static U32 rt_inc_qi (U32 size, U8 *count, U8 *first) { - U32 cnt,c2; -#ifdef __USE_EXCLUSIVE_ACCESS - do { - if ((cnt = __ldrex(count)) == size) { - __clrex(); - return (cnt); } - } while (__strex(cnt+1, count)); - do { - c2 = (cnt = __ldrex(first)) + 1; - if (c2 == size) c2 = 0; - } while (__strex(c2, first)); -#else - __disable_irq(); - if ((cnt = *count) < size) { - *count = cnt+1; - c2 = (cnt = *first) + 1; - if (c2 == size) c2 = 0; - *first = c2; - } - __enable_irq (); -#endif - return (cnt); -} - -__inline static void rt_systick_init (void) { - NVIC_ST_RELOAD = os_trv; - NVIC_ST_CURRENT = 0; - NVIC_ST_CTRL = 0x0007; - NVIC_SYS_PRI3 |= 0xFF000000; -} - -__inline static void rt_svc_init (void) { -#if !(__TARGET_ARCH_6S_M) - int sh,prigroup; -#endif - NVIC_SYS_PRI3 |= 0x00FF0000; -#if (__TARGET_ARCH_6S_M) - NVIC_SYS_PRI2 |= (NVIC_SYS_PRI3<<(8+1)) & 0xFC000000; -#else - sh = 8 - __clz (~((NVIC_SYS_PRI3 << 8) & 0xFF000000)); - prigroup = ((NVIC_AIR_CTRL >> 8) & 0x07); - if (prigroup >= sh) { - sh = prigroup + 1; - } - NVIC_SYS_PRI2 = ((0xFEFFFFFF << sh) & 0xFF000000) | (NVIC_SYS_PRI2 & 0x00FFFFFF); -#endif -} - -extern void rt_set_PSP (U32 stack); -extern U32 rt_get_PSP (void); -extern void os_set_env (void); -extern void *_alloc_box (void *box_mem); -extern int _free_box (void *box_mem, void *box); - -extern void rt_init_stack (P_TCB p_TCB, FUNCP task_body); -extern void rt_ret_val (P_TCB p_TCB, U32 v0); -extern void rt_ret_val2 (P_TCB p_TCB, U32 v0, U32 v1); - -extern void dbg_init (void); -extern void dbg_task_notify (P_TCB p_tcb, BOOL create); -extern void dbg_task_switch (U32 task_id); - -#ifdef DBG_MSG -#define DBG_INIT() dbg_init() -#define DBG_TASK_NOTIFY(p_tcb,create) if (dbg_msg) dbg_task_notify(p_tcb,create) -#define DBG_TASK_SWITCH(task_id) if (dbg_msg && (os_tsk.new_tsk != os_tsk.run)) \ - dbg_task_switch(task_id) -#else -#define DBG_INIT() -#define DBG_TASK_NOTIFY(p_tcb,create) -#define DBG_TASK_SWITCH(task_id) -#endif - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx/rt_List.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,320 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_LIST.C - * Purpose: Functions for the management of different lists - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Conf.h" -#include "rt_System.h" -#include "rt_List.h" -#include "rt_Task.h" -#include "rt_Time.h" -#include "rt_HAL_CM.h" - -/*---------------------------------------------------------------------------- - * Global Variables - *---------------------------------------------------------------------------*/ - -/* List head of chained ready tasks */ -struct OS_XCB os_rdy; -/* List head of chained delay tasks */ -struct OS_XCB os_dly; - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_put_prio -----------------------------------*/ - -void rt_put_prio (P_XCB p_CB, P_TCB p_task) { - /* Put task identified with "p_task" into list ordered by priority. */ - /* "p_CB" points to head of list; list has always an element at end with */ - /* a priority less than "p_task->prio". */ - P_TCB p_CB2; - U32 prio; - BOOL sem_mbx = __FALSE; - - if (p_CB->cb_type == SCB || p_CB->cb_type == MCB || p_CB->cb_type == MUCB) { - sem_mbx = __TRUE; - } - prio = p_task->prio; - p_CB2 = p_CB->p_lnk; - /* Search for an entry in the list */ - while (p_CB2 != NULL && prio <= p_CB2->prio) { - p_CB = (P_XCB)p_CB2; - p_CB2 = p_CB2->p_lnk; - } - /* Entry found, insert the task into the list */ - p_task->p_lnk = p_CB2; - p_CB->p_lnk = p_task; - if (sem_mbx) { - if (p_CB2 != NULL) { - p_CB2->p_rlnk = p_task; - } - p_task->p_rlnk = (P_TCB)p_CB; - } - else { - p_task->p_rlnk = NULL; - } -} - - -/*--------------------------- rt_get_first ----------------------------------*/ - -P_TCB rt_get_first (P_XCB p_CB) { - /* Get task at head of list: it is the task with highest priority. */ - /* "p_CB" points to head of list. */ - P_TCB p_first; - - p_first = p_CB->p_lnk; - p_CB->p_lnk = p_first->p_lnk; - if (p_CB->cb_type == SCB || p_CB->cb_type == MCB || p_CB->cb_type == MUCB) { - if (p_first->p_lnk != NULL) { - p_first->p_lnk->p_rlnk = (P_TCB)p_CB; - p_first->p_lnk = NULL; - } - p_first->p_rlnk = NULL; - } - else { - p_first->p_lnk = NULL; - } - return (p_first); -} - - -/*--------------------------- rt_put_rdy_first ------------------------------*/ - -void rt_put_rdy_first (P_TCB p_task) { - /* Put task identified with "p_task" at the head of the ready list. The */ - /* task must have at least a priority equal to highest priority in list. */ - p_task->p_lnk = os_rdy.p_lnk; - p_task->p_rlnk = NULL; - os_rdy.p_lnk = p_task; -} - - -/*--------------------------- rt_get_same_rdy_prio --------------------------*/ - -P_TCB rt_get_same_rdy_prio (void) { - /* Remove a task of same priority from ready list if any exists. Other- */ - /* wise return NULL. */ - P_TCB p_first; - - p_first = os_rdy.p_lnk; - if (p_first->prio == os_tsk.run->prio) { - os_rdy.p_lnk = os_rdy.p_lnk->p_lnk; - return (p_first); - } - return (NULL); -} - - -/*--------------------------- rt_resort_prio --------------------------------*/ - -void rt_resort_prio (P_TCB p_task) { - /* Re-sort ordered lists after the priority of 'p_task' has changed. */ - P_TCB p_CB; - - if (p_task->p_rlnk == NULL) { - if (p_task->state == READY) { - /* Task is chained into READY list. */ - p_CB = (P_TCB)&os_rdy; - goto res; - } - } - else { - p_CB = p_task->p_rlnk; - while (p_CB->cb_type == TCB) { - /* Find a header of this task chain list. */ - p_CB = p_CB->p_rlnk; - } -res:rt_rmv_list (p_task); - rt_put_prio ((P_XCB)p_CB, p_task); - } -} - - -/*--------------------------- rt_put_dly ------------------------------------*/ - -void rt_put_dly (P_TCB p_task, U16 delay) { - /* Put a task identified with "p_task" into chained delay wait list using */ - /* a delay value of "delay". */ - P_TCB p; - U32 delta,idelay = delay; - - p = (P_TCB)&os_dly; - if (p->p_dlnk == NULL) { - /* Delay list empty */ - delta = 0; - goto last; - } - delta = os_dly.delta_time; - while (delta < idelay) { - if (p->p_dlnk == NULL) { - /* End of list found */ -last: p_task->p_dlnk = NULL; - p->p_dlnk = p_task; - p_task->p_blnk = p; - p->delta_time = (U16)(idelay - delta); - p_task->delta_time = 0; - return; - } - p = p->p_dlnk; - delta += p->delta_time; - } - /* Right place found */ - p_task->p_dlnk = p->p_dlnk; - p->p_dlnk = p_task; - p_task->p_blnk = p; - if (p_task->p_dlnk != NULL) { - p_task->p_dlnk->p_blnk = p_task; - } - p_task->delta_time = (U16)(delta - idelay); - p->delta_time -= p_task->delta_time; -} - - -/*--------------------------- rt_dec_dly ------------------------------------*/ - -void rt_dec_dly (void) { - /* Decrement delta time of list head: remove tasks having a value of zero.*/ - P_TCB p_rdy; - - if (os_dly.p_dlnk == NULL) { - return; - } - os_dly.delta_time--; - while ((os_dly.delta_time == 0) && (os_dly.p_dlnk != NULL)) { - p_rdy = os_dly.p_dlnk; - if (p_rdy->p_rlnk != NULL) { - /* Task is really enqueued, remove task from semaphore/mailbox */ - /* timeout waiting list. */ - p_rdy->p_rlnk->p_lnk = p_rdy->p_lnk; - if (p_rdy->p_lnk != NULL) { - p_rdy->p_lnk->p_rlnk = p_rdy->p_rlnk; - p_rdy->p_lnk = NULL; - } - p_rdy->p_rlnk = NULL; - } - rt_put_prio (&os_rdy, p_rdy); - os_dly.delta_time = p_rdy->delta_time; - if (p_rdy->state == WAIT_ITV) { - /* Calculate the next time for interval wait. */ - p_rdy->delta_time = p_rdy->interval_time + (U16)os_time; - } - p_rdy->state = READY; - os_dly.p_dlnk = p_rdy->p_dlnk; - if (p_rdy->p_dlnk != NULL) { - p_rdy->p_dlnk->p_blnk = (P_TCB)&os_dly; - p_rdy->p_dlnk = NULL; - } - p_rdy->p_blnk = NULL; - } -} - - -/*--------------------------- rt_rmv_list -----------------------------------*/ - -void rt_rmv_list (P_TCB p_task) { - /* Remove task identified with "p_task" from ready, semaphore or mailbox */ - /* waiting list if enqueued. */ - P_TCB p_b; - - if (p_task->p_rlnk != NULL) { - /* A task is enqueued in semaphore / mailbox waiting list. */ - p_task->p_rlnk->p_lnk = p_task->p_lnk; - if (p_task->p_lnk != NULL) { - p_task->p_lnk->p_rlnk = p_task->p_rlnk; - } - return; - } - - p_b = (P_TCB)&os_rdy; - while (p_b != NULL) { - /* Search the ready list for task "p_task" */ - if (p_b->p_lnk == p_task) { - p_b->p_lnk = p_task->p_lnk; - return; - } - p_b = p_b->p_lnk; - } -} - - -/*--------------------------- rt_rmv_dly ------------------------------------*/ - -void rt_rmv_dly (P_TCB p_task) { - /* Remove task identified with "p_task" from delay list if enqueued. */ - P_TCB p_b; - - p_b = p_task->p_blnk; - if (p_b != NULL) { - /* Task is really enqueued */ - p_b->p_dlnk = p_task->p_dlnk; - if (p_task->p_dlnk != NULL) { - /* 'p_task' is in the middle of list */ - p_b->delta_time += p_task->delta_time; - p_task->p_dlnk->p_blnk = p_b; - p_task->p_dlnk = NULL; - } - else { - /* 'p_task' is at the end of list */ - p_b->delta_time = 0; - } - p_task->p_blnk = NULL; - } -} - - -/*--------------------------- rt_psq_enq ------------------------------------*/ - -void rt_psq_enq (OS_ID entry, U32 arg) { - /* Insert post service request "entry" into ps-queue. */ - U32 idx; - - idx = rt_inc_qi (os_psq->size, &os_psq->count, &os_psq->first); - if (idx < os_psq->size) { - os_psq->q[idx].id = entry; - os_psq->q[idx].arg = arg; - } - else { - os_error (OS_ERR_FIFO_OVF); - } -} - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx/rt_List.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_LIST.H - * Purpose: Functions for the management of different lists - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Definitions */ - -/* Values for 'cb_type' */ -#define TCB 0 -#define MCB 1 -#define SCB 2 -#define MUCB 3 -#define HCB 4 - -/* Variables */ -extern struct OS_XCB os_rdy; -extern struct OS_XCB os_dly; - -/* Functions */ -extern void rt_put_prio (P_XCB p_CB, P_TCB p_task); -extern P_TCB rt_get_first (P_XCB p_CB); -extern void rt_put_rdy_first (P_TCB p_task); -extern P_TCB rt_get_same_rdy_prio (void); -extern void rt_resort_prio (P_TCB p_task); -extern void rt_put_dly (P_TCB p_task, U16 delay); -extern void rt_dec_dly (void); -extern void rt_rmv_list (P_TCB p_task); -extern void rt_rmv_dly (P_TCB p_task); -extern void rt_psq_enq (OS_ID entry, U32 arg); - -/* This is a fast macro generating in-line code */ -#define rt_rdy_prio(void) (os_rdy.p_lnk->prio) - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx/rt_Mailbox.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,292 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_MAILBOX.C - * Purpose: Implements waits and wake-ups for mailbox messages - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Conf.h" -#include "rt_System.h" -#include "rt_List.h" -#include "rt_Mailbox.h" -#include "rt_MemBox.h" -#include "rt_Task.h" -#include "rt_HAL_CM.h" - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_mbx_init -----------------------------------*/ - -void rt_mbx_init (OS_ID mailbox, U16 mbx_size) { - /* Initialize a mailbox */ - P_MCB p_MCB = mailbox; - - p_MCB->cb_type = MCB; - p_MCB->state = 0; - p_MCB->isr_st = 0; - p_MCB->p_lnk = NULL; - p_MCB->first = 0; - p_MCB->last = 0; - p_MCB->count = 0; - p_MCB->size = (mbx_size + sizeof(void *) - sizeof(struct OS_MCB)) / - (U32)sizeof (void *); -} - - -/*--------------------------- rt_mbx_send -----------------------------------*/ - -OS_RESULT rt_mbx_send (OS_ID mailbox, void *p_msg, U16 timeout) { - /* Send message to a mailbox */ - P_MCB p_MCB = mailbox; - P_TCB p_TCB; - - if ((p_MCB->p_lnk != NULL) && (p_MCB->state == 1)) { - /* A task is waiting for message */ - p_TCB = rt_get_first ((P_XCB)p_MCB); -#ifdef __CMSIS_RTOS - rt_ret_val2(p_TCB, 0x10/*osEventMessage*/, (U32)p_msg); -#else - *p_TCB->msg = p_msg; - rt_ret_val (p_TCB, OS_R_MBX); -#endif - rt_rmv_dly (p_TCB); - rt_dispatch (p_TCB); - } - else { - /* Store message in mailbox queue */ - if (p_MCB->count == p_MCB->size) { - /* No free message entry, wait for one. If message queue is full, */ - /* then no task is waiting for message. The 'p_MCB->p_lnk' list */ - /* pointer can now be reused for send message waits task list. */ - if (timeout == 0) { - return (OS_R_TMO); - } - if (p_MCB->p_lnk != NULL) { - rt_put_prio ((P_XCB)p_MCB, os_tsk.run); - } - else { - p_MCB->p_lnk = os_tsk.run; - os_tsk.run->p_lnk = NULL; - os_tsk.run->p_rlnk = (P_TCB)p_MCB; - /* Task is waiting to send a message */ - p_MCB->state = 2; - } - os_tsk.run->msg = p_msg; - rt_block (timeout, WAIT_MBX); - return (OS_R_TMO); - } - /* Yes, there is a free entry in a mailbox. */ - p_MCB->msg[p_MCB->first] = p_msg; - rt_inc (&p_MCB->count); - if (++p_MCB->first == p_MCB->size) { - p_MCB->first = 0; - } - } - return (OS_R_OK); -} - - -/*--------------------------- rt_mbx_wait -----------------------------------*/ - -OS_RESULT rt_mbx_wait (OS_ID mailbox, void **message, U16 timeout) { - /* Receive a message; possibly wait for it */ - P_MCB p_MCB = mailbox; - P_TCB p_TCB; - - /* If a message is available in the fifo buffer */ - /* remove it from the fifo buffer and return. */ - if (p_MCB->count) { - *message = p_MCB->msg[p_MCB->last]; - if (++p_MCB->last == p_MCB->size) { - p_MCB->last = 0; - } - if ((p_MCB->p_lnk != NULL) && (p_MCB->state == 2)) { - /* A task is waiting to send message */ - p_TCB = rt_get_first ((P_XCB)p_MCB); -#ifdef __CMSIS_RTOS - rt_ret_val(p_TCB, 0/*osOK*/); -#else - rt_ret_val(p_TCB, OS_R_OK); -#endif - p_MCB->msg[p_MCB->first] = p_TCB->msg; - if (++p_MCB->first == p_MCB->size) { - p_MCB->first = 0; - } - rt_rmv_dly (p_TCB); - rt_dispatch (p_TCB); - } - else { - rt_dec (&p_MCB->count); - } - return (OS_R_OK); - } - /* No message available: wait for one */ - if (timeout == 0) { - return (OS_R_TMO); - } - if (p_MCB->p_lnk != NULL) { - rt_put_prio ((P_XCB)p_MCB, os_tsk.run); - } - else { - p_MCB->p_lnk = os_tsk.run; - os_tsk.run->p_lnk = NULL; - os_tsk.run->p_rlnk = (P_TCB)p_MCB; - /* Task is waiting to receive a message */ - p_MCB->state = 1; - } - rt_block(timeout, WAIT_MBX); -#ifndef __CMSIS_RTOS - os_tsk.run->msg = message; -#endif - return (OS_R_TMO); -} - - -/*--------------------------- rt_mbx_check ----------------------------------*/ - -OS_RESULT rt_mbx_check (OS_ID mailbox) { - /* Check for free space in a mailbox. Returns the number of messages */ - /* that can be stored to a mailbox. It returns 0 when mailbox is full. */ - P_MCB p_MCB = mailbox; - - return (p_MCB->size - p_MCB->count); -} - - -/*--------------------------- isr_mbx_send ----------------------------------*/ - -void isr_mbx_send (OS_ID mailbox, void *p_msg) { - /* Same function as "os_mbx_send", but to be called by ISRs. */ - P_MCB p_MCB = mailbox; - - rt_psq_enq (p_MCB, (U32)p_msg); - rt_psh_req (); -} - - -/*--------------------------- isr_mbx_receive -------------------------------*/ - -OS_RESULT isr_mbx_receive (OS_ID mailbox, void **message) { - /* Receive a message in the interrupt function. The interrupt function */ - /* should not wait for a message since this would block the rtx os. */ - P_MCB p_MCB = mailbox; - - if (p_MCB->count) { - /* A message is available in the fifo buffer. */ - *message = p_MCB->msg[p_MCB->last]; - if (p_MCB->state == 2) { - /* A task is locked waiting to send message */ - rt_psq_enq (p_MCB, 0); - rt_psh_req (); - } - rt_dec (&p_MCB->count); - if (++p_MCB->last == p_MCB->size) { - p_MCB->last = 0; - } - return (OS_R_MBX); - } - return (OS_R_OK); -} - - -/*--------------------------- rt_mbx_psh ------------------------------------*/ - -void rt_mbx_psh (P_MCB p_CB, void *p_msg) { - /* Store the message to the mailbox queue or pass it to task directly. */ - P_TCB p_TCB; - void *mem; - - if (p_CB->p_lnk != NULL) switch (p_CB->state) { -#ifdef __CMSIS_RTOS - case 3: - /* Task is waiting to allocate memory, remove it from the waiting list */ - mem = rt_alloc_box(p_msg); - if (mem == NULL) break; - p_TCB = rt_get_first ((P_XCB)p_CB); - rt_ret_val(p_TCB, (U32)mem); - p_TCB->state = READY; - rt_rmv_dly (p_TCB); - rt_put_prio (&os_rdy, p_TCB); - break; -#endif - case 2: - /* Task is waiting to send a message, remove it from the waiting list */ - p_TCB = rt_get_first ((P_XCB)p_CB); -#ifdef __CMSIS_RTOS - rt_ret_val(p_TCB, 0/*osOK*/); -#else - rt_ret_val(p_TCB, OS_R_OK); -#endif - p_CB->msg[p_CB->first] = p_TCB->msg; - rt_inc (&p_CB->count); - if (++p_CB->first == p_CB->size) { - p_CB->first = 0; - } - p_TCB->state = READY; - rt_rmv_dly (p_TCB); - rt_put_prio (&os_rdy, p_TCB); - break; - case 1: - /* Task is waiting for a message, pass the message to the task directly */ - p_TCB = rt_get_first ((P_XCB)p_CB); -#ifdef __CMSIS_RTOS - rt_ret_val2(p_TCB, 0x10/*osEventMessage*/, (U32)p_msg); -#else - *p_TCB->msg = p_msg; - rt_ret_val (p_TCB, OS_R_MBX); -#endif - p_TCB->state = READY; - rt_rmv_dly (p_TCB); - rt_put_prio (&os_rdy, p_TCB); - break; - } else { - /* No task is waiting for a message, store it to the mailbox queue */ - if (p_CB->count < p_CB->size) { - p_CB->msg[p_CB->first] = p_msg; - rt_inc (&p_CB->count); - if (++p_CB->first == p_CB->size) { - p_CB->first = 0; - } - } - else { - os_error (OS_ERR_MBX_OVF); - } - } -} - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx/rt_Mailbox.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_MAILBOX.H - * Purpose: Implements waits and wake-ups for mailbox messages - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Functions */ -extern void rt_mbx_init (OS_ID mailbox, U16 mbx_size); -extern OS_RESULT rt_mbx_send (OS_ID mailbox, void *p_msg, U16 timeout); -extern OS_RESULT rt_mbx_wait (OS_ID mailbox, void **message, U16 timeout); -extern OS_RESULT rt_mbx_check (OS_ID mailbox); -extern void isr_mbx_send (OS_ID mailbox, void *p_msg); -extern OS_RESULT isr_mbx_receive (OS_ID mailbox, void **message); -extern void rt_mbx_psh (P_MCB p_CB, void *p_msg); - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx/rt_MemBox.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,166 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_MEMBOX.C - * Purpose: Interface functions for fixed memory block management system - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Conf.h" -#include "rt_System.h" -#include "rt_MemBox.h" -#include "rt_HAL_CM.h" - -/*---------------------------------------------------------------------------- - * Global Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- _init_box -------------------------------------*/ - -int _init_box (void *box_mem, U32 box_size, U32 blk_size) { - /* Initialize memory block system, returns 0 if OK, 1 if fails. */ - void *end; - void *blk; - void *next; - U32 sizeof_bm; - - /* Create memory structure. */ - if (blk_size & BOX_ALIGN_8) { - /* Memory blocks 8-byte aligned. */ - blk_size = ((blk_size & ~BOX_ALIGN_8) + 7) & ~7; - sizeof_bm = (sizeof (struct OS_BM) + 7) & ~7; - } - else { - /* Memory blocks 4-byte aligned. */ - blk_size = (blk_size + 3) & ~3; - sizeof_bm = sizeof (struct OS_BM); - } - if (blk_size == 0) { - return (1); - } - if ((blk_size + sizeof_bm) > box_size) { - return (1); - } - /* Create a Memory structure. */ - blk = ((U8 *) box_mem) + sizeof_bm; - ((P_BM) box_mem)->free = blk; - end = ((U8 *) box_mem) + box_size; - ((P_BM) box_mem)->end = end; - ((P_BM) box_mem)->blk_size = blk_size; - - /* Link all free blocks using offsets. */ - end = ((U8 *) end) - blk_size; - while (1) { - next = ((U8 *) blk) + blk_size; - if (next > end) break; - *((void **)blk) = next; - blk = next; - } - /* end marker */ - *((void **)blk) = 0; - return (0); -} - -/*--------------------------- rt_alloc_box ----------------------------------*/ - -void *rt_alloc_box (void *box_mem) { - /* Allocate a memory block and return start address. */ - void **free; -#ifndef __USE_EXCLUSIVE_ACCESS - int irq_dis; - - irq_dis = __disable_irq (); - free = ((P_BM) box_mem)->free; - if (free) { - ((P_BM) box_mem)->free = *free; - } - if (!irq_dis) __enable_irq (); -#else - do { - if ((free = (void **)__ldrex(&((P_BM) box_mem)->free)) == 0) { - __clrex(); - break; - } - } while (__strex((U32)*free, &((P_BM) box_mem)->free)); -#endif - return (free); -} - - -/*--------------------------- _calloc_box -----------------------------------*/ - -void *_calloc_box (void *box_mem) { - /* Allocate a 0-initialized memory block and return start address. */ - void *free; - U32 *p; - U32 i; - - free = _alloc_box (box_mem); - if (free) { - p = free; - for (i = ((P_BM) box_mem)->blk_size; i; i -= 4) { - *p = 0; - p++; - } - } - return (free); -} - - -/*--------------------------- rt_free_box -----------------------------------*/ - -int rt_free_box (void *box_mem, void *box) { - /* Free a memory block, returns 0 if OK, 1 if box does not belong to box_mem */ -#ifndef __USE_EXCLUSIVE_ACCESS - int irq_dis; -#endif - - if (box < box_mem || box >= ((P_BM) box_mem)->end) { - return (1); - } - -#ifndef __USE_EXCLUSIVE_ACCESS - irq_dis = __disable_irq (); - *((void **)box) = ((P_BM) box_mem)->free; - ((P_BM) box_mem)->free = box; - if (!irq_dis) __enable_irq (); -#else - do { - *((void **)box) = (void *)__ldrex(&((P_BM) box_mem)->free); - } while (__strex ((U32)box, &((P_BM) box_mem)->free)); -#endif - return (0); -} - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx/rt_MemBox.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_MEMBOX.H - * Purpose: Interface functions for fixed memory block management system - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Functions */ -#define rt_init_box _init_box -#define rt_calloc_box _calloc_box -extern int _init_box (void *box_mem, U32 box_size, U32 blk_size); -extern void *rt_alloc_box (void *box_mem); -extern void * _calloc_box (void *box_mem); -extern int rt_free_box (void *box_mem, void *box); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx/rt_Mutex.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,197 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_MUTEX.C - * Purpose: Implements mutex synchronization objects - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Conf.h" -#include "rt_List.h" -#include "rt_Task.h" -#include "rt_Mutex.h" -#include "rt_HAL_CM.h" - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_mut_init -----------------------------------*/ - -void rt_mut_init (OS_ID mutex) { - /* Initialize a mutex object */ - P_MUCB p_MCB = mutex; - - p_MCB->cb_type = MUCB; - p_MCB->prio = 0; - p_MCB->level = 0; - p_MCB->p_lnk = NULL; - p_MCB->owner = NULL; -} - - -/*--------------------------- rt_mut_delete ---------------------------------*/ - -#ifdef __CMSIS_RTOS -OS_RESULT rt_mut_delete (OS_ID mutex) { - /* Delete a mutex object */ - P_MUCB p_MCB = mutex; - P_TCB p_TCB; - - /* Restore owner task's priority. */ - if (p_MCB->level != 0) { - p_MCB->owner->prio = p_MCB->prio; - if (p_MCB->owner != os_tsk.run) { - rt_resort_prio (p_MCB->owner); - } - } - - while (p_MCB->p_lnk != NULL) { - /* A task is waiting for mutex. */ - p_TCB = rt_get_first ((P_XCB)p_MCB); - rt_ret_val(p_TCB, 0/*osOK*/); - rt_rmv_dly(p_TCB); - p_TCB->state = READY; - rt_put_prio (&os_rdy, p_TCB); - } - - if (os_rdy.p_lnk && (os_rdy.p_lnk->prio > os_tsk.run->prio)) { - /* preempt running task */ - rt_put_prio (&os_rdy, os_tsk.run); - os_tsk.run->state = READY; - rt_dispatch (NULL); - } - - p_MCB->cb_type = 0; - - return (OS_R_OK); -} -#endif - - -/*--------------------------- rt_mut_release --------------------------------*/ - -OS_RESULT rt_mut_release (OS_ID mutex) { - /* Release a mutex object */ - P_MUCB p_MCB = mutex; - P_TCB p_TCB; - - if (p_MCB->level == 0 || p_MCB->owner != os_tsk.run) { - /* Unbalanced mutex release or task is not the owner */ - return (OS_R_NOK); - } - if (--p_MCB->level != 0) { - return (OS_R_OK); - } - /* Restore owner task's priority. */ - os_tsk.run->prio = p_MCB->prio; - if (p_MCB->p_lnk != NULL) { - /* A task is waiting for mutex. */ - p_TCB = rt_get_first ((P_XCB)p_MCB); -#ifdef __CMSIS_RTOS - rt_ret_val(p_TCB, 0/*osOK*/); -#else - rt_ret_val(p_TCB, OS_R_MUT); -#endif - rt_rmv_dly (p_TCB); - /* A waiting task becomes the owner of this mutex. */ - p_MCB->level = 1; - p_MCB->owner = p_TCB; - p_MCB->prio = p_TCB->prio; - /* Priority inversion, check which task continues. */ - if (os_tsk.run->prio >= rt_rdy_prio()) { - rt_dispatch (p_TCB); - } - else { - /* Ready task has higher priority than running task. */ - rt_put_prio (&os_rdy, os_tsk.run); - rt_put_prio (&os_rdy, p_TCB); - os_tsk.run->state = READY; - p_TCB->state = READY; - rt_dispatch (NULL); - } - } - else { - /* Check if own priority raised by priority inversion. */ - if (rt_rdy_prio() > os_tsk.run->prio) { - rt_put_prio (&os_rdy, os_tsk.run); - os_tsk.run->state = READY; - rt_dispatch (NULL); - } - } - return (OS_R_OK); -} - - -/*--------------------------- rt_mut_wait -----------------------------------*/ - -OS_RESULT rt_mut_wait (OS_ID mutex, U16 timeout) { - /* Wait for a mutex, continue when mutex is free. */ - P_MUCB p_MCB = mutex; - - if (p_MCB->level == 0) { - p_MCB->owner = os_tsk.run; - p_MCB->prio = os_tsk.run->prio; - goto inc; - } - if (p_MCB->owner == os_tsk.run) { - /* OK, running task is the owner of this mutex. */ -inc:p_MCB->level++; - return (OS_R_OK); - } - /* Mutex owned by another task, wait until released. */ - if (timeout == 0) { - return (OS_R_TMO); - } - /* Raise the owner task priority if lower than current priority. */ - /* This priority inversion is called priority inheritance. */ - if (p_MCB->prio < os_tsk.run->prio) { - p_MCB->owner->prio = os_tsk.run->prio; - rt_resort_prio (p_MCB->owner); - } - if (p_MCB->p_lnk != NULL) { - rt_put_prio ((P_XCB)p_MCB, os_tsk.run); - } - else { - p_MCB->p_lnk = os_tsk.run; - os_tsk.run->p_lnk = NULL; - os_tsk.run->p_rlnk = (P_TCB)p_MCB; - } - rt_block(timeout, WAIT_MUT); - return (OS_R_TMO); -} - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx/rt_Mutex.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_MUTEX.H - * Purpose: Implements mutex synchronization objects - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Functions */ -extern void rt_mut_init (OS_ID mutex); -extern OS_RESULT rt_mut_delete (OS_ID mutex); -extern OS_RESULT rt_mut_release (OS_ID mutex); -extern OS_RESULT rt_mut_wait (OS_ID mutex, U16 timeout); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx/rt_Robin.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,84 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_ROBIN.C - * Purpose: Round Robin Task switching - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Conf.h" -#include "rt_List.h" -#include "rt_Task.h" -#include "rt_Time.h" -#include "rt_Robin.h" -#include "rt_HAL_CM.h" - -/*---------------------------------------------------------------------------- - * Global Variables - *---------------------------------------------------------------------------*/ - -struct OS_ROBIN os_robin; - - -/*---------------------------------------------------------------------------- - * Global Functions - *---------------------------------------------------------------------------*/ - -/*--------------------------- rt_init_robin ---------------------------------*/ - -__weak void rt_init_robin (void) { - /* Initialize Round Robin variables. */ - os_robin.task = NULL; - os_robin.tout = (U16)os_rrobin; -} - -/*--------------------------- rt_chk_robin ----------------------------------*/ - -__weak void rt_chk_robin (void) { - /* Check if Round Robin timeout expired and switch to the next ready task.*/ - P_TCB p_new; - - if (os_robin.task != os_rdy.p_lnk) { - /* New task was suspended, reset Round Robin timeout. */ - os_robin.task = os_rdy.p_lnk; - os_robin.time = (U16)os_time + os_robin.tout - 1; - } - if (os_robin.time == (U16)os_time) { - /* Round Robin timeout has expired, swap Robin tasks. */ - os_robin.task = NULL; - p_new = rt_get_first (&os_rdy); - rt_put_prio ((P_XCB)&os_rdy, p_new); - } -} - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx/rt_Robin.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_ROBIN.H - * Purpose: Round Robin Task switching definitions - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Variables */ -extern struct OS_ROBIN os_robin; - -/* Functions */ -extern void rt_init_robin (void); -extern void rt_chk_robin (void); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx/rt_Semaphore.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,183 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_SEMAPHORE.C - * Purpose: Implements binary and counting semaphores - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Conf.h" -#include "rt_System.h" -#include "rt_List.h" -#include "rt_Task.h" -#include "rt_Semaphore.h" -#include "rt_HAL_CM.h" - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_sem_init -----------------------------------*/ - -void rt_sem_init (OS_ID semaphore, U16 token_count) { - /* Initialize a semaphore */ - P_SCB p_SCB = semaphore; - - p_SCB->cb_type = SCB; - p_SCB->p_lnk = NULL; - p_SCB->tokens = token_count; -} - - -/*--------------------------- rt_sem_delete ---------------------------------*/ - -#ifdef __CMSIS_RTOS -OS_RESULT rt_sem_delete (OS_ID semaphore) { - /* Delete semaphore */ - P_SCB p_SCB = semaphore; - P_TCB p_TCB; - - while (p_SCB->p_lnk != NULL) { - /* A task is waiting for token */ - p_TCB = rt_get_first ((P_XCB)p_SCB); - rt_ret_val(p_TCB, 0); - rt_rmv_dly(p_TCB); - p_TCB->state = READY; - rt_put_prio (&os_rdy, p_TCB); - } - - if (os_rdy.p_lnk && (os_rdy.p_lnk->prio > os_tsk.run->prio)) { - /* preempt running task */ - rt_put_prio (&os_rdy, os_tsk.run); - os_tsk.run->state = READY; - rt_dispatch (NULL); - } - - p_SCB->cb_type = 0; - - return (OS_R_OK); -} -#endif - - -/*--------------------------- rt_sem_send -----------------------------------*/ - -OS_RESULT rt_sem_send (OS_ID semaphore) { - /* Return a token to semaphore */ - P_SCB p_SCB = semaphore; - P_TCB p_TCB; - - if (p_SCB->p_lnk != NULL) { - /* A task is waiting for token */ - p_TCB = rt_get_first ((P_XCB)p_SCB); -#ifdef __CMSIS_RTOS - rt_ret_val(p_TCB, 1); -#else - rt_ret_val(p_TCB, OS_R_SEM); -#endif - rt_rmv_dly (p_TCB); - rt_dispatch (p_TCB); - } - else { - /* Store token. */ - p_SCB->tokens++; - } - return (OS_R_OK); -} - - -/*--------------------------- rt_sem_wait -----------------------------------*/ - -OS_RESULT rt_sem_wait (OS_ID semaphore, U16 timeout) { - /* Obtain a token; possibly wait for it */ - P_SCB p_SCB = semaphore; - - if (p_SCB->tokens) { - p_SCB->tokens--; - return (OS_R_OK); - } - /* No token available: wait for one */ - if (timeout == 0) { - return (OS_R_TMO); - } - if (p_SCB->p_lnk != NULL) { - rt_put_prio ((P_XCB)p_SCB, os_tsk.run); - } - else { - p_SCB->p_lnk = os_tsk.run; - os_tsk.run->p_lnk = NULL; - os_tsk.run->p_rlnk = (P_TCB)p_SCB; - } - rt_block(timeout, WAIT_SEM); - return (OS_R_TMO); -} - - -/*--------------------------- isr_sem_send ----------------------------------*/ - -void isr_sem_send (OS_ID semaphore) { - /* Same function as "os_sem"send", but to be called by ISRs */ - P_SCB p_SCB = semaphore; - - rt_psq_enq (p_SCB, 0); - rt_psh_req (); -} - - -/*--------------------------- rt_sem_psh ------------------------------------*/ - -void rt_sem_psh (P_SCB p_CB) { - /* Check if task has to be waken up */ - P_TCB p_TCB; - - if (p_CB->p_lnk != NULL) { - /* A task is waiting for token */ - p_TCB = rt_get_first ((P_XCB)p_CB); - rt_rmv_dly (p_TCB); - p_TCB->state = READY; -#ifdef __CMSIS_RTOS - rt_ret_val(p_TCB, 1); -#else - rt_ret_val(p_TCB, OS_R_SEM); -#endif - rt_put_prio (&os_rdy, p_TCB); - } - else { - /* Store token */ - p_CB->tokens++; - } -} - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx/rt_Semaphore.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_SEMAPHORE.H - * Purpose: Implements binary and counting semaphores - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Functions */ -extern void rt_sem_init (OS_ID semaphore, U16 token_count); -extern OS_RESULT rt_sem_delete(OS_ID semaphore); -extern OS_RESULT rt_sem_send (OS_ID semaphore); -extern OS_RESULT rt_sem_wait (OS_ID semaphore, U16 timeout); -extern void isr_sem_send (OS_ID semaphore); -extern void rt_sem_psh (P_SCB p_CB); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx/rt_System.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,299 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_SYSTEM.C - * Purpose: System Task Manager - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Conf.h" -#include "rt_Task.h" -#include "rt_System.h" -#include "rt_Event.h" -#include "rt_List.h" -#include "rt_Mailbox.h" -#include "rt_Semaphore.h" -#include "rt_Time.h" -#include "rt_Robin.h" -#include "rt_HAL_CM.h" - -/*---------------------------------------------------------------------------- - * Global Variables - *---------------------------------------------------------------------------*/ - -int os_tick_irqn; - -/*---------------------------------------------------------------------------- - * Local Variables - *---------------------------------------------------------------------------*/ - -static volatile BIT os_lock; -static volatile BIT os_psh_flag; -static U8 pend_flags; - -/*---------------------------------------------------------------------------- - * Global Functions - *---------------------------------------------------------------------------*/ - -#if defined (__CC_ARM) -__asm void $$RTX$$version (void) { - /* Export a version number symbol for a version control. */ - - EXPORT __RL_RTX_VER - -__RL_RTX_VER EQU 0x450 -} -#endif - - -/*--------------------------- rt_suspend ------------------------------------*/ -U32 rt_suspend (void) { - /* Suspend OS scheduler */ - U32 delta = 0xFFFF; - - rt_tsk_lock(); - - if (os_dly.p_dlnk) { - delta = os_dly.delta_time; - } -#ifndef __CMSIS_RTOS - if (os_tmr.next) { - if (os_tmr.tcnt < delta) delta = os_tmr.tcnt; - } -#endif - - return (delta); -} - - -/*--------------------------- rt_resume -------------------------------------*/ -void rt_resume (U32 sleep_time) { - /* Resume OS scheduler after suspend */ - P_TCB next; - U32 delta; - - os_tsk.run->state = READY; - rt_put_rdy_first (os_tsk.run); - - os_robin.task = NULL; - - /* Update delays. */ - if (os_dly.p_dlnk) { - delta = sleep_time; - if (delta >= os_dly.delta_time) { - delta -= os_dly.delta_time; - os_time += os_dly.delta_time; - os_dly.delta_time = 1; - while (os_dly.p_dlnk) { - rt_dec_dly(); - if (delta == 0) break; - delta--; - os_time++; - } - } else { - os_time += delta; - os_dly.delta_time -= delta; - } - } else { - os_time += sleep_time; - } - -#ifndef __CMSIS_RTOS - /* Check the user timers. */ - if (os_tmr.next) { - delta = sleep_time; - if (delta >= os_tmr.tcnt) { - delta -= os_tmr.tcnt; - os_tmr.tcnt = 1; - while (os_tmr.next) { - rt_tmr_tick(); - if (delta == 0) break; - delta--; - } - } else { - os_tmr.tcnt -= delta; - } - } -#endif - - /* Switch back to highest ready task */ - next = rt_get_first (&os_rdy); - rt_switch_req (next); - - rt_tsk_unlock(); -} - - -/*--------------------------- rt_tsk_lock -----------------------------------*/ - -void rt_tsk_lock (void) { - /* Prevent task switching by locking out scheduler */ - if (os_tick_irqn < 0) { - OS_LOCK(); - os_lock = __TRUE; - OS_UNPEND (&pend_flags); - } else { - OS_X_LOCK(os_tick_irqn); - os_lock = __TRUE; - OS_X_UNPEND (&pend_flags); - } -} - - -/*--------------------------- rt_tsk_unlock ---------------------------------*/ - -void rt_tsk_unlock (void) { - /* Unlock scheduler and re-enable task switching */ - if (os_tick_irqn < 0) { - OS_UNLOCK(); - os_lock = __FALSE; - OS_PEND (pend_flags, os_psh_flag); - os_psh_flag = __FALSE; - } else { - OS_X_UNLOCK(os_tick_irqn); - os_lock = __FALSE; - OS_X_PEND (pend_flags, os_psh_flag); - os_psh_flag = __FALSE; - } -} - - -/*--------------------------- rt_psh_req ------------------------------------*/ - -void rt_psh_req (void) { - /* Initiate a post service handling request if required. */ - if (os_lock == __FALSE) { - OS_PEND_IRQ (); - } - else { - os_psh_flag = __TRUE; - } -} - - -/*--------------------------- rt_pop_req ------------------------------------*/ - -void rt_pop_req (void) { - /* Process an ISR post service requests. */ - struct OS_XCB *p_CB; - P_TCB next; - U32 idx; - - os_tsk.run->state = READY; - rt_put_rdy_first (os_tsk.run); - - idx = os_psq->last; - while (os_psq->count) { - p_CB = os_psq->q[idx].id; - if (p_CB->cb_type == TCB) { - /* Is of TCB type */ - rt_evt_psh ((P_TCB)p_CB, (U16)os_psq->q[idx].arg); - } - else if (p_CB->cb_type == MCB) { - /* Is of MCB type */ - rt_mbx_psh ((P_MCB)p_CB, (void *)os_psq->q[idx].arg); - } - else { - /* Must be of SCB type */ - rt_sem_psh ((P_SCB)p_CB); - } - if (++idx == os_psq->size) idx = 0; - rt_dec (&os_psq->count); - } - os_psq->last = idx; - - next = rt_get_first (&os_rdy); - rt_switch_req (next); -} - - -/*--------------------------- os_tick_init ----------------------------------*/ - -__weak int os_tick_init (void) { - /* Initialize SysTick timer as system tick timer. */ - rt_systick_init (); - return (-1); /* Return IRQ number of SysTick timer */ -} - - -/*--------------------------- os_tick_irqack --------------------------------*/ - -__weak void os_tick_irqack (void) { - /* Acknowledge timer interrupt. */ -} - - -/*--------------------------- rt_systick ------------------------------------*/ - -extern void sysTimerTick(void); - -void rt_systick (void) { - /* Check for system clock update, suspend running task. */ - P_TCB next; - - os_tsk.run->state = READY; - rt_put_rdy_first (os_tsk.run); - - /* Check Round Robin timeout. */ - rt_chk_robin (); - - /* Update delays. */ - os_time++; - rt_dec_dly (); - - /* Check the user timers. */ -#ifdef __CMSIS_RTOS - sysTimerTick(); -#else - rt_tmr_tick (); -#endif - - /* Switch back to highest ready task */ - next = rt_get_first (&os_rdy); - rt_switch_req (next); -} - -/*--------------------------- rt_stk_check ----------------------------------*/ -__weak void rt_stk_check (void) { - /* Check for stack overflow. */ - if (os_tsk.run->task_id == 0x01) { - // TODO: For the main thread the check should be done against the main heap pointer - } else { - if ((os_tsk.run->tsk_stack < (U32)os_tsk.run->stack) || - (os_tsk.run->stack[0] != MAGIC_WORD)) { - os_error (OS_ERR_STK_OVF); - } - } -} - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx/rt_System.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_SYSTEM.H - * Purpose: System Task Manager definitions - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Variables */ -#define os_psq ((P_PSQ)&os_fifo) -extern int os_tick_irqn; - -/* Functions */ -extern U32 rt_suspend (void); -extern void rt_resume (U32 sleep_time); -extern void rt_tsk_lock (void); -extern void rt_tsk_unlock (void); -extern void rt_psh_req (void); -extern void rt_pop_req (void); -extern void rt_systick (void); -extern void rt_stk_check (void); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx/rt_Task.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,339 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_TASK.C - * Purpose: Task functions and system start up. - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Conf.h" -#include "rt_System.h" -#include "rt_Task.h" -#include "rt_List.h" -#include "rt_MemBox.h" -#include "rt_Robin.h" -#include "rt_HAL_CM.h" - -/*---------------------------------------------------------------------------- - * Global Variables - *---------------------------------------------------------------------------*/ - -/* Running and next task info. */ -struct OS_TSK os_tsk; - -/* Task Control Blocks of idle demon */ -struct OS_TCB os_idle_TCB; - - -/*---------------------------------------------------------------------------- - * Local Functions - *---------------------------------------------------------------------------*/ - -OS_TID rt_get_TID (void) { - U32 tid; - - for (tid = 1; tid <= os_maxtaskrun; tid++) { - if (os_active_TCB[tid-1] == NULL) { - return ((OS_TID)tid); - } - } - return (0); -} - -#if defined (__CC_ARM) && !defined (__MICROLIB) -/*--------------------------- __user_perthread_libspace ---------------------*/ -extern void *__libspace_start; - -void *__user_perthread_libspace (void) { - /* Provide a separate libspace for each task. */ - if (os_tsk.run == NULL) { - /* RTX not running yet. */ - return (&__libspace_start); - } - return (void *)(os_tsk.run->std_libspace); -} -#endif - -/*--------------------------- rt_init_context -------------------------------*/ - -void rt_init_context (P_TCB p_TCB, U8 priority, FUNCP task_body) { - /* Initialize general part of the Task Control Block. */ - p_TCB->cb_type = TCB; - p_TCB->state = READY; - p_TCB->prio = priority; - p_TCB->p_lnk = NULL; - p_TCB->p_rlnk = NULL; - p_TCB->p_dlnk = NULL; - p_TCB->p_blnk = NULL; - p_TCB->delta_time = 0; - p_TCB->interval_time = 0; - p_TCB->events = 0; - p_TCB->waits = 0; - p_TCB->stack_frame = 0; - - rt_init_stack (p_TCB, task_body); -} - - -/*--------------------------- rt_switch_req ---------------------------------*/ - -void rt_switch_req (P_TCB p_new) { - /* Switch to next task (identified by "p_new"). */ - os_tsk.new_tsk = p_new; - p_new->state = RUNNING; - DBG_TASK_SWITCH(p_new->task_id); -} - - -/*--------------------------- rt_dispatch -----------------------------------*/ - -void rt_dispatch (P_TCB next_TCB) { - /* Dispatch next task if any identified or dispatch highest ready task */ - /* "next_TCB" identifies a task to run or has value NULL (=no next task) */ - if (next_TCB == NULL) { - /* Running task was blocked: continue with highest ready task */ - next_TCB = rt_get_first (&os_rdy); - rt_switch_req (next_TCB); - } - else { - /* Check which task continues */ - if (next_TCB->prio > os_tsk.run->prio) { - /* preempt running task */ - rt_put_rdy_first (os_tsk.run); - os_tsk.run->state = READY; - rt_switch_req (next_TCB); - } - else { - /* put next task into ready list, no task switch takes place */ - next_TCB->state = READY; - rt_put_prio (&os_rdy, next_TCB); - } - } -} - - -/*--------------------------- rt_block --------------------------------------*/ - -void rt_block (U16 timeout, U8 block_state) { - /* Block running task and choose next ready task. */ - /* "timeout" sets a time-out value or is 0xffff (=no time-out). */ - /* "block_state" defines the appropriate task state */ - P_TCB next_TCB; - - if (timeout) { - if (timeout < 0xffff) { - rt_put_dly (os_tsk.run, timeout); - } - os_tsk.run->state = block_state; - next_TCB = rt_get_first (&os_rdy); - rt_switch_req (next_TCB); - } -} - - -/*--------------------------- rt_tsk_pass -----------------------------------*/ - -void rt_tsk_pass (void) { - /* Allow tasks of same priority level to run cooperatively.*/ - P_TCB p_new; - - p_new = rt_get_same_rdy_prio(); - if (p_new != NULL) { - rt_put_prio ((P_XCB)&os_rdy, os_tsk.run); - os_tsk.run->state = READY; - rt_switch_req (p_new); - } -} - - -/*--------------------------- rt_tsk_self -----------------------------------*/ - -OS_TID rt_tsk_self (void) { - /* Return own task identifier value. */ - if (os_tsk.run == NULL) { - return (0); - } - return (os_tsk.run->task_id); -} - - -/*--------------------------- rt_tsk_prio -----------------------------------*/ - -OS_RESULT rt_tsk_prio (OS_TID task_id, U8 new_prio) { - /* Change execution priority of a task to "new_prio". */ - P_TCB p_task; - - if (task_id == 0) { - /* Change execution priority of calling task. */ - os_tsk.run->prio = new_prio; -run:if (rt_rdy_prio() > new_prio) { - rt_put_prio (&os_rdy, os_tsk.run); - os_tsk.run->state = READY; - rt_dispatch (NULL); - } - return (OS_R_OK); - } - - /* Find the task in the "os_active_TCB" array. */ - if (task_id > os_maxtaskrun || os_active_TCB[task_id-1] == NULL) { - /* Task with "task_id" not found or not started. */ - return (OS_R_NOK); - } - p_task = os_active_TCB[task_id-1]; - p_task->prio = new_prio; - if (p_task == os_tsk.run) { - goto run; - } - rt_resort_prio (p_task); - if (p_task->state == READY) { - /* Task enqueued in a ready list. */ - p_task = rt_get_first (&os_rdy); - rt_dispatch (p_task); - } - return (OS_R_OK); -} - -/*--------------------------- rt_tsk_delete ---------------------------------*/ - -OS_RESULT rt_tsk_delete (OS_TID task_id) { - /* Terminate the task identified with "task_id". */ - P_TCB task_context; - - if (task_id == 0 || task_id == os_tsk.run->task_id) { - /* Terminate itself. */ - os_tsk.run->state = INACTIVE; - os_tsk.run->tsk_stack = rt_get_PSP (); - rt_stk_check (); - os_active_TCB[os_tsk.run->task_id-1] = NULL; - - os_tsk.run->stack = NULL; - DBG_TASK_NOTIFY(os_tsk.run, __FALSE); - os_tsk.run = NULL; - rt_dispatch (NULL); - /* The program should never come to this point. */ - } - else { - /* Find the task in the "os_active_TCB" array. */ - if (task_id > os_maxtaskrun || os_active_TCB[task_id-1] == NULL) { - /* Task with "task_id" not found or not started. */ - return (OS_R_NOK); - } - task_context = os_active_TCB[task_id-1]; - rt_rmv_list (task_context); - rt_rmv_dly (task_context); - os_active_TCB[task_id-1] = NULL; - - task_context->stack = NULL; - DBG_TASK_NOTIFY(task_context, __FALSE); - } - return (OS_R_OK); -} - - -/*--------------------------- rt_sys_init -----------------------------------*/ - -#ifdef __CMSIS_RTOS -void rt_sys_init (void) { -#else -void rt_sys_init (FUNCP first_task, U32 prio_stksz, void *stk) { -#endif - /* Initialize system and start up task declared with "first_task". */ - U32 i; - - DBG_INIT(); - - /* Initialize dynamic memory and task TCB pointers to NULL. */ - for (i = 0; i < os_maxtaskrun; i++) { - os_active_TCB[i] = NULL; - } - - /* Set up TCB of idle demon */ - os_idle_TCB.task_id = 255; - os_idle_TCB.priv_stack = idle_task_stack_size; - os_idle_TCB.stack = idle_task_stack; - rt_init_context (&os_idle_TCB, 0, os_idle_demon); - - /* Set up ready list: initially empty */ - os_rdy.cb_type = HCB; - os_rdy.p_lnk = NULL; - /* Set up delay list: initially empty */ - os_dly.cb_type = HCB; - os_dly.p_dlnk = NULL; - os_dly.p_blnk = NULL; - os_dly.delta_time = 0; - - /* Fix SP and systemvariables to assume idle task is running */ - /* Transform main program into idle task by assuming idle TCB */ -#ifndef __CMSIS_RTOS - rt_set_PSP (os_idle_TCB.tsk_stack+32); -#endif - os_tsk.run = &os_idle_TCB; - os_tsk.run->state = RUNNING; - - /* Initialize ps queue */ - os_psq->first = 0; - os_psq->last = 0; - os_psq->size = os_fifo_size; - - rt_init_robin (); - - /* Intitialize SVC and PendSV */ - rt_svc_init (); - -#ifndef __CMSIS_RTOS - /* Intitialize and start system clock timer */ - os_tick_irqn = os_tick_init (); - if (os_tick_irqn >= 0) { - OS_X_INIT(os_tick_irqn); - } - - /* Start up first user task before entering the endless loop */ - rt_tsk_create (first_task, prio_stksz, stk, NULL); -#endif -} - - -/*--------------------------- rt_sys_start ----------------------------------*/ - -#ifdef __CMSIS_RTOS -void rt_sys_start (void) { - /* Start system */ - - /* Intitialize and start system clock timer */ - os_tick_irqn = os_tick_init (); - if (os_tick_irqn >= 0) { - OS_X_INIT(os_tick_irqn); - } -} -#endif - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/rtx/rt_Task.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_TASK.H - * Purpose: Task functions and system start up. - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Definitions */ -#define __CMSIS_RTOS 1 - -/* Values for 'state' */ -#define INACTIVE 0 -#define READY 1 -#define RUNNING 2 -#define WAIT_DLY 3 -#define WAIT_ITV 4 -#define WAIT_OR 5 -#define WAIT_AND 6 -#define WAIT_SEM 7 -#define WAIT_MBX 8 -#define WAIT_MUT 9 - -/* Return codes */ -#define OS_R_TMO 0x01 -#define OS_R_EVT 0x02 -#define OS_R_SEM 0x03 -#define OS_R_MBX 0x04 -#define OS_R_MUT 0x05 - -#define OS_R_OK 0x00 -#define OS_R_NOK 0xff - -/* Variables */ -extern struct OS_TSK os_tsk; -extern struct OS_TCB os_idle_TCB; - -/* Functions */ -extern void rt_switch_req (P_TCB p_new); -extern void rt_dispatch (P_TCB next_TCB); -extern void rt_block (U16 timeout, U8 block_state); -extern void rt_tsk_pass (void); -extern OS_TID rt_tsk_self (void); -extern OS_RESULT rt_tsk_prio (OS_TID task_id, U8 new_prio); -extern OS_RESULT rt_tsk_delete (OS_TID task_id); -extern void rt_sys_init (void); -extern void rt_sys_start (void);
--- a/rtx/rt_Time.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,94 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_TIME.C - * Purpose: Delay and interval wait functions - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Conf.h" -#include "rt_Task.h" -#include "rt_Time.h" - -/*---------------------------------------------------------------------------- - * Global Variables - *---------------------------------------------------------------------------*/ - -/* Free running system tick counter */ -U32 os_time; - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_time_get -----------------------------------*/ - -U32 rt_time_get (void) { - /* Get system time tick */ - return (os_time); -} - - -/*--------------------------- rt_dly_wait -----------------------------------*/ - -void rt_dly_wait (U16 delay_time) { - /* Delay task by "delay_time" */ - rt_block (delay_time, WAIT_DLY); -} - - -/*--------------------------- rt_itv_set ------------------------------------*/ - -void rt_itv_set (U16 interval_time) { - /* Set interval length and define start of first interval */ - os_tsk.run->interval_time = interval_time; - os_tsk.run->delta_time = interval_time + (U16)os_time; -} - - -/*--------------------------- rt_itv_wait -----------------------------------*/ - -void rt_itv_wait (void) { - /* Wait for interval end and define start of next one */ - U16 delta; - - delta = os_tsk.run->delta_time - (U16)os_time; - os_tsk.run->delta_time += os_tsk.run->interval_time; - if ((delta & 0x8000) == 0) { - rt_block (delta, WAIT_ITV); - } -} - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx/rt_Time.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_TIME.H - * Purpose: Delay and interval wait functions definitions - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Variables */ -extern U32 os_time; - -/* Functions */ -extern U32 rt_time_get (void); -extern void rt_dly_wait (U16 delay_time); -extern void rt_itv_set (U16 interval_time); -extern void rt_itv_wait (void); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx/rt_TypeDef.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,128 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_TYPEDEF.H - * Purpose: Type Definitions - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ -#ifndef RT_TYPE_DEF_H -#define RT_TYPE_DEF_H - -#include "os_tcb.h" - -typedef U32 OS_TID; -typedef void *OS_ID; -typedef U32 OS_RESULT; - -#define TCB_STACKF 32 /* 'stack_frame' offset */ -#define TCB_TSTACK 36 /* 'tsk_stack' offset */ - -typedef struct OS_PSFE { /* Post Service Fifo Entry */ - void *id; /* Object Identification */ - U32 arg; /* Object Argument */ -} *P_PSFE; - -typedef struct OS_PSQ { /* Post Service Queue */ - U8 first; /* FIFO Head Index */ - U8 last; /* FIFO Tail Index */ - U8 count; /* Number of stored items in FIFO */ - U8 size; /* FIFO Size */ - struct OS_PSFE q[1]; /* FIFO Content */ -} *P_PSQ; - -typedef struct OS_TSK { - P_TCB run; /* Current running task */ - P_TCB new_tsk; /* Scheduled task to run */ -} *P_TSK; - -typedef struct OS_ROBIN { /* Round Robin Control */ - P_TCB task; /* Round Robin task */ - U16 time; /* Round Robin switch time */ - U16 tout; /* Round Robin timeout */ -} *P_ROBIN; - -typedef struct OS_XCB { - U8 cb_type; /* Control Block Type */ - struct OS_TCB *p_lnk; /* Link pointer for ready/sem. wait list */ - struct OS_TCB *p_rlnk; /* Link pointer for sem./mbx lst backwards */ - struct OS_TCB *p_dlnk; /* Link pointer for delay list */ - struct OS_TCB *p_blnk; /* Link pointer for delay list backwards */ - U16 delta_time; /* Time until time out */ -} *P_XCB; - -typedef struct OS_MCB { - U8 cb_type; /* Control Block Type */ - U8 state; /* State flag variable */ - U8 isr_st; /* State flag variable for isr functions */ - struct OS_TCB *p_lnk; /* Chain of tasks waiting for message */ - U16 first; /* Index of the message list begin */ - U16 last; /* Index of the message list end */ - U16 count; /* Actual number of stored messages */ - U16 size; /* Maximum number of stored messages */ - void *msg[1]; /* FIFO for Message pointers 1st element */ -} *P_MCB; - -typedef struct OS_SCB { - U8 cb_type; /* Control Block Type */ - U8 mask; /* Semaphore token mask */ - U16 tokens; /* Semaphore tokens */ - struct OS_TCB *p_lnk; /* Chain of tasks waiting for tokens */ -} *P_SCB; - -typedef struct OS_MUCB { - U8 cb_type; /* Control Block Type */ - U8 prio; /* Owner task default priority */ - U16 level; /* Call nesting level */ - struct OS_TCB *p_lnk; /* Chain of tasks waiting for mutex */ - struct OS_TCB *owner; /* Mutex owner task */ -} *P_MUCB; - -typedef struct OS_XTMR { - struct OS_TMR *next; - U16 tcnt; -} *P_XTMR; - -typedef struct OS_TMR { - struct OS_TMR *next; /* Link pointer to Next timer */ - U16 tcnt; /* Timer delay count */ - U16 info; /* User defined call info */ -} *P_TMR; - -typedef struct OS_BM { - void *free; /* Pointer to first free memory block */ - void *end; /* Pointer to memory block end */ - U32 blk_size; /* Memory block size */ -} *P_BM; - -/* Definitions */ -#define __TRUE 1 -#define __FALSE 0 -#define NULL ((void *) 0) - -#endif
--- a/rtx_ca/ARM/HAL_CA9.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,416 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: HAL_CA9.c - * Purpose: Hardware Abstraction Layer for Cortex-A9 - * Rev.: 3 Sept 2013 - *---------------------------------------------------------------------------- - * - * Copyright (c) 2012 - 2013 ARM Limited - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_System.h" -#include "rt_Task.h" -#include "rt_List.h" -#include "rt_MemBox.h" -#include "rt_HAL_CA.h" - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - -//For A-class, set USR/SYS stack -__asm void rt_set_PSP (U32 stack) { - ARM - - MRS R1, CPSR - CPS #MODE_SYS ;no effect in USR mode - ISB - MOV SP, R0 - MSR CPSR_c, R1 ;no effect in USR mode - ISB - BX LR - -} - -//For A-class, get USR/SYS stack -__asm U32 rt_get_PSP (void) { - ARM - - MRS R1, CPSR - CPS #MODE_SYS ;no effect in USR mode - ISB - MOV R0, SP - MSR CPSR_c, R1 ;no effect in USR mode - ISB - BX LR -} - -/*--------------------------- _alloc_box ------------------------------------*/ -__asm void *_alloc_box (void *box_mem) { - /* Function wrapper for Unprivileged/Privileged mode. */ - ARM - - LDR R12,=__cpp(rt_alloc_box) - MRS R2, CPSR - LSLS R2, #28 - BXNE R12 - SVC 0 - BX LR -} - - -/*--------------------------- _free_box -------------------------------------*/ -__asm int _free_box (void *box_mem, void *box) { - /* Function wrapper for Unprivileged/Privileged mode. */ - ARM - - LDR R12,=__cpp(rt_free_box) - MRS R2, CPSR - LSLS R2, #28 - BXNE R12 - SVC 0 - BX LR - -} - -/*-------------------------- SVC_Handler -----------------------------------*/ - -#pragma push -#pragma arm -__asm void SVC_Handler (void) { - PRESERVE8 - ARM - - IMPORT rt_tsk_lock - IMPORT rt_tsk_unlock - IMPORT SVC_Count - IMPORT SVC_Table - IMPORT rt_stk_check - IMPORT FPUEnable - -Mode_SVC EQU 0x13 - - SRSFD SP!, #Mode_SVC ; Push LR_SVC and SPRS_SVC onto SVC mode stack - PUSH {R4} ; Push R4 so we can use it as a temp - - MRS R4,SPSR ; Get SPSR - TST R4,#CPSR_T_BIT ; Check Thumb Bit - LDRNEH R4,[LR,#-2] ; Thumb: Load Halfword - BICNE R4,R4,#0xFF00 ; Extract SVC Number - LDREQ R4,[LR,#-4] ; ARM: Load Word - BICEQ R4,R4,#0xFF000000 ; Extract SVC Number - - /* Lock out systick and re-enable interrupts */ - PUSH {R0-R3,R12,LR} - - AND R12, SP, #4 ; Ensure stack is 8-byte aligned - SUB SP, SP, R12 ; Adjust stack - PUSH {R12, LR} ; Store stack adjustment and dummy LR to SVC stack - - BLX rt_tsk_lock - CPSIE i - - POP {R12, LR} ; Get stack adjustment & discard dummy LR - ADD SP, SP, R12 ; Unadjust stack - - POP {R0-R3,R12,LR} - - CMP R4,#0 - BNE SVC_User - - MRS R4,SPSR - PUSH {R4} ; Push R4 so we can use it as a temp - AND R4, SP, #4 ; Ensure stack is 8-byte aligned - SUB SP, SP, R4 ; Adjust stack - PUSH {R4, LR} ; Store stack adjustment and dummy LR - BLX R12 - POP {R4, LR} ; Get stack adjustment & discard dummy LR - ADD SP, SP, R4 ; Unadjust stack - POP {R4} ; Restore R4 - MSR SPSR_CXSF,R4 - - /* Here we will be in SVC mode (even if coming in from PendSV_Handler or OS_Tick_Handler) */ -Sys_Switch - LDR LR,=__cpp(&os_tsk) - LDM LR,{R4,LR} ; os_tsk.run, os_tsk.new - CMP R4,LR - BNE switching - - PUSH {R0-R3,R12,LR} - - AND R12, SP, #4 ; Ensure stack is 8-byte aligned - SUB SP, SP, R12 ; Adjust stack - PUSH {R12, LR} ; Store stack adjustment and dummy LR to SVC stack - - CPSID i - BLX rt_tsk_unlock - - POP {R12, LR} ; Get stack adjustment & discard dummy LR - ADD SP, SP, R12 ; Unadjust stack - - POP {R0-R3,R12,LR} - POP {R4} - RFEFD SP! ; Return from exception, no task switch - -switching - CLREX - CMP R4,#0 - ADDEQ SP,SP,#12 ; Original R4, LR & SPSR do not need to be popped when we are paging in a different task - BEQ SVC_Next ; Runtask deleted? - - - PUSH {R8-R11} //R4 and LR already stacked - MOV R10,R4 ; Preserve os_tsk.run - MOV R11,LR ; Preserve os_tsk.new - - ADD R8,SP,#16 ; Unstack R4,LR - LDMIA R8,{R4,LR} - - SUB SP,SP,#4 ; Make space on the stack for the next instn - STMIA SP,{SP}^ ; Put User SP onto stack - POP {R8} ; Pop User SP into R8 - - MRS R9,SPSR - STMDB R8!,{R9} ; User CPSR - STMDB R8!,{LR} ; User PC - STMDB R8,{LR}^ ; User LR - SUB R8,R8,#4 ; No writeback for store of User LR - STMDB R8!,{R0-R3,R12} ; User R0-R3,R12 - MOV R3,R10 ; os_tsk.run - MOV LR,R11 ; os_tsk.new - POP {R9-R12} - ADD SP,SP,#12 ; Fix up SP for unstack of R4, LR & SPSR - STMDB R8!,{R4-R7,R9-R12} ; User R4-R11 - - //If applicable, stack VFP state - MRC p15,0,R1,c1,c0,2 ; VFP/NEON access enabled? (CPACR) - AND R2,R1,#0x00F00000 - CMP R2,#0x00F00000 - BNE no_outgoing_vfp - VMRS R2,FPSCR - STMDB R8!,{R2,R4} ; Push FPSCR, maintain 8-byte alignment - VSTMDB R8!,{S0-S31} - LDRB R2,[R3,#TCB_STACKF] ; Record in TCB that VFP state is stacked - ORR R2,#2 - STRB R2,[R3,#TCB_STACKF] - -no_outgoing_vfp - STR R8,[R3,#TCB_TSTACK] - MOV R4,LR - - PUSH {R4} ; Push R4 so we can use it as a temp - AND R4, SP, #4 ; Ensure stack is 8-byte aligned - SUB SP, SP, R4 ; Adjust stack - PUSH {R4, LR} ; Store stack adjustment and dummy LR to SVC stack - - BLX rt_stk_check - - POP {R4, LR} ; Get stack adjustment & discard dummy LR - ADD SP, SP, R4 ; Unadjust stack - POP {R4} ; Restore R4 - - MOV LR,R4 - -SVC_Next //R4 == os_tsk.run, LR == os_tsk.new, R0-R3, R5-R12 corruptible - LDR R1,=__cpp(&os_tsk) ; os_tsk.run = os_tsk.new - STR LR,[R1] - LDRB R1,[LR,#TCB_TID] ; os_tsk.run->task_id - LSL R1,#8 ; Store PROCID - MCR p15,0,R1,c13,c0,1 ; Write CONTEXTIDR - - LDR R0,[LR,#TCB_TSTACK] ; os_tsk.run->tsk_stack - - //Does incoming task have VFP state in stack? - LDRB R3,[LR,#TCB_STACKF] - TST R3,#0x2 - MRC p15,0,R1,c1,c0,2 ; Read CPACR - ANDEQ R1,R1,#0xFF0FFFFF ; Disable VFP access if incoming task does not have stacked VFP state - ORRNE R1,R1,#0x00F00000 ; Enable VFP access if incoming task does have stacked VFP state - MCR p15,0,R1,c1,c0,2 ; Write CPACR - BEQ no_incoming_vfp - ISB ; We only need the sync if we enabled, otherwise we will context switch before next VFP instruction anyway - VLDMIA R0!,{S0-S31} - LDR R2,[R0] - VMSR FPSCR,R2 - ADD R0,R0,#8 - -no_incoming_vfp - LDR R1,[R0,#60] ; Restore User CPSR - MSR SPSR_CXSF,R1 - LDMIA R0!,{R4-R11} ; Restore User R4-R11 - ADD R0,R0,#4 ; Restore User R1-R3,R12 - LDMIA R0!,{R1-R3,R12} - LDMIA R0,{LR}^ ; Restore User LR - ADD R0,R0,#4 ; No writeback for load to user LR - LDMIA R0!,{LR} ; Restore User PC - ADD R0,R0,#4 ; Correct User SP for unstacked user CPSR - - PUSH {R0} ; Push R0 onto stack - LDMIA SP,{SP}^ ; Get R0 off stack into User SP - ADD SP,SP,#4 ; Put SP back - - LDR R0,[R0,#-32] ; Restore R0 - - PUSH {R0-R3,R12,LR} - - AND R12, SP, #4 ; Ensure stack is 8-byte aligned - SUB SP, SP, R12 ; Adjust stack - PUSH {R12, LR} ; Store stack adjustment and dummy LR to SVC stack - - CPSID i - BLX rt_tsk_unlock - - POP {R12, LR} ; Get stack adjustment & discard dummy LR - ADD SP, SP, R12 ; Unadjust stack - - POP {R0-R3,R12,LR} - - MOVS PC,LR ; Return from exception - - - /*------------------- User SVC -------------------------------*/ - -SVC_User - LDR R12,=SVC_Count - LDR R12,[R12] - CMP R4,R12 ; Check for overflow - BHI SVC_Done - - LDR R12,=SVC_Table-4 - LDR R12,[R12,R4,LSL #2] ; Load SVC Function Address - MRS R4,SPSR ; Save SPSR - PUSH {R4} ; Push R4 so we can use it as a temp - AND R4, SP, #4 ; Ensure stack is 8-byte aligned - SUB SP, SP, R4 ; Adjust stack - PUSH {R4, LR} ; Store stack adjustment and dummy LR - BLX R12 ; Call SVC Function - POP {R4, LR} ; Get stack adjustment & discard dummy LR - ADD SP, SP, R4 ; Unadjust stack - POP {R4} ; Restore R4 - MSR SPSR_CXSF,R4 ; Restore SPSR - -SVC_Done - PUSH {R0-R3,R12,LR} - - PUSH {R4} ; Push R4 so we can use it as a temp - AND R4, SP, #4 ; Ensure stack is 8-byte aligned - SUB SP, SP, R4 ; Adjust stack - PUSH {R4, LR} ; Store stack adjustment and dummy LR - - CPSID i - BLX rt_tsk_unlock - - POP {R4, LR} ; Get stack adjustment & discard dummy LR - ADD SP, SP, R4 ; Unadjust stack - POP {R4} ; Restore R4 - - POP {R0-R3,R12,LR} - POP {R4} - RFEFD SP! ; Return from exception -} -#pragma pop - -#pragma push -#pragma arm -__asm void PendSV_Handler (U32 IRQn) { - ARM - - IMPORT rt_tsk_lock - IMPORT IRQNestLevel - - ADD SP,SP,#8 //fix up stack pointer (R0 has been pushed and will never be popped, R1 was pushed for stack alignment) - - //Disable systick interrupts, then write EOIR. We want interrupts disabled before we enter the context switcher. - PUSH {R0, R1} - BLX rt_tsk_lock - POP {R0, R1} - LDR R1, =__cpp(&GICInterface_BASE) - LDR R1, [R1, #0] - STR R0, [R1, #0x10] - - LDR R0, =IRQNestLevel ; Get address of nesting counter - LDR R1, [R0] - SUB R1, R1, #1 ; Decrement nesting counter - STR R1, [R0] - - BLX __cpp(rt_pop_req) - - POP {R1, LR} ; Get stack adjustment & discard dummy LR - ADD SP, SP, R1 ; Unadjust stack - - LDR R0,[SP,#24] - MSR SPSR_CXSF,R0 - POP {R0-R3,R12} ; Leave SPSR & LR on the stack - PUSH {R4} - B Sys_Switch -} -#pragma pop - - -#pragma push -#pragma arm -__asm void OS_Tick_Handler (U32 IRQn) { - ARM - - IMPORT rt_tsk_lock - IMPORT IRQNestLevel - - ADD SP,SP,#8 //fix up stack pointer (R0 has been pushed and will never be popped, R1 was pushed for stack alignment) - - PUSH {R0, R1} - BLX rt_tsk_lock - POP {R0, R1} - LDR R1, =__cpp(&GICInterface_BASE) - LDR R1, [R1, #0] - STR R0, [R1, #0x10] - - LDR R0, =IRQNestLevel ; Get address of nesting counter - LDR R1, [R0] - SUB R1, R1, #1 ; Decrement nesting counter - STR R1, [R0] - - BLX __cpp(os_tick_irqack) - BLX __cpp(rt_systick) - - POP {R1, LR} ; Get stack adjustment & discard dummy LR - ADD SP, SP, R1 ; Unadjust stack - - LDR R0,[SP,#24] - MSR SPSR_CXSF,R0 - POP {R0-R3,R12} ; Leave SPSR & LR on the stack - PUSH {R4} - B Sys_Switch -} -#pragma pop - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/rtx_ca/ARM/SVC_Table.s Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -;/*---------------------------------------------------------------------------- -; * RL-ARM - RTX -; *---------------------------------------------------------------------------- -; * Name: SVC_TABLE.S -; * Purpose: Pre-defined SVC Table for Cortex-M -; * Rev.: V4.60 -; *---------------------------------------------------------------------------- -; * -; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH -; * All rights reserved. -; * Redistribution and use in source and binary forms, with or without -; * modification, are permitted provided that the following conditions are met: -; * - Redistributions of source code must retain the above copyright -; * notice, this list of conditions and the following disclaimer. -; * - Redistributions in binary form must reproduce the above copyright -; * notice, this list of conditions and the following disclaimer in the -; * documentation and/or other materials provided with the distribution. -; * - Neither the name of ARM nor the names of its contributors may be used -; * to endorse or promote products derived from this software without -; * specific prior written permission. -; * -; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE -; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -; * POSSIBILITY OF SUCH DAMAGE. -; *---------------------------------------------------------------------------*/ - - - AREA SVC_TABLE, CODE, READONLY - - EXPORT SVC_Count - -SVC_Cnt EQU (SVC_End-SVC_Table)/4 -SVC_Count DCD SVC_Cnt - -; Import user SVC functions here. -; IMPORT __SVC_1 - - EXPORT SVC_Table -SVC_Table -; Insert user SVC functions here. SVC 0 used by RTL Kernel. -; DCD __SVC_1 ; InitMemorySubsystem - -SVC_End - - END - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/rtx_ca/HAL_CA.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,126 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: HAL_CA.C - * Purpose: Hardware Abstraction Layer for Cortex-A - * Rev.: - *---------------------------------------------------------------------------- - * - * Copyright (c) 2012 ARM Limited - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_HAL_CA.h" - -/*--------------------------- os_init_context -------------------------------*/ - -void rt_init_stack (P_TCB p_TCB, FUNCP task_body) { - /* Prepare TCB and saved context for a first time start of a task. */ - U32 *stk,i,size; - - /* Prepare a complete interrupt frame for first task start */ - size = p_TCB->priv_stack >> 2; - if (size == 0) { - size = (U16)os_stackinfo >> 2; - } - /* Write to the top of stack. */ - stk = &p_TCB->stack[size]; - - /* Auto correct to 8-byte ARM stack alignment. */ - if ((U32)stk & 0x04) { - stk--; - } - - stk -= 16; - - /* Initial PC and default CPSR */ - stk[14] = (U32)task_body; - /* Task run mode is inherited from the startup file. */ - /* (non-privileged USER or privileged SYSTEM mode) */ - stk[15] = (os_flags & 1) ? INIT_CPSR_SYS : INIT_CPSR_USER; - /* Set T-bit if task function in Thumb mode. */ - if ((U32)task_body & 1) { - stk[15] |= CPSR_T_BIT; - } - /* Assign a void pointer to R0. */ - stk[8] = (U32)p_TCB->msg; - /* Clear R1-R12,LR registers. */ - for (i = 0; i < 8; i++) { - stk[i] = 0; - } - for (i = 9; i < 14; i++) { - stk[i] = 0; - } - - /* Initial Task stack pointer. */ - p_TCB->tsk_stack = (U32)stk; - - /* Task entry point. */ - p_TCB->ptask = task_body; - - /* Set a magic word for checking of stack overflow. */ - p_TCB->stack[0] = MAGIC_WORD; -} - - -/*--------------------------- rt_ret_val ----------------------------------*/ - -static __inline U32 *rt_ret_regs (P_TCB p_TCB) { - /* Get pointer to task return value registers (R0..R3) in Stack */ -#if (__TARGET_FPU_VFP) - if (p_TCB->stack_frame & 0x2) { - /* Extended Stack Frame: S0-31,FPSCR,Reserved,R4-R11,R0-R3,R12,LR,PC,xPSR */ - return (U32 *)(p_TCB->tsk_stack + 8*4 + 34*4); - } else { - /* Basic Stack Frame: R4-R11,R0-R3,R12,LR,PC,xPSR */ - return (U32 *)(p_TCB->tsk_stack + 8*4); - } -#else - /* Stack Frame: R4-R11,R0-R3,R12,LR,PC,xPSR */ - return (U32 *)(p_TCB->tsk_stack + 8*4); -#endif -} - -void rt_ret_val (P_TCB p_TCB, U32 v0) { - U32 *ret; - - ret = rt_ret_regs(p_TCB); - ret[0] = v0; -} - -void rt_ret_val2(P_TCB p_TCB, U32 v0, U32 v1) { - U32 *ret; - - ret = rt_ret_regs(p_TCB); - ret[0] = v0; - ret[1] = v1; -} - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/rtx_ca/HAL_CM.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,168 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: HAL_CM.C - * Purpose: Hardware Abstraction Layer for Cortex-M - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_HAL_CM.h" - - -/*---------------------------------------------------------------------------- - * Global Variables - *---------------------------------------------------------------------------*/ - -#ifdef DBG_MSG -BIT dbg_msg; -#endif - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_init_stack ---------------------------------*/ - -void rt_init_stack (P_TCB p_TCB, FUNCP task_body) { - /* Prepare TCB and saved context for a first time start of a task. */ - U32 *stk,i,size; - - /* Prepare a complete interrupt frame for first task start */ - size = p_TCB->priv_stack >> 2; - if (size == 0) { - size = (U16)os_stackinfo >> 2; - } - - /* Write to the top of stack. */ - stk = &p_TCB->stack[size]; - - /* Auto correct to 8-byte ARM stack alignment. */ - if ((U32)stk & 0x04) { - stk--; - } - - stk -= 16; - - /* Default xPSR and initial PC */ - stk[15] = INITIAL_xPSR; - stk[14] = (U32)task_body; - - /* Clear R4-R11,R0-R3,R12,LR registers. */ - for (i = 0; i < 14; i++) { - stk[i] = 0; - } - - /* Assign a void pointer to R0. */ - stk[8] = (U32)p_TCB->msg; - - /* Initial Task stack pointer. */ - p_TCB->tsk_stack = (U32)stk; - - /* Task entry point. */ - p_TCB->ptask = task_body; - - /* Set a magic word for checking of stack overflow. */ - p_TCB->stack[0] = MAGIC_WORD; -} - - -/*--------------------------- rt_ret_val ----------------------------------*/ - -static __inline U32 *rt_ret_regs (P_TCB p_TCB) { - /* Get pointer to task return value registers (R0..R3) in Stack */ -#if (__TARGET_FPU_VFP) - if (p_TCB->stack_frame) { - /* Extended Stack Frame: R4-R11,S16-S31,R0-R3,R12,LR,PC,xPSR,S0-S15,FPSCR */ - return (U32 *)(p_TCB->tsk_stack + 8*4 + 16*4); - } else { - /* Basic Stack Frame: R4-R11,R0-R3,R12,LR,PC,xPSR */ - return (U32 *)(p_TCB->tsk_stack + 8*4); - } -#else - /* Stack Frame: R4-R11,R0-R3,R12,LR,PC,xPSR */ - return (U32 *)(p_TCB->tsk_stack + 8*4); -#endif -} - -void rt_ret_val (P_TCB p_TCB, U32 v0) { - U32 *ret; - - ret = rt_ret_regs(p_TCB); - ret[0] = v0; -} - -void rt_ret_val2(P_TCB p_TCB, U32 v0, U32 v1) { - U32 *ret; - - ret = rt_ret_regs(p_TCB); - ret[0] = v0; - ret[1] = v1; -} - - -/*--------------------------- dbg_init --------------------------------------*/ - -#ifdef DBG_MSG -void dbg_init (void) { - if ((DEMCR & DEMCR_TRCENA) && - (ITM_CONTROL & ITM_ITMENA) && - (ITM_ENABLE & (1UL << 31))) { - dbg_msg = __TRUE; - } -} -#endif - -/*--------------------------- dbg_task_notify -------------------------------*/ - -#ifdef DBG_MSG -void dbg_task_notify (P_TCB p_tcb, BOOL create) { - while (ITM_PORT31_U32 == 0); - ITM_PORT31_U32 = (U32)p_tcb->ptask; - while (ITM_PORT31_U32 == 0); - ITM_PORT31_U16 = (create << 8) | p_tcb->task_id; -} -#endif - -/*--------------------------- dbg_task_switch -------------------------------*/ - -#ifdef DBG_MSG -void dbg_task_switch (U32 task_id) { - while (ITM_PORT31_U32 == 0); - ITM_PORT31_U8 = task_id; -} -#endif - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx_ca/RTX_CM_lib.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,423 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RTX_CM_LIB.H - * Purpose: RTX Kernel System Configuration - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#if defined (__CC_ARM) -#pragma O3 -#define __USED __attribute__((used)) -#elif defined (__GNUC__) -#pragma GCC optimize ("O3") -#define __USED __attribute__((used)) -#elif defined (__ICCARM__) -#define __USED __root -#endif - - -/*---------------------------------------------------------------------------- - * Definitions - *---------------------------------------------------------------------------*/ - -#define _declare_box(pool,size,cnt) uint32_t pool[(((size)+3)/4)*(cnt) + 3] -#define _declare_box8(pool,size,cnt) uint64_t pool[(((size)+7)/8)*(cnt) + 2] - -#define OS_TCB_SIZE 48 -#define OS_TMR_SIZE 8 - -#if defined (__CC_ARM) && !defined (__MICROLIB) - -typedef void *OS_ID; -typedef uint32_t OS_TID; -typedef uint32_t OS_MUT[3]; -typedef uint32_t OS_RESULT; - -#define runtask_id() rt_tsk_self() -#define mutex_init(m) rt_mut_init(m) -#define mutex_wait(m) os_mut_wait(m,0xFFFF) -#define mutex_rel(m) os_mut_release(m) - -extern OS_TID rt_tsk_self (void); -extern void rt_mut_init (OS_ID mutex); -extern OS_RESULT rt_mut_release (OS_ID mutex); -extern OS_RESULT rt_mut_wait (OS_ID mutex, uint16_t timeout); - -#define os_mut_wait(mutex,timeout) _os_mut_wait((uint32_t)rt_mut_wait,mutex,timeout) -#define os_mut_release(mutex) _os_mut_release((uint32_t)rt_mut_release,mutex) - -OS_RESULT _os_mut_release (uint32_t p, OS_ID mutex) __svc_indirect(0); -OS_RESULT _os_mut_wait (uint32_t p, OS_ID mutex, uint16_t timeout) __svc_indirect(0); - -#endif - - -/*---------------------------------------------------------------------------- - * Global Variables - *---------------------------------------------------------------------------*/ - -#if (OS_TIMERS != 0) -#define OS_TASK_CNT (OS_TASKCNT + 1) -#define OS_PRIV_CNT (OS_PRIVCNT + 2) -#define OS_STACK_SZ (4*(OS_PRIVSTKSIZE+OS_MAINSTKSIZE+OS_TIMERSTKSZ)) -#else -#define OS_TASK_CNT OS_TASKCNT -#define OS_PRIV_CNT (OS_PRIVCNT + 1) -#define OS_STACK_SZ (4*(OS_PRIVSTKSIZE+OS_MAINSTKSIZE)) -#endif - -uint16_t const os_maxtaskrun = OS_TASK_CNT; -uint32_t const os_stackinfo = (OS_STKCHECK<<24)| (OS_PRIV_CNT<<16) | (OS_STKSIZE*4); -uint32_t const os_rrobin = (OS_ROBIN << 16) | OS_ROBINTOUT; -uint32_t const os_trv = OS_TRV; -uint8_t const os_flags = OS_RUNPRIV; - -/* Export following defines to uVision debugger. */ -__USED uint32_t const os_clockrate = OS_TICK; -__USED uint32_t const os_timernum = 0; - -/* Memory pool for TCB allocation */ -_declare_box (mp_tcb, OS_TCB_SIZE, OS_TASK_CNT); -uint16_t const mp_tcb_size = sizeof(mp_tcb); - -/* Memory pool for System stack allocation (+os_idle_demon). */ -_declare_box8 (mp_stk, OS_STKSIZE*4, OS_TASK_CNT-OS_PRIV_CNT+1); -uint32_t const mp_stk_size = sizeof(mp_stk); - -/* Memory pool for user specified stack allocation (+main, +timer) */ -uint64_t os_stack_mem[2+OS_PRIV_CNT+(OS_STACK_SZ/8)]; -uint32_t const os_stack_sz = sizeof(os_stack_mem); - -#ifndef OS_FIFOSZ - #define OS_FIFOSZ 16 -#endif - -/* Fifo Queue buffer for ISR requests.*/ -uint32_t os_fifo[OS_FIFOSZ*2+1]; -uint8_t const os_fifo_size = OS_FIFOSZ; - -/* An array of Active task pointers. */ -void *os_active_TCB[OS_TASK_CNT]; - -/* User Timers Resources */ -#if (OS_TIMERS != 0) -extern void osTimerThread (void const *argument); -#if defined (__MBED_CMSIS_RTOS_CA9) -osThreadDef(osTimerThread, (osPriority)(OS_TIMERPRIO-3), 4*OS_TIMERSTKSZ); -#else -osThreadDef(osTimerThread, (osPriority)(OS_TIMERPRIO-3), 1, 4*OS_TIMERSTKSZ); -#endif -osThreadId osThreadId_osTimerThread; -osMessageQDef(osTimerMessageQ, OS_TIMERCBQS, void *); -osMessageQId osMessageQId_osTimerMessageQ; -#else -osThreadDef_t os_thread_def_osTimerThread = { NULL }; -osThreadId osThreadId_osTimerThread; -osMessageQDef(osTimerMessageQ, 0, void *); -osMessageQId osMessageQId_osTimerMessageQ; -#endif - -/* Legacy RTX User Timers not used */ -uint32_t os_tmr = 0; -uint32_t const *m_tmr = NULL; -uint16_t const mp_tmr_size = 0; - -#if defined (__CC_ARM) && !defined (__MICROLIB) - /* A memory space for arm standard library. */ - static uint32_t std_libspace[OS_TASK_CNT][96/4]; - static OS_MUT std_libmutex[OS_MUTEXCNT]; - static uint32_t nr_mutex; - extern void *__libspace_start; -#endif - - -/*---------------------------------------------------------------------------- - * RTX Optimizations (empty functions) - *---------------------------------------------------------------------------*/ - -#if OS_ROBIN == 0 - void rt_init_robin (void) {;} - void rt_chk_robin (void) {;} -#endif - -#if OS_STKCHECK == 0 - void rt_stk_check (void) {;} -#endif - - -/*---------------------------------------------------------------------------- - * Standard Library multithreading interface - *---------------------------------------------------------------------------*/ - -#if defined (__CC_ARM) && !defined (__MICROLIB) - -/*--------------------------- __user_perthread_libspace ---------------------*/ - -void *__user_perthread_libspace (void) { - /* Provide a separate libspace for each task. */ - uint32_t idx; - - idx = runtask_id (); - if (idx == 0) { - /* RTX not running yet. */ - return (&__libspace_start); - } - return ((void *)&std_libspace[idx-1]); -} - -/*--------------------------- _mutex_initialize -----------------------------*/ - -int _mutex_initialize (OS_ID *mutex) { - /* Allocate and initialize a system mutex. */ - - if (nr_mutex >= OS_MUTEXCNT) { - /* If you are here, you need to increase the number OS_MUTEXCNT. */ - for (;;); - } - *mutex = &std_libmutex[nr_mutex++]; - mutex_init (*mutex); - return (1); -} - - -/*--------------------------- _mutex_acquire --------------------------------*/ - -__attribute__((used)) void _mutex_acquire (OS_ID *mutex) { - /* Acquire a system mutex, lock stdlib resources. */ - if (runtask_id ()) { - /* RTX running, acquire a mutex. */ - mutex_wait (*mutex); - } -} - - -/*--------------------------- _mutex_release --------------------------------*/ - -__attribute__((used)) void _mutex_release (OS_ID *mutex) { - /* Release a system mutex, unlock stdlib resources. */ - if (runtask_id ()) { - /* RTX running, release a mutex. */ - mutex_rel (*mutex); - } -} - -#endif - - -/*---------------------------------------------------------------------------- - * RTX Startup - *---------------------------------------------------------------------------*/ - -/* Main Thread definition */ -extern int main (void); -osThreadDef_t os_thread_def_main = {(os_pthread)main, osPriorityNormal, 1, 4*OS_MAINSTKSIZE }; - - -#if defined (__CC_ARM) - -#ifdef __MICROLIB -void _main_init (void) __attribute__((section(".ARM.Collect$$$$000000FF"))); -#if __TARGET_ARCH_ARM -#pragma push -#pragma arm -#endif -void _main_init (void) { - osKernelInitialize(); - osThreadCreate(&os_thread_def_main, NULL); - osKernelStart(); - for (;;); -} -#if __TARGET_ARCH_ARM -#pragma pop -#endif -#else -#if 0 -//#ifdef __MBED_CMSIS_RTOS_CA9 -__asm void __rt_entry (void) { - - IMPORT __user_setup_stackheap - IMPORT __rt_lib_init - IMPORT os_thread_def_main - IMPORT osKernelInitialize - IMPORT osKernelStart - IMPORT osThreadCreate - IMPORT InterruptHandlerRegister - IMPORT PendSV_Handler - IMPORT OS_Tick_Handler - IMPORT exit - - BL __user_setup_stackheap - MOV R1,R2 - BL __rt_lib_init - BL osKernelInitialize - LDR R0,=os_thread_def_main - MOVS R1,#0 - BL osThreadCreate - BL osKernelStart - MOVS R0,#0 - LDR R1,=PendSV_Handler - BL InterruptHandlerRegister - MOVS R0,#134 - LDR R1,=OS_Tick_Handler - BL InterruptHandlerRegister - BL exit - - ALIGN -} -#else -__asm void __rt_entry (void) { - - IMPORT __user_setup_stackheap - IMPORT __rt_lib_init - IMPORT os_thread_def_main - IMPORT osKernelInitialize - IMPORT osKernelStart - IMPORT osThreadCreate - IMPORT exit - - BL __user_setup_stackheap - MOV R1,R2 - BL __rt_lib_init - BL osKernelInitialize - LDR R0,=os_thread_def_main - MOVS R1,#0 - BL osThreadCreate - BL osKernelStart - BL exit - - ALIGN -} -#endif -#endif - -#elif defined (__GNUC__) - -#ifdef __CS3__ - -/* CS3 start_c routine. - * - * Copyright (c) 2006, 2007 CodeSourcery Inc - * - * The authors hereby grant permission to use, copy, modify, distribute, - * and license this software and its documentation for any purpose, provided - * that existing copyright notices are retained in all copies and that this - * notice is included verbatim in any distributions. No written agreement, - * license, or royalty fee is required for any of the authorized uses. - * Modifications to this software may be copyrighted by their authors - * and need not follow the licensing terms described here, provided that - * the new terms are clearly indicated on the first page of each file where - * they apply. - */ - -#include "cs3.h" - -extern void __libc_init_array (void); - -__attribute ((noreturn)) void __cs3_start_c (void){ - unsigned regions = __cs3_region_num; - const struct __cs3_region *rptr = __cs3_regions; - - /* Initialize memory */ - for (regions = __cs3_region_num, rptr = __cs3_regions; regions--; rptr++) { - long long *src = (long long *)rptr->init; - long long *dst = (long long *)rptr->data; - unsigned limit = rptr->init_size; - unsigned count; - - if (src != dst) - for (count = 0; count != limit; count += sizeof (long long)) - *dst++ = *src++; - else - dst = (long long *)((char *)dst + limit); - limit = rptr->zero_size; - for (count = 0; count != limit; count += sizeof (long long)) - *dst++ = 0; - } - - /* Run initializers. */ - __libc_init_array (); - - osKernelInitialize(); - osThreadCreate(&os_thread_def_main, NULL); - osKernelStart(); - for (;;); -} - -#else - -__attribute__((naked)) void software_init_hook (void) { - __asm ( - ".syntax unified\n" - ".thumb\n" - "movs r0,#0\n" - "movs r1,#0\n" - "mov r4,r0\n" - "mov r5,r1\n" - "ldr r0,= __libc_fini_array\n" - "bl atexit\n" - "bl __libc_init_array\n" - "mov r0,r4\n" - "mov r1,r5\n" - "bl osKernelInitialize\n" - "ldr r0,=os_thread_def_main\n" - "movs r1,#0\n" - "bl osThreadCreate\n" - "bl osKernelStart\n" - "bl exit\n" - ); -} - -#endif - -#elif defined (__ICCARM__) - -extern int __low_level_init(void); -extern void __iar_data_init3(void); -extern void exit(int arg); - -__noreturn __stackless void __cmain(void) { - int a; - - if (__low_level_init() != 0) { - __iar_data_init3(); - } - osKernelInitialize(); - osThreadCreate(&os_thread_def_main, NULL); - a = osKernelStart(); - exit(a); -} - -#endif - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx_ca/RTX_Conf_CA.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,319 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RTX_Conf_CM.C - * Purpose: Configuration of CMSIS RTX Kernel - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "cmsis_os.h" - -/*---------------------------------------------------------------------------- - * RTX User configuration part BEGIN - *---------------------------------------------------------------------------*/ - -//-------- <<< Use Configuration Wizard in Context Menu >>> ----------------- -// -// <h>Thread Configuration -// ======================= -// -// <o>Number of concurrent running threads <0-250> -// <i> Defines max. number of threads that will run at the same time. -// <i> Default: 6 -#ifndef OS_TASKCNT - #define OS_TASKCNT 25 -#endif - -// <o>Default Thread stack size [bytes] <64-4096:8><#/4> -// <i> Defines default stack size for threads with osThreadDef stacksz = 0 -// <i> Default: 200 -#ifndef OS_STKSIZE - #define OS_STKSIZE 200 -#endif - -// <o>Main Thread stack size [bytes] <64-4096:8><#/4> -// <i> Defines stack size for main thread. -// <i> Default: 200 -#ifndef OS_MAINSTKSIZE - #define OS_MAINSTKSIZE 512 -#endif - -// <o>Number of threads with user-provided stack size <0-250> -// <i> Defines the number of threads with user-provided stack size. -// <i> Default: 0 -#ifndef OS_PRIVCNT - #define OS_PRIVCNT 8 -#endif - -// <o>Total stack size [bytes] for threads with user-provided stack size <0-4096:8><#/4> -// <i> Defines the combined stack size for threads with user-provided stack size. -// <i> Default: 0 -#ifndef OS_PRIVSTKSIZE - #define OS_PRIVSTKSIZE 4096 -#endif - -// <q>Check for stack overflow -// <i> Includes the stack checking code for stack overflow. -// <i> Note that additional code reduces the Kernel performance. -#ifndef OS_STKCHECK - #define OS_STKCHECK 1 -#endif - -// <o>Processor mode for thread execution -// <0=> Unprivileged mode -// <1=> Privileged mode -// <i> Default: Privileged mode -#ifndef OS_RUNPRIV - #define OS_RUNPRIV 0 -#endif - -// </h> - -// <h>RTX Kernel Timer Tick Configuration -// ====================================== -// <q> Use Cortex-M SysTick timer as RTX Kernel Timer -// <i> Use the Cortex-M SysTick timer as a time-base for RTX. -#ifndef OS_SYSTICK - #define OS_SYSTICK 0 -#endif -// -// <o>Timer clock value [Hz] <1-1000000000> -// <i> Defines the timer clock value. -// <i> Default: 12000000 (12MHz) -#ifndef OS_CLOCK - #define OS_CLOCK 12000000 -#endif - -// <o>Timer tick value [us] <1-1000000> -// <i> Defines the timer tick value. -// <i> Default: 1000 (1ms) -#ifndef OS_TICK - #define OS_TICK 1000 -#endif - -// </h> - -// <h>System Configuration -// ======================= -// -// <e>Round-Robin Thread switching -// =============================== -// -// <i> Enables Round-Robin Thread switching. -#ifndef OS_ROBIN - #define OS_ROBIN 1 -#endif - -// <o>Round-Robin Timeout [ticks] <1-1000> -// <i> Defines how long a thread will execute before a thread switch. -// <i> Default: 5 -#ifndef OS_ROBINTOUT - #define OS_ROBINTOUT 5 -#endif - -// </e> - -// <e>User Timers -// ============== -// <i> Enables user Timers -#ifndef OS_TIMERS - #define OS_TIMERS 1 -#endif - -// <o>Timer Thread Priority -// <1=> Low -// <2=> Below Normal <3=> Normal <4=> Above Normal -// <5=> High -// <6=> Realtime (highest) -// <i> Defines priority for Timer Thread -// <i> Default: High -#ifndef OS_TIMERPRIO - #define OS_TIMERPRIO 5 -#endif - -// <o>Timer Thread stack size [bytes] <64-4096:8><#/4> -// <i> Defines stack size for Timer thread. -// <i> Default: 200 -#ifndef OS_TIMERSTKSZ - #define OS_TIMERSTKSZ 400 -#endif - -// <o>Timer Callback Queue size <1-32> -// <i> Number of concurrent active timer callback functions. -// <i> Default: 4 -#ifndef OS_TIMERCBQS - #define OS_TIMERCBQS 4 -#endif - -// </e> - -// <o>ISR FIFO Queue size<4=> 4 entries <8=> 8 entries -// <12=> 12 entries <16=> 16 entries -// <24=> 24 entries <32=> 32 entries -// <48=> 48 entries <64=> 64 entries -// <96=> 96 entries -// <i> ISR functions store requests to this buffer, -// <i> when they are called from the interrupt handler. -// <i> Default: 16 entries -#ifndef OS_FIFOSZ - #define OS_FIFOSZ 16 -#endif - -// </h> - -//------------- <<< end of configuration section >>> ----------------------- - -// Standard library system mutexes -// =============================== -// Define max. number system mutexes that are used to protect -// the arm standard runtime library. For microlib they are not used. -#ifndef OS_MUTEXCNT - #define OS_MUTEXCNT 8 -#endif - -/*---------------------------------------------------------------------------- - * RTX User configuration part END - *---------------------------------------------------------------------------*/ - -#define OS_TRV ((uint32_t)(((double)OS_CLOCK*(double)OS_TICK)/1E6)-1) - - -/*---------------------------------------------------------------------------- - * Global Functions - *---------------------------------------------------------------------------*/ - -/*--------------------------- os_idle_demon ---------------------------------*/ - -void os_idle_demon (void) { - /* The idle demon is a system thread, running when no other thread is */ - /* ready to run. */ - - for (;;) { - /* HERE: include optional user code to be executed when no thread runs.*/ -#if 0 - __DSB(); - __WFI(); -#endif - } -} - -#if (OS_SYSTICK == 0) // Functions for alternative timer as RTX kernel timer - -/*--------------------------- os_tick_init ----------------------------------*/ -#ifdef TARGET_RZ_A1H -#define OSTM0 (0xFCFEC000uL) /* OSTM0 */ -#define OSTM1 (0xFCFEC400uL) /* OSTM1 */ -#define CPG (0xFCFE0410uL) /* CPG */ - -#define CPGSTBCR5 (*((volatile unsigned char*)(CPG + 0x00000018uL))) - -#define OSTM0CMP (*((volatile unsigned long*)(OSTM0 + 0x00000000uL))) -#define OSTM0CNT (*((volatile unsigned long*)(OSTM0 + 0x00000004uL))) -#define OSTM0TE (*((volatile unsigned char*)(OSTM0 + 0x00000010uL))) -#define OSTM0TS (*((volatile unsigned char*)(OSTM0 + 0x00000014uL))) -#define OSTM0TT (*((volatile unsigned char*)(OSTM0 + 0x00000018uL))) -#define OSTM0CTL (*((volatile unsigned char*)(OSTM0 + 0x00000020uL))) - -#define OSTM1CMP (*((volatile unsigned long*)(OSTM1 + 0x00000000uL))) -#define OSTM1CNT (*((volatile unsigned long*)(OSTM1 + 0x00000004uL))) -#define OSTM1TE (*((volatile unsigned char*)(OSTM1 + 0x00000010uL))) -#define OSTM1TS (*((volatile unsigned char*)(OSTM1 + 0x00000014uL))) -#define OSTM1TT (*((volatile unsigned char*)(OSTM1 + 0x00000018uL))) -#define OSTM1CTL (*((volatile unsigned char*)(OSTM1 + 0x00000020uL))) - -#define CPG_STBCR5_BIT_MSTP51 (0x02u) /* OSTM0 */ -#define CM1_RENESAS_RZ_A1_P0_CLK ( 32000000u) -#define CM0_RENESAS_RZ_A1_P0_CLK ( 33333333u) - -typedef enum -{ - IRQ_SGI0 = 0, - IRQ_OSTMI0TINT = 134 -} IRQn_Type; - -typedef void(*IRQHandler)(); - -extern void PendSV_Handler(uint32_t); -extern void OS_Tick_Handler(uint32_t); -extern uint32_t InterruptHandlerRegister (IRQn_Type irq, IRQHandler handler); -#endif - -// Initialize alternative hardware timer as RTX kernel timer -// Return: IRQ number of the alternative hardware timer -int os_tick_init (void) { -#ifdef TARGET_RZ_A1H - CPGSTBCR5 &= ~(CPG_STBCR5_BIT_MSTP51); /* enable OSTM0 clock */ - - OSTM0TT = 0x1; /* Stop the counter and clears the OSTM0TE bit. */ - OSTM0CTL = 0x1; /* Interval timer mode. Interrupt enabled */ - - OSTM0CMP = (uint32_t)(((double)CM0_RENESAS_RZ_A1_P0_CLK*(double)OS_TICK)/1E6); - - OSTM0TS = 0x1; /* Start the counter and sets the OSTM0TE bit. */ - - InterruptHandlerRegister(IRQ_SGI0 , (IRQHandler)PendSV_Handler); - InterruptHandlerRegister(IRQ_OSTMI0TINT, (IRQHandler)OS_Tick_Handler); - - - return IRQ_OSTMI0TINT; /* Return IRQ number of timer (0..239) */ - /* RTX will set and configure the interrupt */ -#endif -} - -/*--------------------------- os_tick_irqack --------------------------------*/ - -// Acknowledge alternative hardware timer interrupt -void os_tick_irqack (void) { - /* ... */ -} - -#endif // (OS_SYSTICK == 0) - -/*--------------------------- os_error --------------------------------------*/ -extern void mbed_die(void); - -void os_error (uint32_t err_code) { - /* This function is called when a runtime error is detected. Parameter */ - /* 'err_code' holds the runtime error code (defined in RTL.H). */ - mbed_die(); - - /* HERE: include optional code to be executed on runtime error. */ - for (;;); -} - - -/*---------------------------------------------------------------------------- - * RTX Configuration Functions - *---------------------------------------------------------------------------*/ - -#include "RTX_CM_lib.h" - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/rtx_ca/RTX_Config.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RTX_CONFIG.H - * Purpose: Exported functions of RTX_Config.c - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - - -/* Error Codes */ -#define OS_ERR_STK_OVF 1 -#define OS_ERR_FIFO_OVF 2 -#define OS_ERR_MBX_OVF 3 - -/* Definitions */ -#define BOX_ALIGN_8 0x80000000 -#define _declare_box(pool,size,cnt) U32 pool[(((size)+3)/4)*(cnt) + 3] -#define _declare_box8(pool,size,cnt) U64 pool[(((size)+7)/8)*(cnt) + 2] -#define _init_box8(pool,size,bsize) _init_box (pool,size,(bsize) | BOX_ALIGN_8) - -/* Variables */ -extern U32 mp_tcb[]; -extern U64 mp_stk[]; -extern U32 os_fifo[]; -extern void *os_active_TCB[]; - -/* Constants */ -extern U16 const os_maxtaskrun; -extern U32 const os_trv; -extern U8 const os_flags; -extern U32 const os_stackinfo; -extern U32 const os_rrobin; -extern U32 const os_clockrate; -extern U32 const os_timernum; -extern U16 const mp_tcb_size; -extern U32 const mp_stk_size; -extern U32 const *m_tmr; -extern U16 const mp_tmr_size; -extern U8 const os_fifo_size; - -/* Functions */ -extern void os_idle_demon (void); -extern int os_tick_init (void); -extern void os_tick_irqack (void); -extern void os_tmr_call (U16 info); -extern void os_error (U32 err_code); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/rtx_ca/cmsis_os.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,803 +0,0 @@ -/* ---------------------------------------------------------------------- - * $Date: 5. June 2012 - * $Revision: V1.01 - * - * Project: CMSIS-RTOS API - * Title: cmsis_os.h RTX header file - * - * Version 0.02 - * Initial Proposal Phase - * Version 0.03 - * osKernelStart added, optional feature: main started as thread - * osSemaphores have standard behavior - * osTimerCreate does not start the timer, added osTimerStart - * osThreadPass is renamed to osThreadYield - * Version 1.01 - * Support for C++ interface - * - const attribute removed from the osXxxxDef_t typedef's - * - const attribute added to the osXxxxDef macros - * Added: osTimerDelete, osMutexDelete, osSemaphoreDelete - * Added: osKernelInitialize - *---------------------------------------------------------------------------- - * - * Copyright (c) 2012 ARM LIMITED - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/** -\page cmsis_os_h Header File Template: cmsis_os.h - -The file \b cmsis_os.h is a template header file for a CMSIS-RTOS compliant Real-Time Operating System (RTOS). -Each RTOS that is compliant with CMSIS-RTOS shall provide a specific \b cmsis_os.h header file that represents -its implementation. - -The file cmsis_os.h contains: - - CMSIS-RTOS API function definitions - - struct definitions for parameters and return types - - status and priority values used by CMSIS-RTOS API functions - - macros for defining threads and other kernel objects - - -<b>Name conventions and header file modifications</b> - -All definitions are prefixed with \b os to give an unique name space for CMSIS-RTOS functions. -Definitions that are prefixed \b os_ are not used in the application code but local to this header file. -All definitions and functions that belong to a module are grouped and have a common prefix, i.e. \b osThread. - -Definitions that are marked with <b>CAN BE CHANGED</b> can be adapted towards the needs of the actual CMSIS-RTOS implementation. -These definitions can be specific to the underlying RTOS kernel. - -Definitions that are marked with <b>MUST REMAIN UNCHANGED</b> cannot be altered. Otherwise the CMSIS-RTOS implementation is no longer -compliant to the standard. Note that some functions are optional and need not to be provided by every CMSIS-RTOS implementation. - - -<b>Function calls from interrupt service routines</b> - -The following CMSIS-RTOS functions can be called from threads and interrupt service routines (ISR): - - \ref osSignalSet - - \ref osSemaphoreRelease - - \ref osPoolAlloc, \ref osPoolCAlloc, \ref osPoolFree - - \ref osMessagePut, \ref osMessageGet - - \ref osMailAlloc, \ref osMailCAlloc, \ref osMailGet, \ref osMailPut, \ref osMailFree - -Functions that cannot be called from an ISR are verifying the interrupt status and return in case that they are called -from an ISR context the status code \b osErrorISR. In some implementations this condition might be caught using the HARD FAULT vector. - -Some CMSIS-RTOS implementations support CMSIS-RTOS function calls from multiple ISR at the same time. -If this is impossible, the CMSIS-RTOS rejects calls by nested ISR functions with the status code \b osErrorISRRecursive. - - -<b>Define and reference object definitions</b> - -With <b>\#define osObjectsExternal</b> objects are defined as external symbols. This allows to create a consistent header file -that is used throughout a project as shown below: - -<i>Header File</i> -\code -#include <cmsis_os.h> // CMSIS RTOS header file - -// Thread definition -extern void thread_sample (void const *argument); // function prototype -osThreadDef (thread_sample, osPriorityBelowNormal, 1, 100); - -// Pool definition -osPoolDef(MyPool, 10, long); -\endcode - - -This header file defines all objects when included in a C/C++ source file. When <b>\#define osObjectsExternal</b> is -present before the header file, the objects are defined as external symbols. A single consistent header file can therefore be -used throughout the whole project. - -<i>Example</i> -\code -#include "osObjects.h" // Definition of the CMSIS-RTOS objects -\endcode - -\code -#define osObjectExternal // Objects will be defined as external symbols -#include "osObjects.h" // Reference to the CMSIS-RTOS objects -\endcode - -*/ - -#ifndef _CMSIS_OS_H -#define _CMSIS_OS_H - -/// \note MUST REMAIN UNCHANGED: \b osCMSIS identifies the CMSIS-RTOS API version. -#define osCMSIS 0x10001 ///< API version (main [31:16] .sub [15:0]) - -/// \note CAN BE CHANGED: \b osCMSIS_KERNEL identifies the underlying RTOS kernel and version number. -#define osCMSIS_RTX ((4<<16)|61) ///< RTOS identification and version (main [31:16] .sub [15:0]) - -/// \note MUST REMAIN UNCHANGED: \b osKernelSystemId shall be consistent in every CMSIS-RTOS. -#define osKernelSystemId "RTX V4.61" ///< RTOS identification string - -#define CMSIS_OS_RTX -#define CMSIS_OS_RTX_CA /* new define for Coretex-A */ - -// The stack space occupied is mainly dependent on the underling C standard library -#if defined(TOOLCHAIN_GCC) || defined(TOOLCHAIN_ARM_STD) -# define WORDS_STACK_SIZE 512 -#elif defined(TOOLCHAIN_ARM_MICRO) -# define WORDS_STACK_SIZE 128 -#endif - -#define DEFAULT_STACK_SIZE (WORDS_STACK_SIZE*4) - -/// \note MUST REMAIN UNCHANGED: \b osFeature_xxx shall be consistent in every CMSIS-RTOS. -#define osFeature_MainThread 1 ///< main thread 1=main can be thread, 0=not available -#define osFeature_Pool 1 ///< Memory Pools: 1=available, 0=not available -#define osFeature_MailQ 1 ///< Mail Queues: 1=available, 0=not available -#define osFeature_MessageQ 1 ///< Message Queues: 1=available, 0=not available -#define osFeature_Signals 16 ///< maximum number of Signal Flags available per thread -#define osFeature_Semaphore 65535 ///< maximum count for \ref osSemaphoreCreate function -#define osFeature_Wait 0 ///< osWait function: 1=available, 0=not available - -#if defined (__CC_ARM) -#define os_InRegs __value_in_regs // Compiler specific: force struct in registers -#else -#define os_InRegs -#endif - -#include <stdint.h> -#include <stddef.h> - -#ifdef __cplusplus -extern "C" -{ -#endif - - -// ==== Enumeration, structures, defines ==== - -/// Priority used for thread control. -/// \note MUST REMAIN UNCHANGED: \b osPriority shall be consistent in every CMSIS-RTOS. -typedef enum { - osPriorityIdle = -3, ///< priority: idle (lowest) - osPriorityLow = -2, ///< priority: low - osPriorityBelowNormal = -1, ///< priority: below normal - osPriorityNormal = 0, ///< priority: normal (default) - osPriorityAboveNormal = +1, ///< priority: above normal - osPriorityHigh = +2, ///< priority: high - osPriorityRealtime = +3, ///< priority: realtime (highest) - osPriorityError = 0x84 ///< system cannot determine priority or thread has illegal priority -} osPriority; - -/// Timeout value. -/// \note MUST REMAIN UNCHANGED: \b osWaitForever shall be consistent in every CMSIS-RTOS. -#define osWaitForever 0xFFFFFFFF ///< wait forever timeout value - -/// Status code values returned by CMSIS-RTOS functions. -/// \note MUST REMAIN UNCHANGED: \b osStatus shall be consistent in every CMSIS-RTOS. -typedef enum { - osOK = 0, ///< function completed; no error or event occurred. - osEventSignal = 0x08, ///< function completed; signal event occurred. - osEventMessage = 0x10, ///< function completed; message event occurred. - osEventMail = 0x20, ///< function completed; mail event occurred. - osEventTimeout = 0x40, ///< function completed; timeout occurred. - osErrorParameter = 0x80, ///< parameter error: a mandatory parameter was missing or specified an incorrect object. - osErrorResource = 0x81, ///< resource not available: a specified resource was not available. - osErrorTimeoutResource = 0xC1, ///< resource not available within given time: a specified resource was not available within the timeout period. - osErrorISR = 0x82, ///< not allowed in ISR context: the function cannot be called from interrupt service routines. - osErrorISRRecursive = 0x83, ///< function called multiple times from ISR with same object. - osErrorPriority = 0x84, ///< system cannot determine priority or thread has illegal priority. - osErrorNoMemory = 0x85, ///< system is out of memory: it was impossible to allocate or reserve memory for the operation. - osErrorValue = 0x86, ///< value of a parameter is out of range. - osErrorOS = 0xFF, ///< unspecified RTOS error: run-time error but no other error message fits. - os_status_reserved = 0x7FFFFFFF ///< prevent from enum down-size compiler optimization. -} osStatus; - - -/// Timer type value for the timer definition. -/// \note MUST REMAIN UNCHANGED: \b os_timer_type shall be consistent in every CMSIS-RTOS. -typedef enum { - osTimerOnce = 0, ///< one-shot timer - osTimerPeriodic = 1 ///< repeating timer -} os_timer_type; - -/// Entry point of a thread. -/// \note MUST REMAIN UNCHANGED: \b os_pthread shall be consistent in every CMSIS-RTOS. -typedef void (*os_pthread) (void const *argument); - -/// Entry point of a timer call back function. -/// \note MUST REMAIN UNCHANGED: \b os_ptimer shall be consistent in every CMSIS-RTOS. -typedef void (*os_ptimer) (void const *argument); - -// >>> the following data type definitions may shall adapted towards a specific RTOS - -/// Thread ID identifies the thread (pointer to a thread control block). -/// \note CAN BE CHANGED: \b os_thread_cb is implementation specific in every CMSIS-RTOS. -typedef struct os_thread_cb *osThreadId; - -/// Timer ID identifies the timer (pointer to a timer control block). -/// \note CAN BE CHANGED: \b os_timer_cb is implementation specific in every CMSIS-RTOS. -typedef struct os_timer_cb *osTimerId; - -/// Mutex ID identifies the mutex (pointer to a mutex control block). -/// \note CAN BE CHANGED: \b os_mutex_cb is implementation specific in every CMSIS-RTOS. -typedef struct os_mutex_cb *osMutexId; - -/// Semaphore ID identifies the semaphore (pointer to a semaphore control block). -/// \note CAN BE CHANGED: \b os_semaphore_cb is implementation specific in every CMSIS-RTOS. -typedef struct os_semaphore_cb *osSemaphoreId; - -/// Pool ID identifies the memory pool (pointer to a memory pool control block). -/// \note CAN BE CHANGED: \b os_pool_cb is implementation specific in every CMSIS-RTOS. -typedef struct os_pool_cb *osPoolId; - -/// Message ID identifies the message queue (pointer to a message queue control block). -/// \note CAN BE CHANGED: \b os_messageQ_cb is implementation specific in every CMSIS-RTOS. -typedef struct os_messageQ_cb *osMessageQId; - -/// Mail ID identifies the mail queue (pointer to a mail queue control block). -/// \note CAN BE CHANGED: \b os_mailQ_cb is implementation specific in every CMSIS-RTOS. -typedef struct os_mailQ_cb *osMailQId; - - -/// Thread Definition structure contains startup information of a thread. -/// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS. -typedef struct os_thread_def { - os_pthread pthread; ///< start address of thread function - osPriority tpriority; ///< initial thread priority - uint32_t instances; ///< maximum number of instances of that thread function - uint32_t stacksize; ///< stack size requirements in bytes; 0 is default stack size -} osThreadDef_t; - -/// Timer Definition structure contains timer parameters. -/// \note CAN BE CHANGED: \b os_timer_def is implementation specific in every CMSIS-RTOS. -typedef struct os_timer_def { - os_ptimer ptimer; ///< start address of a timer function - void *timer; ///< pointer to internal data -} osTimerDef_t; - -/// Mutex Definition structure contains setup information for a mutex. -/// \note CAN BE CHANGED: \b os_mutex_def is implementation specific in every CMSIS-RTOS. -typedef struct os_mutex_def { - void *mutex; ///< pointer to internal data -} osMutexDef_t; - -/// Semaphore Definition structure contains setup information for a semaphore. -/// \note CAN BE CHANGED: \b os_semaphore_def is implementation specific in every CMSIS-RTOS. -typedef struct os_semaphore_def { - void *semaphore; ///< pointer to internal data -} osSemaphoreDef_t; - -/// Definition structure for memory block allocation. -/// \note CAN BE CHANGED: \b os_pool_def is implementation specific in every CMSIS-RTOS. -typedef struct os_pool_def { - uint32_t pool_sz; ///< number of items (elements) in the pool - uint32_t item_sz; ///< size of an item - void *pool; ///< pointer to memory for pool -} osPoolDef_t; - -/// Definition structure for message queue. -/// \note CAN BE CHANGED: \b os_messageQ_def is implementation specific in every CMSIS-RTOS. -typedef struct os_messageQ_def { - uint32_t queue_sz; ///< number of elements in the queue - void *pool; ///< memory array for messages -} osMessageQDef_t; - -/// Definition structure for mail queue. -/// \note CAN BE CHANGED: \b os_mailQ_def is implementation specific in every CMSIS-RTOS. -typedef struct os_mailQ_def { - uint32_t queue_sz; ///< number of elements in the queue - uint32_t item_sz; ///< size of an item - void *pool; ///< memory array for mail -} osMailQDef_t; - -/// Event structure contains detailed information about an event. -/// \note MUST REMAIN UNCHANGED: \b os_event shall be consistent in every CMSIS-RTOS. -/// However the struct may be extended at the end. -typedef struct { - osStatus status; ///< status code: event or error information - union { - uint32_t v; ///< message as 32-bit value - void *p; ///< message or mail as void pointer - int32_t signals; ///< signal flags - } value; ///< event value - union { - osMailQId mail_id; ///< mail id obtained by \ref osMailCreate - osMessageQId message_id; ///< message id obtained by \ref osMessageCreate - } def; ///< event definition -} osEvent; - - -// ==== Kernel Control Functions ==== - -/// Initialize the RTOS Kernel for creating objects. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osKernelInitialize shall be consistent in every CMSIS-RTOS. -osStatus osKernelInitialize (void); - -/// Start the RTOS Kernel. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osKernelStart shall be consistent in every CMSIS-RTOS. -osStatus osKernelStart (void); - -/// Check if the RTOS kernel is already started. -/// \note MUST REMAIN UNCHANGED: \b osKernelRunning shall be consistent in every CMSIS-RTOS. -/// \return 0 RTOS is not started, 1 RTOS is started. -int32_t osKernelRunning(void); - - -// ==== Thread Management ==== - -/// Create a Thread Definition with function, priority, and stack requirements. -/// \param name name of the thread function. -/// \param priority initial priority of the thread function. -/// \param instances number of possible thread instances. -/// \param stacksz stack size (in bytes) requirements for the thread function. -/// \note CAN BE CHANGED: The parameters to \b osThreadDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osThreadDef(name, priority, instances, stacksz) \ -extern const osThreadDef_t os_thread_def_##name -#else // define the object -#if defined (__MBED_CMSIS_RTOS_CA9) -#define osThreadDef(name, priority, stacksz) \ -const osThreadDef_t os_thread_def_##name = \ -{ (name), (priority), 1, (stacksz) } -#else -#define osThreadDef(name, priority, instances, stacksz) \ -const osThreadDef_t os_thread_def_##name = \ -{ (name), (priority), (instances), (stacksz) } -#endif -#endif - -/// Access a Thread definition. -/// \param name name of the thread definition object. -/// \note CAN BE CHANGED: The parameter to \b osThread shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osThread(name) \ -&os_thread_def_##name - -/// Create a thread and add it to Active Threads and set it to state READY. -/// \param[in] thread_def thread definition referenced with \ref osThread. -/// \param[in] argument pointer that is passed to the thread function as start argument. -/// \return thread ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osThreadCreate shall be consistent in every CMSIS-RTOS. -osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument); - -/// Return the thread ID of the current running thread. -/// \return thread ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osThreadGetId shall be consistent in every CMSIS-RTOS. -osThreadId osThreadGetId (void); - -/// Terminate execution of a thread and remove it from Active Threads. -/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osThreadTerminate shall be consistent in every CMSIS-RTOS. -osStatus osThreadTerminate (osThreadId thread_id); - -/// Pass control to next thread that is in state \b READY. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osThreadYield shall be consistent in every CMSIS-RTOS. -osStatus osThreadYield (void); - -/// Change priority of an active thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. -/// \param[in] priority new priority value for the thread function. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osThreadSetPriority shall be consistent in every CMSIS-RTOS. -osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority); - -/// Get current priority of an active thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. -/// \return current priority value of the thread function. -/// \note MUST REMAIN UNCHANGED: \b osThreadGetPriority shall be consistent in every CMSIS-RTOS. -osPriority osThreadGetPriority (osThreadId thread_id); - -#ifdef __MBED_CMSIS_RTOS_CA9 -/// Get current thread state. -uint8_t osThreadGetState (osThreadId thread_id); -#endif - -// ==== Generic Wait Functions ==== - -/// Wait for Timeout (Time Delay). -/// \param[in] millisec time delay value -/// \return status code that indicates the execution status of the function. -osStatus osDelay (uint32_t millisec); - -#if (defined (osFeature_Wait) && (osFeature_Wait != 0)) // Generic Wait available - -/// Wait for Signal, Message, Mail, or Timeout. -/// \param[in] millisec timeout value or 0 in case of no time-out -/// \return event that contains signal, message, or mail information or error code. -/// \note MUST REMAIN UNCHANGED: \b osWait shall be consistent in every CMSIS-RTOS. -os_InRegs osEvent osWait (uint32_t millisec); - -#endif // Generic Wait available - - -// ==== Timer Management Functions ==== -/// Define a Timer object. -/// \param name name of the timer object. -/// \param function name of the timer call back function. -/// \note CAN BE CHANGED: The parameter to \b osTimerDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osTimerDef(name, function) \ -extern const osTimerDef_t os_timer_def_##name -#else // define the object -#define osTimerDef(name, function) \ -uint32_t os_timer_cb_##name[5]; \ -const osTimerDef_t os_timer_def_##name = \ -{ (function), (os_timer_cb_##name) } -#endif - -/// Access a Timer definition. -/// \param name name of the timer object. -/// \note CAN BE CHANGED: The parameter to \b osTimer shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osTimer(name) \ -&os_timer_def_##name - -/// Create a timer. -/// \param[in] timer_def timer object referenced with \ref osTimer. -/// \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior. -/// \param[in] argument argument to the timer call back function. -/// \return timer ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osTimerCreate shall be consistent in every CMSIS-RTOS. -osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument); - -/// Start or restart a timer. -/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. -/// \param[in] millisec time delay value of the timer. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osTimerStart shall be consistent in every CMSIS-RTOS. -osStatus osTimerStart (osTimerId timer_id, uint32_t millisec); - -/// Stop the timer. -/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osTimerStop shall be consistent in every CMSIS-RTOS. -osStatus osTimerStop (osTimerId timer_id); - -/// Delete a timer that was created by \ref osTimerCreate. -/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osTimerDelete shall be consistent in every CMSIS-RTOS. -osStatus osTimerDelete (osTimerId timer_id); - - -// ==== Signal Management ==== - -/// Set the specified Signal Flags of an active thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. -/// \param[in] signals specifies the signal flags of the thread that should be set. -/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. -/// \note MUST REMAIN UNCHANGED: \b osSignalSet shall be consistent in every CMSIS-RTOS. -int32_t osSignalSet (osThreadId thread_id, int32_t signals); - -/// Clear the specified Signal Flags of an active thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. -/// \param[in] signals specifies the signal flags of the thread that shall be cleared. -/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. -/// \note MUST REMAIN UNCHANGED: \b osSignalClear shall be consistent in every CMSIS-RTOS. -int32_t osSignalClear (osThreadId thread_id, int32_t signals); - -/// Get Signal Flags status of an active thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. -/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. -/// \note MUST REMAIN UNCHANGED: \b osSignalGet shall be consistent in every CMSIS-RTOS. -int32_t osSignalGet (osThreadId thread_id); - -/// Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread. -/// \param[in] signals wait until all specified signal flags set or 0 for any single signal flag. -/// \param[in] millisec timeout value or 0 in case of no time-out. -/// \return event flag information or error code. -/// \note MUST REMAIN UNCHANGED: \b osSignalWait shall be consistent in every CMSIS-RTOS. -os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec); - - -// ==== Mutex Management ==== - -/// Define a Mutex. -/// \param name name of the mutex object. -/// \note CAN BE CHANGED: The parameter to \b osMutexDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osMutexDef(name) \ -extern const osMutexDef_t os_mutex_def_##name -#else // define the object -#define osMutexDef(name) \ -uint32_t os_mutex_cb_##name[3]; \ -const osMutexDef_t os_mutex_def_##name = { (os_mutex_cb_##name) } -#endif - -/// Access a Mutex definition. -/// \param name name of the mutex object. -/// \note CAN BE CHANGED: The parameter to \b osMutex shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osMutex(name) \ -&os_mutex_def_##name - -/// Create and Initialize a Mutex object. -/// \param[in] mutex_def mutex definition referenced with \ref osMutex. -/// \return mutex ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osMutexCreate shall be consistent in every CMSIS-RTOS. -osMutexId osMutexCreate (const osMutexDef_t *mutex_def); - -/// Wait until a Mutex becomes available. -/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. -/// \param[in] millisec timeout value or 0 in case of no time-out. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMutexWait shall be consistent in every CMSIS-RTOS. -osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec); - -/// Release a Mutex that was obtained by \ref osMutexWait. -/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMutexRelease shall be consistent in every CMSIS-RTOS. -osStatus osMutexRelease (osMutexId mutex_id); - -/// Delete a Mutex that was created by \ref osMutexCreate. -/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMutexDelete shall be consistent in every CMSIS-RTOS. -osStatus osMutexDelete (osMutexId mutex_id); - - -// ==== Semaphore Management Functions ==== - -#if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0)) // Semaphore available - -/// Define a Semaphore object. -/// \param name name of the semaphore object. -/// \note CAN BE CHANGED: The parameter to \b osSemaphoreDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osSemaphoreDef(name) \ -extern const osSemaphoreDef_t os_semaphore_def_##name -#else // define the object -#define osSemaphoreDef(name) \ -uint32_t os_semaphore_cb_##name[2]; \ -const osSemaphoreDef_t os_semaphore_def_##name = { (os_semaphore_cb_##name) } -#endif - -/// Access a Semaphore definition. -/// \param name name of the semaphore object. -/// \note CAN BE CHANGED: The parameter to \b osSemaphore shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osSemaphore(name) \ -&os_semaphore_def_##name - -/// Create and Initialize a Semaphore object used for managing resources. -/// \param[in] semaphore_def semaphore definition referenced with \ref osSemaphore. -/// \param[in] count number of available resources. -/// \return semaphore ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osSemaphoreCreate shall be consistent in every CMSIS-RTOS. -osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count); - -/// Wait until a Semaphore token becomes available. -/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. -/// \param[in] millisec timeout value or 0 in case of no time-out. -/// \return number of available tokens, or -1 in case of incorrect parameters. -/// \note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS. -int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec); - -/// Release a Semaphore token. -/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osSemaphoreRelease shall be consistent in every CMSIS-RTOS. -osStatus osSemaphoreRelease (osSemaphoreId semaphore_id); - -/// Delete a Semaphore that was created by \ref osSemaphoreCreate. -/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osSemaphoreDelete shall be consistent in every CMSIS-RTOS. -osStatus osSemaphoreDelete (osSemaphoreId semaphore_id); - -#endif // Semaphore available - - -// ==== Memory Pool Management Functions ==== - -#if (defined (osFeature_Pool) && (osFeature_Pool != 0)) // Memory Pool Management available - -/// \brief Define a Memory Pool. -/// \param name name of the memory pool. -/// \param no maximum number of blocks (objects) in the memory pool. -/// \param type data type of a single block (object). -/// \note CAN BE CHANGED: The parameter to \b osPoolDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osPoolDef(name, no, type) \ -extern const osPoolDef_t os_pool_def_##name -#else // define the object -#define osPoolDef(name, no, type) \ -uint32_t os_pool_m_##name[3+((sizeof(type)+3)/4)*(no)]; \ -const osPoolDef_t os_pool_def_##name = \ -{ (no), sizeof(type), (os_pool_m_##name) } -#endif - -/// \brief Access a Memory Pool definition. -/// \param name name of the memory pool -/// \note CAN BE CHANGED: The parameter to \b osPool shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osPool(name) \ -&os_pool_def_##name - -/// Create and Initialize a memory pool. -/// \param[in] pool_def memory pool definition referenced with \ref osPool. -/// \return memory pool ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osPoolCreate shall be consistent in every CMSIS-RTOS. -osPoolId osPoolCreate (const osPoolDef_t *pool_def); - -/// Allocate a memory block from a memory pool. -/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. -/// \return address of the allocated memory block or NULL in case of no memory available. -/// \note MUST REMAIN UNCHANGED: \b osPoolAlloc shall be consistent in every CMSIS-RTOS. -void *osPoolAlloc (osPoolId pool_id); - -/// Allocate a memory block from a memory pool and set memory block to zero. -/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. -/// \return address of the allocated memory block or NULL in case of no memory available. -/// \note MUST REMAIN UNCHANGED: \b osPoolCAlloc shall be consistent in every CMSIS-RTOS. -void *osPoolCAlloc (osPoolId pool_id); - -/// Return an allocated memory block back to a specific memory pool. -/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. -/// \param[in] block address of the allocated memory block that is returned to the memory pool. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osPoolFree shall be consistent in every CMSIS-RTOS. -osStatus osPoolFree (osPoolId pool_id, void *block); - -#endif // Memory Pool Management available - - -// ==== Message Queue Management Functions ==== - -#if (defined (osFeature_MessageQ) && (osFeature_MessageQ != 0)) // Message Queues available - -/// \brief Create a Message Queue Definition. -/// \param name name of the queue. -/// \param queue_sz maximum number of messages in the queue. -/// \param type data type of a single message element (for debugger). -/// \note CAN BE CHANGED: The parameter to \b osMessageQDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osMessageQDef(name, queue_sz, type) \ -extern const osMessageQDef_t os_messageQ_def_##name -#else // define the object -#define osMessageQDef(name, queue_sz, type) \ -uint32_t os_messageQ_q_##name[4+(queue_sz)]; \ -const osMessageQDef_t os_messageQ_def_##name = \ -{ (queue_sz), (os_messageQ_q_##name) } -#endif - -/// \brief Access a Message Queue Definition. -/// \param name name of the queue -/// \note CAN BE CHANGED: The parameter to \b osMessageQ shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osMessageQ(name) \ -&os_messageQ_def_##name - -/// Create and Initialize a Message Queue. -/// \param[in] queue_def queue definition referenced with \ref osMessageQ. -/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. -/// \return message queue ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osMessageCreate shall be consistent in every CMSIS-RTOS. -osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id); - -/// Put a Message to a Queue. -/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. -/// \param[in] info message information. -/// \param[in] millisec timeout value or 0 in case of no time-out. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMessagePut shall be consistent in every CMSIS-RTOS. -osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec); - -/// Get a Message or Wait for a Message from a Queue. -/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. -/// \param[in] millisec timeout value or 0 in case of no time-out. -/// \return event information that includes status code. -/// \note MUST REMAIN UNCHANGED: \b osMessageGet shall be consistent in every CMSIS-RTOS. -os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec); - -#endif // Message Queues available - - -// ==== Mail Queue Management Functions ==== - -#if (defined (osFeature_MailQ) && (osFeature_MailQ != 0)) // Mail Queues available - -/// \brief Create a Mail Queue Definition. -/// \param name name of the queue -/// \param queue_sz maximum number of messages in queue -/// \param type data type of a single message element -/// \note CAN BE CHANGED: The parameter to \b osMailQDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osMailQDef(name, queue_sz, type) \ -extern const osMailQDef_t os_mailQ_def_##name -#else // define the object -#define osMailQDef(name, queue_sz, type) \ -uint32_t os_mailQ_q_##name[4+(queue_sz)]; \ -uint32_t os_mailQ_m_##name[3+((sizeof(type)+3)/4)*(queue_sz)]; \ -void * os_mailQ_p_##name[2] = { (os_mailQ_q_##name), os_mailQ_m_##name }; \ -const osMailQDef_t os_mailQ_def_##name = \ -{ (queue_sz), sizeof(type), (os_mailQ_p_##name) } -#endif - -/// \brief Access a Mail Queue Definition. -/// \param name name of the queue -/// \note CAN BE CHANGED: The parameter to \b osMailQ shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osMailQ(name) \ -&os_mailQ_def_##name - -/// Create and Initialize mail queue. -/// \param[in] queue_def reference to the mail queue definition obtain with \ref osMailQ -/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. -/// \return mail queue ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osMailCreate shall be consistent in every CMSIS-RTOS. -osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id); - -/// Allocate a memory block from a mail. -/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. -/// \param[in] millisec timeout value or 0 in case of no time-out -/// \return pointer to memory block that can be filled with mail or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osMailAlloc shall be consistent in every CMSIS-RTOS. -void *osMailAlloc (osMailQId queue_id, uint32_t millisec); - -/// Allocate a memory block from a mail and set memory block to zero. -/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. -/// \param[in] millisec timeout value or 0 in case of no time-out -/// \return pointer to memory block that can be filled with mail or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osMailCAlloc shall be consistent in every CMSIS-RTOS. -void *osMailCAlloc (osMailQId queue_id, uint32_t millisec); - -/// Put a mail to a queue. -/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. -/// \param[in] mail memory block previously allocated with \ref osMailAlloc or \ref osMailCAlloc. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMailPut shall be consistent in every CMSIS-RTOS. -osStatus osMailPut (osMailQId queue_id, void *mail); - -/// Get a mail from a queue. -/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. -/// \param[in] millisec timeout value or 0 in case of no time-out -/// \return event that contains mail information or error code. -/// \note MUST REMAIN UNCHANGED: \b osMailGet shall be consistent in every CMSIS-RTOS. -os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec); - -/// Free a memory block from a mail. -/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. -/// \param[in] mail pointer to the memory block that was obtained with \ref osMailGet. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMailFree shall be consistent in every CMSIS-RTOS. -osStatus osMailFree (osMailQId queue_id, void *mail); - -#endif // Mail Queues available - - -#ifdef __cplusplus -} -#endif - -#endif // _CMSIS_OS_H
--- a/rtx_ca/rt_CMSIS.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1978 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: rt_CMSIS.c - * Purpose: CMSIS RTOS API - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#define __CMSIS_GENERIC - -#if defined (__CORTEX_M4) || defined (__CORTEX_M4F) - #include "core_cm4.h" -#elif defined (__CORTEX_M3) - #include "core_cm3.h" -#elif defined (__CORTEX_M0) - #include "core_cm0.h" -#elif defined (__CORTEX_A9) - #include "core_ca9.h" -#else - #error "Missing __CORTEX_xx definition" -#endif - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_System.h" -#include "rt_Task.h" -#include "rt_Event.h" -#include "rt_List.h" -#include "rt_Time.h" -#include "rt_Mutex.h" -#include "rt_Semaphore.h" -#include "rt_Mailbox.h" -#include "rt_MemBox.h" -#include "rt_Memory.h" -#include "rt_HAL_CM.h" - -#define os_thread_cb OS_TCB - -#include "cmsis_os.h" - -#if (osFeature_Signals != 16) -#error Invalid "osFeature_Signals" value! -#endif -#if (osFeature_Semaphore > 65535) -#error Invalid "osFeature_Semaphore" value! -#endif -#if (osFeature_Wait != 0) -#error osWait not supported! -#endif - - -// ==== Enumeration, structures, defines ==== - -// Service Calls defines - -#if defined (__CC_ARM) /* ARM Compiler */ - -#define __NO_RETURN __declspec(noreturn) - -#define osEvent_type osEvent -#define osEvent_ret_status ret -#define osEvent_ret_value ret -#define osEvent_ret_msg ret -#define osEvent_ret_mail ret - -#define osCallback_type osCallback -#define osCallback_ret ret - -#define SVC_0_1(f,t,...) \ -__svc_indirect(0) t _##f (t(*)()); \ - t f (void); \ -__attribute__((always_inline)) \ -static __inline t __##f (void) { \ - return _##f(f); \ -} - -#define SVC_1_1(f,t,t1,...) \ -__svc_indirect(0) t _##f (t(*)(t1),t1); \ - t f (t1 a1); \ -__attribute__((always_inline)) \ -static __inline t __##f (t1 a1) { \ - return _##f(f,a1); \ -} - -#define SVC_2_1(f,t,t1,t2,...) \ -__svc_indirect(0) t _##f (t(*)(t1,t2),t1,t2); \ - t f (t1 a1, t2 a2); \ -__attribute__((always_inline)) \ -static __inline t __##f (t1 a1, t2 a2) { \ - return _##f(f,a1,a2); \ -} - -#define SVC_3_1(f,t,t1,t2,t3,...) \ -__svc_indirect(0) t _##f (t(*)(t1,t2,t3),t1,t2,t3); \ - t f (t1 a1, t2 a2, t3 a3); \ -__attribute__((always_inline)) \ -static __inline t __##f (t1 a1, t2 a2, t3 a3) { \ - return _##f(f,a1,a2,a3); \ -} - -#define SVC_4_1(f,t,t1,t2,t3,t4,...) \ -__svc_indirect(0) t _##f (t(*)(t1,t2,t3,t4),t1,t2,t3,t4); \ - t f (t1 a1, t2 a2, t3 a3, t4 a4); \ -__attribute__((always_inline)) \ -static __inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ - return _##f(f,a1,a2,a3,a4); \ -} - -#define SVC_1_2 SVC_1_1 -#define SVC_1_3 SVC_1_1 -#define SVC_2_3 SVC_2_1 - -#elif defined (__GNUC__) /* GNU Compiler */ - -#define __NO_RETURN __attribute__((noreturn)) - -typedef uint32_t __attribute__((vector_size(8))) ret64; -typedef uint32_t __attribute__((vector_size(16))) ret128; - -#define RET_pointer __r0 -#define RET_int32_t __r0 -#define RET_osStatus __r0 -#define RET_osPriority __r0 -#define RET_osEvent {(osStatus)__r0, {(uint32_t)__r1}, {(void *)__r2}} -#define RET_osCallback {(void *)__r0, (void *)__r1} - -#define osEvent_type ret128 -#define osEvent_ret_status (ret128){ret.status} -#define osEvent_ret_value (ret128){ret.status, ret.value.v} -#define osEvent_ret_msg (ret128){ret.status, ret.value.v, (uint32_t)ret.def.message_id} -#define osEvent_ret_mail (ret128){ret.status, ret.value.v, (uint32_t)ret.def.mail_id} - -#define osCallback_type ret64 -#define osCallback_ret (ret64) {(uint32_t)ret.fp, (uint32_t)ret.arg} - -#define SVC_ArgN(n) \ - register int __r##n __asm("r"#n); - -#define SVC_ArgR(n,t,a) \ - register t __r##n __asm("r"#n) = a; - -#define SVC_Arg0() \ - SVC_ArgN(0) \ - SVC_ArgN(1) \ - SVC_ArgN(2) \ - SVC_ArgN(3) - -#define SVC_Arg1(t1) \ - SVC_ArgR(0,t1,a1) \ - SVC_ArgN(1) \ - SVC_ArgN(2) \ - SVC_ArgN(3) - -#define SVC_Arg2(t1,t2) \ - SVC_ArgR(0,t1,a1) \ - SVC_ArgR(1,t2,a2) \ - SVC_ArgN(2) \ - SVC_ArgN(3) - -#define SVC_Arg3(t1,t2,t3) \ - SVC_ArgR(0,t1,a1) \ - SVC_ArgR(1,t2,a2) \ - SVC_ArgR(2,t3,a3) \ - SVC_ArgN(3) - -#define SVC_Arg4(t1,t2,t3,t4) \ - SVC_ArgR(0,t1,a1) \ - SVC_ArgR(1,t2,a2) \ - SVC_ArgR(2,t3,a3) \ - SVC_ArgR(3,t4,a4) - -#if (defined (__CORTEX_M0)) -#define SVC_Call(f) \ - __asm volatile \ - ( \ - "ldr r7,="#f"\n\t" \ - "mov r12,r7\n\t" \ - "svc 0" \ - : "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3) \ - : "r" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) \ - : "r7", "r12", "lr", "cc" \ - ); -#else -#define SVC_Call(f) \ - __asm volatile \ - ( \ - "ldr r12,="#f"\n\t" \ - "svc 0" \ - : "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3) \ - : "r" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) \ - : "r12", "lr", "cc" \ - ); -#endif - -#define SVC_0_1(f,t,rv) \ -__attribute__((always_inline)) \ -static inline t __##f (void) { \ - SVC_Arg0(); \ - SVC_Call(f); \ - return (t) rv; \ -} - -#define SVC_1_1(f,t,t1,rv) \ -__attribute__((always_inline)) \ -static inline t __##f (t1 a1) { \ - SVC_Arg1(t1); \ - SVC_Call(f); \ - return (t) rv; \ -} - -#define SVC_2_1(f,t,t1,t2,rv) \ -__attribute__((always_inline)) \ -static inline t __##f (t1 a1, t2 a2) { \ - SVC_Arg2(t1,t2); \ - SVC_Call(f); \ - return (t) rv; \ -} - -#define SVC_3_1(f,t,t1,t2,t3,rv) \ -__attribute__((always_inline)) \ -static inline t __##f (t1 a1, t2 a2, t3 a3) { \ - SVC_Arg3(t1,t2,t3); \ - SVC_Call(f); \ - return (t) rv; \ -} - -#define SVC_4_1(f,t,t1,t2,t3,t4,rv) \ -__attribute__((always_inline)) \ -static inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ - SVC_Arg4(t1,t2,t3,t4); \ - SVC_Call(f); \ - return (t) rv; \ -} - -#define SVC_1_2 SVC_1_1 -#define SVC_1_3 SVC_1_1 -#define SVC_2_3 SVC_2_1 - -#elif defined (__ICCARM__) /* IAR Compiler */ - -#define __NO_RETURN __noreturn - -#define RET_osEvent "=r"(ret.status), "=r"(ret.value), "=r"(ret.def) -#define RET_osCallback "=r"(ret.fp), "=r"(ret.arg) - -#define osEvent_type osEvent -#define osEvent_ret_status ret -#define osEvent_ret_value ret -#define osEvent_ret_msg ret -#define osEvent_ret_mail ret - -#define osCallback_type uint64_t -#define osCallback_ret ((uint64_t)ret.fp | ((uint64_t)ret.arg)<<32) - -#define SVC_Setup(f) \ - __asm( \ - "mov r12,%0\n" \ - :: "r"(&f): "r12" \ - ); - -#define SVC_Ret3() \ - __asm( \ - "ldr r0,[sp,#0]\n" \ - "ldr r1,[sp,#4]\n" \ - "ldr r2,[sp,#8]\n" \ - ); - -#define SVC_0_1(f,t,...) \ -t f (void); \ -_Pragma("swi_number=0") __swi t _##f (void); \ -static inline t __##f (void) { \ - SVC_Setup(f); \ - return _##f(); \ -} - -#define SVC_1_1(f,t,t1,...) \ -t f (t1 a1); \ -_Pragma("swi_number=0") __swi t _##f (t1 a1); \ -static inline t __##f (t1 a1) { \ - SVC_Setup(f); \ - return _##f(a1); \ -} - -#define SVC_2_1(f,t,t1,t2,...) \ -t f (t1 a1, t2 a2); \ -_Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2); \ -static inline t __##f (t1 a1, t2 a2) { \ - SVC_Setup(f); \ - return _##f(a1,a2); \ -} - -#define SVC_3_1(f,t,t1,t2,t3,...) \ -t f (t1 a1, t2 a2, t3 a3); \ -_Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2, t3 a3); \ -static inline t __##f (t1 a1, t2 a2, t3 a3) { \ - SVC_Setup(f); \ - return _##f(a1,a2,a3); \ -} - -#define SVC_4_1(f,t,t1,t2,t3,t4,...) \ -t f (t1 a1, t2 a2, t3 a3, t4 a4); \ -_Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2, t3 a3, t4 a4); \ -static inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ - SVC_Setup(f); \ - return _##f(a1,a2,a3,a4); \ -} - -#define SVC_1_2(f,t,t1,rr) \ -uint64_t f (t1 a1); \ -_Pragma("swi_number=0") __swi uint64_t _##f (t1 a1); \ -static inline t __##f (t1 a1) { \ - t ret; \ - SVC_Setup(f); \ - _##f(a1); \ - __asm("" : rr : :); \ - return ret; \ -} - -#define SVC_1_3(f,t,t1,rr) \ -t f (t1 a1); \ -void f##_ (t1 a1) { \ - f(a1); \ - SVC_Ret3(); \ -} \ -_Pragma("swi_number=0") __swi void _##f (t1 a1); \ -static inline t __##f (t1 a1) { \ - t ret; \ - SVC_Setup(f##_); \ - _##f(a1); \ - __asm("" : rr : :); \ - return ret; \ -} - -#define SVC_2_3(f,t,t1,t2,rr) \ -t f (t1 a1, t2 a2); \ -void f##_ (t1 a1, t2 a2) { \ - f(a1,a2); \ - SVC_Ret3(); \ -} \ -_Pragma("swi_number=0") __swi void _##f (t1 a1, t2 a2); \ -static inline t __##f (t1 a1, t2 a2) { \ - t ret; \ - SVC_Setup(f##_); \ - _##f(a1,a2); \ - __asm("" : rr : :); \ - return ret; \ -} - -#endif - - -// Callback structure -typedef struct { - void *fp; // Function pointer - void *arg; // Function argument -} osCallback; - - -// OS Section definitions -#ifdef OS_SECTIONS_LINK_INFO -extern const uint32_t os_section_id$$Base; -extern const uint32_t os_section_id$$Limit; -#endif - -// OS Stack Memory for Threads definitions -extern uint64_t os_stack_mem[]; -extern const uint32_t os_stack_sz; - -// OS Timers external resources -extern const osThreadDef_t os_thread_def_osTimerThread; -extern osThreadId osThreadId_osTimerThread; -extern const osMessageQDef_t os_messageQ_def_osTimerMessageQ; -extern osMessageQId osMessageQId_osTimerMessageQ; - -extern U32 IRQNestLevel; /* Indicates whether inside an ISR, and the depth of nesting. 0 = not in ISR. */ - - -// ==== Helper Functions ==== - -/// Convert timeout in millisec to system ticks -static uint32_t rt_ms2tick (uint32_t millisec) { - uint32_t tick; - - if (millisec == osWaitForever) return 0xFFFF; // Indefinite timeout - if (millisec > 4000000) return 0xFFFE; // Max ticks supported - - tick = ((1000 * millisec) + os_clockrate - 1) / os_clockrate; - if (tick > 0xFFFE) return 0xFFFE; - - return tick; -} - -/// Convert Thread ID to TCB pointer -static P_TCB rt_tid2ptcb (osThreadId thread_id) { - P_TCB ptcb; - - if (thread_id == NULL) return NULL; - - if ((uint32_t)thread_id & 3) return NULL; - -#ifdef OS_SECTIONS_LINK_INFO - if ((os_section_id$$Base != 0) && (os_section_id$$Limit != 0)) { - if (thread_id < (osThreadId)os_section_id$$Base) return NULL; - if (thread_id >= (osThreadId)os_section_id$$Limit) return NULL; - } -#endif - - ptcb = thread_id; - - if (ptcb->cb_type != TCB) return NULL; - - return ptcb; -} - -/// Convert ID pointer to Object pointer -static void *rt_id2obj (void *id) { - - if ((uint32_t)id & 3) return NULL; - -#ifdef OS_SECTIONS_LINK_INFO - if ((os_section_id$$Base != 0) && (os_section_id$$Limit != 0)) { - if (id < (void *)os_section_id$$Base) return NULL; - if (id >= (void *)os_section_id$$Limit) return NULL; - } -#endif - - return id; -} - -// === Helper functions for system call interface === - -static __inline char __get_mode(void) { - return (char)(__get_CPSR() & 0x1f); -} - -static __inline char __exceptional_mode(void) { - switch(__get_mode()) { - case MODE_USR: - case MODE_SYS: - return 0; - case MODE_SVC: - if (IRQNestLevel == 0) - return 0; /* handling a regular service call */ - else - return 1; /* handling an ISR in SVC mode */ - default: - return 1; - } -} - -// ==== Kernel Control ==== - -uint8_t os_initialized; // Kernel Initialized flag -uint8_t os_running; // Kernel Running flag - -// Kernel Control Service Calls declarations -SVC_0_1(svcKernelInitialize, osStatus, RET_osStatus) -SVC_0_1(svcKernelStart, osStatus, RET_osStatus) -SVC_0_1(svcKernelRunning, int32_t, RET_int32_t) - -static void sysThreadError (osStatus status); -osThreadId svcThreadCreate (const osThreadDef_t *thread_def, void *argument); -osMessageQId svcMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id); - -// Kernel Control Service Calls - -/// Initialize the RTOS Kernel for creating objects -osStatus svcKernelInitialize (void) { - int ret; - - if (!os_initialized) { - - // Init Thread Stack Memory (must be 8-byte aligned) - if ((uint32_t)os_stack_mem & 7) return osErrorNoMemory; - ret = rt_init_mem(os_stack_mem, os_stack_sz); - if (ret != 0) return osErrorNoMemory; - - rt_sys_init(); // RTX System Initialization - } - - os_tsk.run->prio = 255; // Highest priority - - if (!os_initialized) { - // Create OS Timers resources (Message Queue & Thread) - osMessageQId_osTimerMessageQ = svcMessageCreate (&os_messageQ_def_osTimerMessageQ, NULL); - osThreadId_osTimerThread = svcThreadCreate(&os_thread_def_osTimerThread, NULL); - } - - sysThreadError(osOK); - - os_initialized = 1; - - return osOK; -} - -/// Start the RTOS Kernel -osStatus svcKernelStart (void) { - - if (os_running) return osOK; - - rt_tsk_prio(0, 0); // Lowest priority - __set_PSP(os_tsk.run->tsk_stack + 8*4); // New context - os_tsk.run = NULL; // Force context switch - - rt_sys_start(); - - os_running = 1; - - return osOK; -} - -/// Check if the RTOS kernel is already started -int32_t svcKernelRunning(void) { - return os_running; -} - -// Kernel Control Public API - -/// Initialize the RTOS Kernel for creating objects -osStatus osKernelInitialize (void) { - if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR - if (__get_mode() != MODE_USR) { - return svcKernelInitialize(); - } else { - return __svcKernelInitialize(); - } -} - -/// Start the RTOS Kernel -osStatus osKernelStart (void) { - char mode = __get_mode(); - - switch(mode) { - case MODE_USR: - if (os_flags & 1) return osErrorOS; // Privileged Thread mode requested from Unprivileged - break; - case MODE_SYS: - if (!(os_flags & 1)) { - __set_CPS_USR(); - } - break; - default: - return osErrorISR; // Not allowed in ISR - } - return __svcKernelStart(); -} - -/// Check if the RTOS kernel is already started -int32_t osKernelRunning(void) { - if(__get_mode() != MODE_USR) { - return os_running; - } else { - return __svcKernelRunning(); - } -} - - -// ==== Thread Management ==== - -/// Set Thread Error (for Create functions which return IDs) -static void sysThreadError (osStatus status) { - // To Do -} - -__NO_RETURN void osThreadExit (void); - -// Thread Service Calls declarations -SVC_2_1(svcThreadCreate, osThreadId, const osThreadDef_t *, void *, RET_pointer) -SVC_0_1(svcThreadGetId, osThreadId, RET_pointer) -SVC_1_1(svcThreadTerminate, osStatus, osThreadId, RET_osStatus) -SVC_0_1(svcThreadYield, osStatus, RET_osStatus) -SVC_2_1(svcThreadSetPriority, osStatus, osThreadId, osPriority, RET_osStatus) -SVC_1_1(svcThreadGetPriority, osPriority, osThreadId, RET_osPriority) - -// Thread Service Calls - -/// Create a thread and add it to Active Threads and set it to state READY -osThreadId svcThreadCreate (const osThreadDef_t *thread_def, void *argument) { - P_TCB ptcb; - OS_TID tsk; - void *stk; - - if ((thread_def == NULL) || - (thread_def->pthread == NULL) || - (thread_def->tpriority < osPriorityIdle) || - (thread_def->tpriority > osPriorityRealtime)) { - sysThreadError(osErrorParameter); - return NULL; - } - - if (thread_def->stacksize != 0) { // Custom stack size - stk = rt_alloc_mem( // Allocate stack - os_stack_mem, - thread_def->stacksize - ); - if (stk == NULL) { - sysThreadError(osErrorNoMemory); // Out of memory - return NULL; - } - } else { // Default stack size - stk = NULL; - } - - tsk = rt_tsk_create( // Create task - (FUNCP)thread_def->pthread, // Task function pointer - (thread_def->tpriority-osPriorityIdle+1) | // Task priority - (thread_def->stacksize << 8), // Task stack size in bytes - stk, // Pointer to task's stack - argument // Argument to the task - ); - - if (tsk == 0) { // Invalid task ID - if (stk != NULL) { - rt_free_mem(os_stack_mem, stk); // Free allocated stack - } - sysThreadError(osErrorNoMemory); // Create task failed (Out of memory) - return NULL; - } - - ptcb = (P_TCB)os_active_TCB[tsk - 1]; // TCB pointer - - *((uint32_t *)ptcb->tsk_stack + 13) = (uint32_t)osThreadExit; - - return ptcb; -} - -/// Return the thread ID of the current running thread -osThreadId svcThreadGetId (void) { - OS_TID tsk; - - tsk = rt_tsk_self(); - if (tsk == 0) return NULL; - return (P_TCB)os_active_TCB[tsk - 1]; -} - -/// Terminate execution of a thread and remove it from ActiveThreads -osStatus svcThreadTerminate (osThreadId thread_id) { - OS_RESULT res; - P_TCB ptcb; - void *stk; - - ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) return osErrorParameter; - - stk = ptcb->priv_stack ? ptcb->stack : NULL; // Private stack - - res = rt_tsk_delete(ptcb->task_id); // Delete task - - if (res == OS_R_NOK) return osErrorResource; // Delete task failed - - if (stk != NULL) { - rt_free_mem(os_stack_mem, stk); // Free private stack - } - - return osOK; -} - -/// Pass control to next thread that is in state READY -osStatus svcThreadYield (void) { - rt_tsk_pass(); // Pass control to next task - return osOK; -} - -/// Change priority of an active thread -osStatus svcThreadSetPriority (osThreadId thread_id, osPriority priority) { - OS_RESULT res; - P_TCB ptcb; - - ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) return osErrorParameter; - - if ((priority < osPriorityIdle) || (priority > osPriorityRealtime)) { - return osErrorValue; - } - - res = rt_tsk_prio( // Change task priority - ptcb->task_id, // Task ID - priority - osPriorityIdle + 1 // New task priority - ); - - if (res == OS_R_NOK) return osErrorResource; // Change task priority failed - - return osOK; -} - -/// Get current priority of an active thread -osPriority svcThreadGetPriority (osThreadId thread_id) { - P_TCB ptcb; - - ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) return osPriorityError; - - return (osPriority)(ptcb->prio - 1 + osPriorityIdle); -} - - -// Thread Public API - -/// Create a thread and add it to Active Threads and set it to state READY -osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument) { - if (__exceptional_mode()) return NULL; // Not allowed in ISR - if ((__get_mode() != MODE_USR) && (os_running == 0)) { - // Privileged and not running - return svcThreadCreate(thread_def, argument); - } else { - return __svcThreadCreate(thread_def, argument); - } -} - -/// Return the thread ID of the current running thread -osThreadId osThreadGetId (void) { - if (__exceptional_mode()) return NULL; // Not allowed in ISR - return __svcThreadGetId(); -} - -/// Terminate execution of a thread and remove it from ActiveThreads -osStatus osThreadTerminate (osThreadId thread_id) { - if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR - return __svcThreadTerminate(thread_id); -} - -/// Pass control to next thread that is in state READY -osStatus osThreadYield (void) { - if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR - return __svcThreadYield(); -} - -/// Change priority of an active thread -osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority) { - if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR - return __svcThreadSetPriority(thread_id, priority); -} - -/// Get current priority of an active thread -osPriority osThreadGetPriority (osThreadId thread_id) { - if (__exceptional_mode()) return osPriorityError;// Not allowed in ISR - return __svcThreadGetPriority(thread_id); -} - -/// INTERNAL - Not Public -/// Auto Terminate Thread on exit (used implicitly when thread exists) -__NO_RETURN void osThreadExit (void) { - __svcThreadTerminate(__svcThreadGetId()); - for (;;); // Should never come here -} - -#ifdef __MBED_CMSIS_RTOS_CA9 -/// Get current thread state -uint8_t osThreadGetState (osThreadId thread_id) { - P_TCB ptcb; - - if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR - - ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) return osErrorParameter; - - return ptcb->state; -} -#endif - -// ==== Generic Wait Functions ==== - -// Generic Wait Service Calls declarations -SVC_1_1(svcDelay, osStatus, uint32_t, RET_osStatus) -#if osFeature_Wait != 0 -SVC_1_3(svcWait, os_InRegs osEvent, uint32_t, RET_osEvent) -#endif - -// Generic Wait Service Calls - -/// Wait for Timeout (Time Delay) -osStatus svcDelay (uint32_t millisec) { - if (millisec == 0) return osOK; - rt_dly_wait(rt_ms2tick(millisec)); - return osEventTimeout; -} - -/// Wait for Signal, Message, Mail, or Timeout -#if osFeature_Wait != 0 -os_InRegs osEvent_type svcWait (uint32_t millisec) { - osEvent ret; - - if (millisec == 0) { - ret.status = osOK; - return osEvent_ret_status; - } - - /* To Do: osEventSignal, osEventMessage, osEventMail */ - rt_dly_wait(rt_ms2tick(millisec)); - ret.status = osEventTimeout; - - return osEvent_ret_status; -} -#endif - - -// Generic Wait API - -/// Wait for Timeout (Time Delay) -osStatus osDelay (uint32_t millisec) { - if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR - return __svcDelay(millisec); -} - -/// Wait for Signal, Message, Mail, or Timeout -os_InRegs osEvent osWait (uint32_t millisec) { - osEvent ret; - -#if osFeature_Wait == 0 - ret.status = osErrorOS; - return ret; -#else - if (__exceptional_mode()) { // Not allowed in ISR - ret.status = osErrorISR; - return ret; - } - return __svcWait(millisec); -#endif -} - - -// ==== Timer Management ==== - -// Timer definitions -#define osTimerInvalid 0 -#define osTimerStopped 1 -#define osTimerRunning 2 - -// Timer structures - -typedef struct os_timer_cb_ { // Timer Control Block - struct os_timer_cb_ *next; // Pointer to next active Timer - uint8_t state; // Timer State - uint8_t type; // Timer Type (Periodic/One-shot) - uint16_t reserved; // Reserved - uint16_t tcnt; // Timer Delay Count - uint16_t icnt; // Timer Initial Count - void *arg; // Timer Function Argument - const osTimerDef_t *timer; // Pointer to Timer definition -} os_timer_cb; - -// Timer variables -os_timer_cb *os_timer_head; // Pointer to first active Timer - - -// Timer Helper Functions - -// Insert Timer into the list sorted by time -static void rt_timer_insert (os_timer_cb *pt, uint32_t tcnt) { - os_timer_cb *p, *prev; - - prev = NULL; - p = os_timer_head; - while (p != NULL) { - if (tcnt < p->tcnt) break; - tcnt -= p->tcnt; - prev = p; - p = p->next; - } - pt->next = p; - pt->tcnt = (uint16_t)tcnt; - if (p != NULL) { - p->tcnt -= pt->tcnt; - } - if (prev != NULL) { - prev->next = pt; - } else { - os_timer_head = pt; - } -} - -// Remove Timer from the list -static int rt_timer_remove (os_timer_cb *pt) { - os_timer_cb *p, *prev; - - prev = NULL; - p = os_timer_head; - while (p != NULL) { - if (p == pt) break; - prev = p; - p = p->next; - } - if (p == NULL) return -1; - if (prev != NULL) { - prev->next = pt->next; - } else { - os_timer_head = pt->next; - } - if (pt->next != NULL) { - pt->next->tcnt += pt->tcnt; - } - - return 0; -} - - -// Timer Service Calls declarations -SVC_3_1(svcTimerCreate, osTimerId, const osTimerDef_t *, os_timer_type, void *, RET_pointer) -SVC_2_1(svcTimerStart, osStatus, osTimerId, uint32_t, RET_osStatus) -SVC_1_1(svcTimerStop, osStatus, osTimerId, RET_osStatus) -SVC_1_1(svcTimerDelete, osStatus, osTimerId, RET_osStatus) -SVC_1_2(svcTimerCall, os_InRegs osCallback, osTimerId, RET_osCallback) - -// Timer Management Service Calls - -/// Create timer -osTimerId svcTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument) { - os_timer_cb *pt; - - if ((timer_def == NULL) || (timer_def->ptimer == NULL)) { - sysThreadError(osErrorParameter); - return NULL; - } - - pt = timer_def->timer; - if (pt == NULL) { - sysThreadError(osErrorParameter); - return NULL; - } - - if ((type != osTimerOnce) && (type != osTimerPeriodic)) { - sysThreadError(osErrorValue); - return NULL; - } - - if (osThreadId_osTimerThread == NULL) { - sysThreadError(osErrorResource); - return NULL; - } - - if (pt->state != osTimerInvalid){ - sysThreadError(osErrorResource); - return NULL; - } - - pt->state = osTimerStopped; - pt->type = (uint8_t)type; - pt->arg = argument; - pt->timer = timer_def; - - return (osTimerId)pt; -} - -/// Start or restart timer -osStatus svcTimerStart (osTimerId timer_id, uint32_t millisec) { - os_timer_cb *pt; - uint32_t tcnt; - - pt = rt_id2obj(timer_id); - if (pt == NULL) return osErrorParameter; - - tcnt = rt_ms2tick(millisec); - if (tcnt == 0) return osErrorValue; - - switch (pt->state) { - case osTimerRunning: - if (rt_timer_remove(pt) != 0) { - return osErrorResource; - } - break; - case osTimerStopped: - pt->state = osTimerRunning; - pt->icnt = (uint16_t)tcnt; - break; - default: - return osErrorResource; - } - - rt_timer_insert(pt, tcnt); - - return osOK; -} - -/// Stop timer -osStatus svcTimerStop (osTimerId timer_id) { - os_timer_cb *pt; - - pt = rt_id2obj(timer_id); - if (pt == NULL) return osErrorParameter; - - if (pt->state != osTimerRunning) return osErrorResource; - - pt->state = osTimerStopped; - - if (rt_timer_remove(pt) != 0) { - return osErrorResource; - } - - return osOK; -} - -/// Delete timer -osStatus svcTimerDelete (osTimerId timer_id) { - os_timer_cb *pt; - - pt = rt_id2obj(timer_id); - if (pt == NULL) return osErrorParameter; - - switch (pt->state) { - case osTimerRunning: - rt_timer_remove(pt); - break; - case osTimerStopped: - break; - default: - return osErrorResource; - } - - pt->state = osTimerInvalid; - - return osOK; -} - -/// Get timer callback parameters -os_InRegs osCallback_type svcTimerCall (osTimerId timer_id) { - os_timer_cb *pt; - osCallback ret; - - pt = rt_id2obj(timer_id); - if (pt == NULL) { - ret.fp = NULL; - ret.arg = NULL; - return osCallback_ret; - } - - ret.fp = (void *)pt->timer->ptimer; - ret.arg = pt->arg; - - return osCallback_ret; -} - -static __INLINE osStatus isrMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec); - -/// Timer Tick (called each SysTick) -void sysTimerTick (void) { - os_timer_cb *pt, *p; - - p = os_timer_head; - if (p == NULL) return; - - p->tcnt--; - while ((p != NULL) && (p->tcnt == 0)) { - pt = p; - p = p->next; - os_timer_head = p; - isrMessagePut(osMessageQId_osTimerMessageQ, (uint32_t)pt, 0); - if (pt->type == osTimerPeriodic) { - rt_timer_insert(pt, pt->icnt); - } else { - pt->state = osTimerStopped; - } - } -} - - -// Timer Management Public API - -/// Create timer -osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument) { - if (__exceptional_mode()) return NULL; // Not allowed in ISR - if ((__get_mode() != MODE_USR) && (os_running == 0)) { - // Privileged and not running - return svcTimerCreate(timer_def, type, argument); - } else { - return __svcTimerCreate(timer_def, type, argument); - } -} - -/// Start or restart timer -osStatus osTimerStart (osTimerId timer_id, uint32_t millisec) { - if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR - return __svcTimerStart(timer_id, millisec); -} - -/// Stop timer -osStatus osTimerStop (osTimerId timer_id) { - if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR - return __svcTimerStop(timer_id); -} - -/// Delete timer -osStatus osTimerDelete (osTimerId timer_id) { - if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR - return __svcTimerDelete(timer_id); -} - -/// INTERNAL - Not Public -/// Get timer callback parameters (used by OS Timer Thread) -os_InRegs osCallback osTimerCall (osTimerId timer_id) { - return __svcTimerCall(timer_id); -} - - -// Timer Thread -__NO_RETURN void osTimerThread (void const *argument) { - osCallback cb; - osEvent evt; - - for (;;) { - evt = osMessageGet(osMessageQId_osTimerMessageQ, osWaitForever); - if (evt.status == osEventMessage) { - cb = osTimerCall(evt.value.p); - if (cb.fp != NULL) { - (*(os_ptimer)cb.fp)(cb.arg); - } - } - } -} - - -// ==== Signal Management ==== - -// Signal Service Calls declarations -SVC_2_1(svcSignalSet, int32_t, osThreadId, int32_t, RET_int32_t) -SVC_2_1(svcSignalClear, int32_t, osThreadId, int32_t, RET_int32_t) -SVC_1_1(svcSignalGet, int32_t, osThreadId, RET_int32_t) -SVC_2_3(svcSignalWait, os_InRegs osEvent, int32_t, uint32_t, RET_osEvent) - -// Signal Service Calls - -/// Set the specified Signal Flags of an active thread -int32_t svcSignalSet (osThreadId thread_id, int32_t signals) { - P_TCB ptcb; - int32_t sig; - - ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) return 0x80000000; - - if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000; - - sig = ptcb->events; // Previous signal flags - - rt_evt_set(signals, ptcb->task_id); // Set event flags - - return sig; -} - -/// Clear the specified Signal Flags of an active thread -int32_t svcSignalClear (osThreadId thread_id, int32_t signals) { - P_TCB ptcb; - int32_t sig; - - ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) return 0x80000000; - - if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000; - - sig = ptcb->events; // Previous signal flags - - rt_evt_clr(signals, ptcb->task_id); // Clear event flags - - return sig; -} - -/// Get Signal Flags status of an active thread -int32_t svcSignalGet (osThreadId thread_id) { - P_TCB ptcb; - - ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) return 0x80000000; - - return ptcb->events; // Return event flags -} - -/// Wait for one or more Signal Flags to become signaled for the current RUNNING thread -os_InRegs osEvent_type svcSignalWait (int32_t signals, uint32_t millisec) { - OS_RESULT res; - osEvent ret; - - if (signals & (0xFFFFFFFF << osFeature_Signals)) { - ret.status = osErrorValue; - return osEvent_ret_status; - } - - if (signals != 0) { // Wait for all specified signals - res = rt_evt_wait(signals, rt_ms2tick(millisec), __TRUE); - } else { // Wait for any signal - res = rt_evt_wait(0xFFFF, rt_ms2tick(millisec), __FALSE); - } - - if (res == OS_R_EVT) { - ret.status = osEventSignal; - ret.value.signals = signals ? signals : os_tsk.run->waits; - } else { - ret.status = millisec ? osEventTimeout : osOK; - ret.value.signals = 0; - } - - return osEvent_ret_value; -} - - -// Signal ISR Calls - -/// Set the specified Signal Flags of an active thread -static __INLINE int32_t isrSignalSet (osThreadId thread_id, int32_t signals) { - P_TCB ptcb; - int32_t sig; - - ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) return 0x80000000; - - if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000; - - sig = ptcb->events; // Previous signal flags - - isr_evt_set(signals, ptcb->task_id); // Set event flags - - return sig; -} - - -// Signal Public API - -/// Set the specified Signal Flags of an active thread -int32_t osSignalSet (osThreadId thread_id, int32_t signals) { - if (__exceptional_mode()) { // in ISR - return isrSignalSet(thread_id, signals); - } else { // in Thread - return __svcSignalSet(thread_id, signals); - } -} - -/// Clear the specified Signal Flags of an active thread -int32_t osSignalClear (osThreadId thread_id, int32_t signals) { - if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR - return __svcSignalClear(thread_id, signals); -} - -/// Get Signal Flags status of an active thread -int32_t osSignalGet (osThreadId thread_id) { - if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR - return __svcSignalGet(thread_id); -} - -/// Wait for one or more Signal Flags to become signaled for the current RUNNING thread -os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec) { - osEvent ret; - - if (__exceptional_mode()) { // Not allowed in ISR - ret.status = osErrorISR; - return ret; - } - return __svcSignalWait(signals, millisec); -} - - -// ==== Mutex Management ==== - -// Mutex Service Calls declarations -SVC_1_1(svcMutexCreate, osMutexId, const osMutexDef_t *, RET_pointer) -SVC_2_1(svcMutexWait, osStatus, osMutexId, uint32_t, RET_osStatus) -SVC_1_1(svcMutexRelease, osStatus, osMutexId, RET_osStatus) -SVC_1_1(svcMutexDelete, osStatus, osMutexId, RET_osStatus) - -// Mutex Service Calls - -/// Create and Initialize a Mutex object -osMutexId svcMutexCreate (const osMutexDef_t *mutex_def) { - OS_ID mut; - - if (mutex_def == NULL) { - sysThreadError(osErrorParameter); - return NULL; - } - - mut = mutex_def->mutex; - if (mut == NULL) { - sysThreadError(osErrorParameter); - return NULL; - } - - if (((P_MUCB)mut)->cb_type != 0) { - sysThreadError(osErrorParameter); - return NULL; - } - - rt_mut_init(mut); // Initialize Mutex - - return mut; -} - -/// Wait until a Mutex becomes available -osStatus svcMutexWait (osMutexId mutex_id, uint32_t millisec) { - OS_ID mut; - OS_RESULT res; - - mut = rt_id2obj(mutex_id); - if (mut == NULL) return osErrorParameter; - - if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter; - - res = rt_mut_wait(mut, rt_ms2tick(millisec)); // Wait for Mutex - - if (res == OS_R_TMO) { - return (millisec ? osErrorTimeoutResource : osErrorResource); - } - - return osOK; -} - -/// Release a Mutex that was obtained with osMutexWait -osStatus svcMutexRelease (osMutexId mutex_id) { - OS_ID mut; - OS_RESULT res; - - mut = rt_id2obj(mutex_id); - if (mut == NULL) return osErrorParameter; - - if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter; - - res = rt_mut_release(mut); // Release Mutex - - if (res == OS_R_NOK) return osErrorResource; // Thread not owner or Zero Counter - - return osOK; -} - -/// Delete a Mutex that was created by osMutexCreate -osStatus svcMutexDelete (osMutexId mutex_id) { - OS_ID mut; - - mut = rt_id2obj(mutex_id); - if (mut == NULL) return osErrorParameter; - - if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter; - - rt_mut_delete(mut); // Release Mutex - - return osOK; -} - - -// Mutex Public API - -/// Create and Initialize a Mutex object -osMutexId osMutexCreate (const osMutexDef_t *mutex_def) { - if (__exceptional_mode()) return NULL; // Not allowed in ISR - if ((__get_mode() != MODE_USR) && (os_running == 0)) { - // Privileged and not running - return svcMutexCreate(mutex_def); - } else { - return __svcMutexCreate(mutex_def); - } -} - -/// Wait until a Mutex becomes available -osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec) { - if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR - return __svcMutexWait(mutex_id, millisec); -} - -/// Release a Mutex that was obtained with osMutexWait -osStatus osMutexRelease (osMutexId mutex_id) { - if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR - return __svcMutexRelease(mutex_id); -} - -/// Delete a Mutex that was created by osMutexCreate -osStatus osMutexDelete (osMutexId mutex_id) { - if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR - return __svcMutexDelete(mutex_id); -} - - -// ==== Semaphore Management ==== - -// Semaphore Service Calls declarations -SVC_2_1(svcSemaphoreCreate, osSemaphoreId, const osSemaphoreDef_t *, int32_t, RET_pointer) -SVC_2_1(svcSemaphoreWait, int32_t, osSemaphoreId, uint32_t, RET_int32_t) -SVC_1_1(svcSemaphoreRelease, osStatus, osSemaphoreId, RET_osStatus) -SVC_1_1(svcSemaphoreDelete, osStatus, osSemaphoreId, RET_osStatus) - -// Semaphore Service Calls - -/// Create and Initialize a Semaphore object -osSemaphoreId svcSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count) { - OS_ID sem; - - if (semaphore_def == NULL) { - sysThreadError(osErrorParameter); - return NULL; - } - - sem = semaphore_def->semaphore; - if (sem == NULL) { - sysThreadError(osErrorParameter); - return NULL; - } - - if (((P_SCB)sem)->cb_type != 0) { - sysThreadError(osErrorParameter); - return NULL; - } - - if (count > osFeature_Semaphore) { - sysThreadError(osErrorValue); - return NULL; - } - - rt_sem_init(sem, count); // Initialize Semaphore - - return sem; -} - -/// Wait until a Semaphore becomes available -int32_t svcSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) { - OS_ID sem; - OS_RESULT res; - - sem = rt_id2obj(semaphore_id); - if (sem == NULL) return -1; - - if (((P_SCB)sem)->cb_type != SCB) return -1; - - res = rt_sem_wait(sem, rt_ms2tick(millisec)); // Wait for Semaphore - - if (res == OS_R_TMO) return 0; // Timeout - - return (((P_SCB)sem)->tokens + 1); -} - -/// Release a Semaphore -osStatus svcSemaphoreRelease (osSemaphoreId semaphore_id) { - OS_ID sem; - - sem = rt_id2obj(semaphore_id); - if (sem == NULL) return osErrorParameter; - - if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter; - - if (((P_SCB)sem)->tokens == osFeature_Semaphore) return osErrorResource; - - rt_sem_send(sem); // Release Semaphore - - return osOK; -} - -/// Delete a Semaphore that was created by osSemaphoreCreate -osStatus svcSemaphoreDelete (osSemaphoreId semaphore_id) { - OS_ID sem; - - sem = rt_id2obj(semaphore_id); - if (sem == NULL) return osErrorParameter; - - if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter; - - rt_sem_delete(sem); // Delete Semaphore - - return osOK; -} - - -// Semaphore ISR Calls - -/// Release a Semaphore -static __INLINE osStatus isrSemaphoreRelease (osSemaphoreId semaphore_id) { - OS_ID sem; - - sem = rt_id2obj(semaphore_id); - if (sem == NULL) return osErrorParameter; - - if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter; - - if (((P_SCB)sem)->tokens == osFeature_Semaphore) return osErrorResource; - - isr_sem_send(sem); // Release Semaphore - - return osOK; -} - - -// Semaphore Public API - -/// Create and Initialize a Semaphore object -osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count) { - if (__exceptional_mode()) return NULL; // Not allowed in ISR - if ((__get_mode() != MODE_USR) && (os_running == 0)) { - // Privileged and not running - return svcSemaphoreCreate(semaphore_def, count); - } else { - return __svcSemaphoreCreate(semaphore_def, count); - } -} - -/// Wait until a Semaphore becomes available -int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) { - if (__exceptional_mode()) return -1; // Not allowed in ISR - return __svcSemaphoreWait(semaphore_id, millisec); -} - -/// Release a Semaphore -osStatus osSemaphoreRelease (osSemaphoreId semaphore_id) { - if (__exceptional_mode()) { // in ISR - return isrSemaphoreRelease(semaphore_id); - } else { // in Thread - return __svcSemaphoreRelease(semaphore_id); - } -} - -/// Delete a Semaphore that was created by osSemaphoreCreate -osStatus osSemaphoreDelete (osSemaphoreId semaphore_id) { - if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR - return __svcSemaphoreDelete(semaphore_id); -} - - -// ==== Memory Management Functions ==== - -// Memory Management Helper Functions - -// Clear Memory Box (Zero init) -static void rt_clr_box (void *box_mem, void *box) { - uint32_t *p, n; - - if (box) { - p = box; - for (n = ((P_BM)box_mem)->blk_size; n; n -= 4) { - *p++ = 0; - } - } -} - -// Memory Management Service Calls declarations -SVC_1_1(svcPoolCreate, osPoolId, const osPoolDef_t *, RET_pointer) -SVC_2_1(sysPoolAlloc, void *, osPoolId, uint32_t, RET_pointer) -SVC_2_1(sysPoolFree, osStatus, osPoolId, void *, RET_osStatus) - -// Memory Management Service & ISR Calls - -/// Create and Initialize memory pool -osPoolId svcPoolCreate (const osPoolDef_t *pool_def) { - uint32_t blk_sz; - - if ((pool_def == NULL) || - (pool_def->pool_sz == 0) || - (pool_def->item_sz == 0) || - (pool_def->pool == NULL)) { - sysThreadError(osErrorParameter); - return NULL; - } - - blk_sz = (pool_def->item_sz + 3) & ~3; - - _init_box(pool_def->pool, sizeof(struct OS_BM) + pool_def->pool_sz * blk_sz, blk_sz); - - return pool_def->pool; -} - -/// Allocate a memory block from a memory pool -void *sysPoolAlloc (osPoolId pool_id, uint32_t clr) { - void *ptr; - - if (pool_id == NULL) return NULL; - - ptr = rt_alloc_box(pool_id); - if (clr) { - rt_clr_box(pool_id, ptr); - } - - return ptr; -} - -/// Return an allocated memory block back to a specific memory pool -osStatus sysPoolFree (osPoolId pool_id, void *block) { - int32_t res; - - if (pool_id == NULL) return osErrorParameter; - - res = rt_free_box(pool_id, block); - if (res != 0) return osErrorValue; - - return osOK; -} - - -// Memory Management Public API - -/// Create and Initialize memory pool -osPoolId osPoolCreate (const osPoolDef_t *pool_def) { - if (__exceptional_mode()) return NULL; // Not allowed in ISR - if ((__get_mode() != MODE_USR) && (os_running == 0)) { - // Privileged and not running - return svcPoolCreate(pool_def); - } else { - return __svcPoolCreate(pool_def); - } -} - -/// Allocate a memory block from a memory pool -void *osPoolAlloc (osPoolId pool_id) { - if (__get_mode() != MODE_USR) { // in ISR or Privileged - return sysPoolAlloc(pool_id, 0); - } else { // in Thread - return __sysPoolAlloc(pool_id, 0); - } -} - -/// Allocate a memory block from a memory pool and set memory block to zero -void *osPoolCAlloc (osPoolId pool_id) { - if (__get_mode() != MODE_USR) { // in ISR or Privileged - return sysPoolAlloc(pool_id, 1); - } else { // in Thread - return __sysPoolAlloc(pool_id, 1); - } -} - -/// Return an allocated memory block back to a specific memory pool -osStatus osPoolFree (osPoolId pool_id, void *block) { - if (__get_mode() != MODE_USR) { // in ISR or Privileged - return sysPoolFree(pool_id, block); - } else { // in Thread - return __sysPoolFree(pool_id, block); - } -} - - -// ==== Message Queue Management Functions ==== - -// Message Queue Management Service Calls declarations -SVC_2_1(svcMessageCreate, osMessageQId, const osMessageQDef_t *, osThreadId, RET_pointer) -SVC_3_1(svcMessagePut, osStatus, osMessageQId, uint32_t, uint32_t, RET_osStatus) -SVC_2_3(svcMessageGet, os_InRegs osEvent, osMessageQId, uint32_t, RET_osEvent) - -// Message Queue Service Calls - -/// Create and Initialize Message Queue -osMessageQId svcMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id) { - - if ((queue_def == NULL) || - (queue_def->queue_sz == 0) || - (queue_def->pool == NULL)) { - sysThreadError(osErrorParameter); - return NULL; - } - - if (((P_MCB)queue_def->pool)->cb_type != 0) { - sysThreadError(osErrorParameter); - return NULL; - } - - rt_mbx_init(queue_def->pool, 4*(queue_def->queue_sz + 4)); - - return queue_def->pool; -} - -/// Put a Message to a Queue -osStatus svcMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { - OS_RESULT res; - - if (queue_id == NULL) return osErrorParameter; - - if (((P_MCB)queue_id)->cb_type != MCB) return osErrorParameter; - - res = rt_mbx_send(queue_id, (void *)info, rt_ms2tick(millisec)); - - if (res == OS_R_TMO) { - return (millisec ? osErrorTimeoutResource : osErrorResource); - } - - return osOK; -} - -/// Get a Message or Wait for a Message from a Queue -os_InRegs osEvent_type svcMessageGet (osMessageQId queue_id, uint32_t millisec) { - OS_RESULT res; - osEvent ret; - - if (queue_id == NULL) { - ret.status = osErrorParameter; - return osEvent_ret_status; - } - - if (((P_MCB)queue_id)->cb_type != MCB) { - ret.status = osErrorParameter; - return osEvent_ret_status; - } - - res = rt_mbx_wait(queue_id, &ret.value.p, rt_ms2tick(millisec)); - - if (res == OS_R_TMO) { - ret.status = millisec ? osEventTimeout : osOK; - return osEvent_ret_value; - } - - ret.status = osEventMessage; - - return osEvent_ret_value; -} - - -// Message Queue ISR Calls - -/// Put a Message to a Queue -static __INLINE osStatus isrMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { - - if ((queue_id == NULL) || (millisec != 0)) { - return osErrorParameter; - } - - if (((P_MCB)queue_id)->cb_type != MCB) return osErrorParameter; - - if (rt_mbx_check(queue_id) == 0) { // Check if Queue is full - return osErrorResource; - } - - isr_mbx_send(queue_id, (void *)info); - - return osOK; -} - -/// Get a Message or Wait for a Message from a Queue -static __INLINE os_InRegs osEvent isrMessageGet (osMessageQId queue_id, uint32_t millisec) { - OS_RESULT res; - osEvent ret; - - if ((queue_id == NULL) || (millisec != 0)) { - ret.status = osErrorParameter; - return ret; - } - - if (((P_MCB)queue_id)->cb_type != MCB) { - ret.status = osErrorParameter; - return ret; - } - - res = isr_mbx_receive(queue_id, &ret.value.p); - - if (res != OS_R_MBX) { - ret.status = osOK; - return ret; - } - - ret.status = osEventMessage; - - return ret; -} - - -// Message Queue Management Public API - -/// Create and Initialize Message Queue -osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id) { - if (__exceptional_mode()) return NULL; // Not allowed in ISR - if ((__get_mode() != MODE_USR) && (os_running == 0)) { - // Privileged and not running - return svcMessageCreate(queue_def, thread_id); - } else { - return __svcMessageCreate(queue_def, thread_id); - } -} - -/// Put a Message to a Queue -osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { - if (__exceptional_mode()) { // in ISR - return isrMessagePut(queue_id, info, millisec); - } else { // in Thread - return __svcMessagePut(queue_id, info, millisec); - } -} - -/// Get a Message or Wait for a Message from a Queue -os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec) { - if (__exceptional_mode()) { // in ISR - return isrMessageGet(queue_id, millisec); - } else { // in Thread - return __svcMessageGet(queue_id, millisec); - } -} - - -// ==== Mail Queue Management Functions ==== - -// Mail Queue Management Service Calls declarations -SVC_2_1(svcMailCreate, osMailQId, const osMailQDef_t *, osThreadId, RET_pointer) -SVC_4_1(sysMailAlloc, void *, osMailQId, uint32_t, uint32_t, uint32_t, RET_pointer) -SVC_3_1(sysMailFree, osStatus, osMailQId, void *, uint32_t, RET_osStatus) - -// Mail Queue Management Service & ISR Calls - -/// Create and Initialize mail queue -osMailQId svcMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id) { - uint32_t blk_sz; - P_MCB pmcb; - void *pool; - - if ((queue_def == NULL) || - (queue_def->queue_sz == 0) || - (queue_def->item_sz == 0) || - (queue_def->pool == NULL)) { - sysThreadError(osErrorParameter); - return NULL; - } - - pmcb = *(((void **)queue_def->pool) + 0); - pool = *(((void **)queue_def->pool) + 1); - - if ((pool == NULL) || (pmcb == NULL) || (pmcb->cb_type != 0)) { - sysThreadError(osErrorParameter); - return NULL; - } - - blk_sz = (queue_def->item_sz + 3) & ~3; - - _init_box(pool, sizeof(struct OS_BM) + queue_def->queue_sz * blk_sz, blk_sz); - - rt_mbx_init(pmcb, 4*(queue_def->queue_sz + 4)); - - - return queue_def->pool; -} - -/// Allocate a memory block from a mail -void *sysMailAlloc (osMailQId queue_id, uint32_t millisec, uint32_t isr, uint32_t clr) { - P_MCB pmcb; - void *pool; - void *mem; - - if (queue_id == NULL) return NULL; - - pmcb = *(((void **)queue_id) + 0); - pool = *(((void **)queue_id) + 1); - - if ((pool == NULL) || (pmcb == NULL)) return NULL; - - if (isr && (millisec != 0)) return NULL; - - mem = rt_alloc_box(pool); - if (clr) { - rt_clr_box(pool, mem); - } - - if ((mem == NULL) && (millisec != 0)) { - // Put Task to sleep when Memory not available - if (pmcb->p_lnk != NULL) { - rt_put_prio((P_XCB)pmcb, os_tsk.run); - } else { - pmcb->p_lnk = os_tsk.run; - os_tsk.run->p_lnk = NULL; - os_tsk.run->p_rlnk = (P_TCB)pmcb; - // Task is waiting to allocate a message - pmcb->state = 3; - } - rt_block(rt_ms2tick(millisec), WAIT_MBX); - } - - return mem; -} - -/// Free a memory block from a mail -osStatus sysMailFree (osMailQId queue_id, void *mail, uint32_t isr) { - P_MCB pmcb; - P_TCB ptcb; - void *pool; - void *mem; - int32_t res; - - if (queue_id == NULL) return osErrorParameter; - - pmcb = *(((void **)queue_id) + 0); - pool = *(((void **)queue_id) + 1); - - if ((pmcb == NULL) || (pool == NULL)) return osErrorParameter; - - res = rt_free_box(pool, mail); - - if (res != 0) return osErrorValue; - - if (pmcb->state == 3) { - // Task is waiting to allocate a message - if (isr) { - rt_psq_enq (pmcb, (U32)pool); - rt_psh_req (); - } else { - mem = rt_alloc_box(pool); - if (mem != NULL) { - ptcb = rt_get_first((P_XCB)pmcb); - if (pmcb->p_lnk == NULL) { - pmcb->state = 0; - } - rt_ret_val(ptcb, (U32)mem); - rt_rmv_dly(ptcb); - rt_dispatch(ptcb); - } - } - } - - return osOK; -} - - -// Mail Queue Management Public API - -/// Create and Initialize mail queue -osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id) { - if (__exceptional_mode()) return NULL; // Not allowed in ISR - if ((__get_mode() != MODE_USR) && (os_running == 0)) { - // Privileged and not running - return svcMailCreate(queue_def, thread_id); - } else { - return __svcMailCreate(queue_def, thread_id); - } -} - -/// Allocate a memory block from a mail -void *osMailAlloc (osMailQId queue_id, uint32_t millisec) { - if (__exceptional_mode()) { // in ISR - return sysMailAlloc(queue_id, millisec, 1, 0); - } else { // in Thread - return __sysMailAlloc(queue_id, millisec, 0, 0); - } -} - -/// Allocate a memory block from a mail and set memory block to zero -void *osMailCAlloc (osMailQId queue_id, uint32_t millisec) { - if (__exceptional_mode()) { // in ISR - return sysMailAlloc(queue_id, millisec, 1, 1); - } else { // in Thread - return __sysMailAlloc(queue_id, millisec, 0, 1); - } -} - -/// Free a memory block from a mail -osStatus osMailFree (osMailQId queue_id, void *mail) { - if (__exceptional_mode()) { // in ISR - return sysMailFree(queue_id, mail, 1); - } else { // in Thread - return __sysMailFree(queue_id, mail, 0); - } -} - -/// Put a mail to a queue -osStatus osMailPut (osMailQId queue_id, void *mail) { - if (queue_id == NULL) return osErrorParameter; - if (mail == NULL) return osErrorValue; - return osMessagePut(*((void **)queue_id), (uint32_t)mail, 0); -} - -/// Get a mail from a queue -os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec) { - osEvent ret; - - if (queue_id == NULL) { - ret.status = osErrorParameter; - return ret; - } - - ret = osMessageGet(*((void **)queue_id), millisec); - if (ret.status == osEventMessage) ret.status = osEventMail; - - return ret; -}
--- a/rtx_ca/rt_Event.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,194 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_EVENT.C - * Purpose: Implements waits and wake-ups for event flags - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_System.h" -#include "rt_Event.h" -#include "rt_List.h" -#include "rt_Task.h" -#ifdef __CORTEX_A9 -#include "rt_HAL_CA.h" -#else -#include "rt_HAL_CM.h" -#endif - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_evt_wait -----------------------------------*/ - -OS_RESULT rt_evt_wait (U16 wait_flags, U16 timeout, BOOL and_wait) { - /* Wait for one or more event flags with optional time-out. */ - /* "wait_flags" identifies the flags to wait for. */ - /* "timeout" is the time-out limit in system ticks (0xffff if no time-out) */ - /* "and_wait" specifies the AND-ing of "wait_flags" as condition to be met */ - /* to complete the wait. (OR-ing if set to 0). */ - U32 block_state; - - if (and_wait) { - /* Check for AND-connected events */ - if ((os_tsk.run->events & wait_flags) == wait_flags) { - os_tsk.run->events &= ~wait_flags; - return (OS_R_EVT); - } - block_state = WAIT_AND; - } - else { - /* Check for OR-connected events */ - if (os_tsk.run->events & wait_flags) { - os_tsk.run->waits = os_tsk.run->events & wait_flags; - os_tsk.run->events &= ~wait_flags; - return (OS_R_EVT); - } - block_state = WAIT_OR; - } - /* Task has to wait */ - os_tsk.run->waits = wait_flags; - rt_block (timeout, (U8)block_state); - return (OS_R_TMO); -} - - -/*--------------------------- rt_evt_set ------------------------------------*/ - -void rt_evt_set (U16 event_flags, OS_TID task_id) { - /* Set one or more event flags of a selectable task. */ - P_TCB p_tcb; - - p_tcb = os_active_TCB[task_id-1]; - if (p_tcb == NULL) { - return; - } - p_tcb->events |= event_flags; - event_flags = p_tcb->waits; - /* If the task is not waiting for an event, it should not be put */ - /* to ready state. */ - if (p_tcb->state == WAIT_AND) { - /* Check for AND-connected events */ - if ((p_tcb->events & event_flags) == event_flags) { - goto wkup; - } - } - if (p_tcb->state == WAIT_OR) { - /* Check for OR-connected events */ - if (p_tcb->events & event_flags) { - p_tcb->waits &= p_tcb->events; -wkup: p_tcb->events &= ~event_flags; - rt_rmv_dly (p_tcb); - p_tcb->state = READY; -#ifdef __CMSIS_RTOS - rt_ret_val2(p_tcb, 0x08/*osEventSignal*/, p_tcb->waits); -#else - rt_ret_val (p_tcb, OS_R_EVT); -#endif - rt_dispatch (p_tcb); - } - } -} - - -/*--------------------------- rt_evt_clr ------------------------------------*/ - -void rt_evt_clr (U16 clear_flags, OS_TID task_id) { - /* Clear one or more event flags (identified by "clear_flags") of a */ - /* selectable task (identified by "task"). */ - P_TCB task = os_active_TCB[task_id-1]; - - if (task == NULL) { - return; - } - task->events &= ~clear_flags; -} - - -/*--------------------------- isr_evt_set -----------------------------------*/ - -void isr_evt_set (U16 event_flags, OS_TID task_id) { - /* Same function as "os_evt_set", but to be called by ISRs. */ - P_TCB p_tcb = os_active_TCB[task_id-1]; - - if (p_tcb == NULL) { - return; - } - rt_psq_enq (p_tcb, event_flags); - rt_psh_req (); -} - - -/*--------------------------- rt_evt_get ------------------------------------*/ - -U16 rt_evt_get (void) { - /* Get events of a running task after waiting for OR connected events. */ - return (os_tsk.run->waits); -} - - -/*--------------------------- rt_evt_psh ------------------------------------*/ - -void rt_evt_psh (P_TCB p_CB, U16 set_flags) { - /* Check if task has to be waken up */ - U16 event_flags; - - p_CB->events |= set_flags; - event_flags = p_CB->waits; - if (p_CB->state == WAIT_AND) { - /* Check for AND-connected events */ - if ((p_CB->events & event_flags) == event_flags) { - goto rdy; - } - } - if (p_CB->state == WAIT_OR) { - /* Check for OR-connected events */ - if (p_CB->events & event_flags) { - p_CB->waits &= p_CB->events; -rdy: p_CB->events &= ~event_flags; - rt_rmv_dly (p_CB); - p_CB->state = READY; -#ifdef __CMSIS_RTOS - rt_ret_val2(p_CB, 0x08/*osEventSignal*/, p_CB->waits); -#else - rt_ret_val (p_CB, OS_R_EVT); -#endif - rt_put_prio (&os_rdy, p_CB); - } - } -} - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/rtx_ca/rt_Event.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_EVENT.H - * Purpose: Implements waits and wake-ups for event flags - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Functions */ -extern OS_RESULT rt_evt_wait (U16 wait_flags, U16 timeout, BOOL and_wait); -extern void rt_evt_set (U16 event_flags, OS_TID task_id); -extern void rt_evt_clr (U16 clear_flags, OS_TID task_id); -extern void isr_evt_set (U16 event_flags, OS_TID task_id); -extern U16 rt_evt_get (void); -extern void rt_evt_psh (P_TCB p_CB, U16 set_flags); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx_ca/rt_HAL_CA.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,199 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_HAL_CM.H - * Purpose: Hardware Abstraction Layer for Cortex-A definitions - * Rev.: 21 Aug 2013 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Definitions */ -#define INIT_CPSR_SYS 0x4000001F -#define INIT_CPSR_USER 0x40000010 - -#define CPSR_T_BIT 0x20 -#define CPSR_I_BIT 0x80 -#define CPSR_F_BIT 0x40 - -#define MODE_USR 0x10 -#define MODE_FIQ 0x11 -#define MODE_IRQ 0x12 -#define MODE_SVC 0x13 -#define MODE_ABT 0x17 -#define MODE_UND 0x1B -#define MODE_SYS 0x1F - -#define MAGIC_WORD 0xE25A2EA5 - -#include "core_ca9.h" - -#if defined (__CC_ARM) /* ARM Compiler */ - -#if ((__TARGET_ARCH_7_M || __TARGET_ARCH_7E_M || __TARGET_ARCH_7_A) && !NO_EXCLUSIVE_ACCESS) - #define __USE_EXCLUSIVE_ACCESS -#else - #undef __USE_EXCLUSIVE_ACCESS -#endif - -#elif defined (__GNUC__) /* GNU Compiler */ - -#error GNU Compiler support not implemented for Cortex-A - -#elif defined (__ICCARM__) /* IAR Compiler */ - -#error IAR Compiler support not implemented for Cortex-A - -#endif - -static U8 priority = 0xff; - -extern const U32 GICDistributor_BASE; -extern const U32 GICInterface_BASE; - -/* GIC registers - Distributor */ -#define GICD_ICDICER0 (*((volatile U32 *)(GICDistributor_BASE + 0x180))) /* - RW - Interrupt Clear-Enable Registers */ -#define GICD_ICDISER0 (*((volatile U32 *)(GICDistributor_BASE + 0x100))) /* - RW - Interrupt Set-Enable Registers */ -#define GICD_ICDIPR0 (*((volatile U32 *)(GICDistributor_BASE + 0x400))) /* - RW - Interrupt Priority Registers */ -#define GICD_ICDSGIR (*((volatile U32 *)(GICDistributor_BASE + 0xf00))) /* - RW - Interrupt Software Interrupt Register */ -#define GICD_ICDICERx(irq) *(volatile U32 *)(&GICD_ICDICER0 + irq/32) -#define GICD_ICDISERx(irq) *(volatile U32 *)(&GICD_ICDISER0 + irq/32) - -/* GIC register - CPU Interface */ -#define GICI_ICCPMR (*((volatile U32 *)(GICInterface_BASE + 0x004))) /* - RW - Interrupt Priority Mask Register */ - -#define SGI_PENDSV 0 /* SGI0 */ -#define SGI_PENDSV_BIT ((U32)(1 << (SGI_PENDSV & 0xf))) - -//Increase priority filter to prevent timer and PendSV interrupts signaling. Guarantees that interrupts will not be forwarded. -#define OS_LOCK() int irq_dis = __disable_irq();\ - priority = GICI_ICCPMR; \ - GICI_ICCPMR = 0xff; \ - GICI_ICCPMR = GICI_ICCPMR - 1; \ - while(GICI_ICCPMR > priority);\ - __DSB();\ - if(!irq_dis) __enable_irq(); \ - -//Restore priority filter. Re-enable timer and PendSV signaling -#define OS_UNLOCK() __DSB(); \ - GICI_ICCPMR = priority; \ - -#define OS_PEND_IRQ() GICD_ICDSGIR = 0x0010000 | SGI_PENDSV -#define OS_PEND(fl,p) if(p) OS_PEND_IRQ(); -#define OS_UNPEND(fl) - -/* HW initialization needs to be done in os_tick_init (void) -RTX_Conf_CM.c- - * OS_X_INIT enables the IRQ n in the GIC */ -#define OS_X_INIT(n) char *reg; \ - reg = (char *)(&GICD_ICDIPR0 + n / 4); \ - reg += n % 4; \ - *reg = (char)0xff; \ - *reg = *reg - 1; \ - GICD_ICDISERx(n) = (U32)(1 << n % 32); -#define OS_X_LOCK(n) OS_LOCK() -#define OS_X_UNLOCK(n) OS_UNLOCK() -#define OS_X_PEND_IRQ() OS_PEND_IRQ() -#define OS_X_PEND(fl,p) if(p) OS_X_PEND_IRQ(); -#define OS_X_UNPEND(fl) - - -/* Functions */ -#ifdef __USE_EXCLUSIVE_ACCESS - #define rt_inc(p) while(__strex((__ldrex(p)+1),p)) - #define rt_dec(p) while(__strex((__ldrex(p)-1),p)) -#else - #define rt_inc(p) { int irq_dis = __disable_irq();(*p)++;if(!irq_dis) __enable_irq(); } - #define rt_dec(p) { int irq_dis = __disable_irq();(*p)--;if(!irq_dis) __enable_irq(); } -#endif - -__inline static U32 rt_inc_qi (U32 size, U8 *count, U8 *first) { - U32 cnt,c2; -#ifdef __USE_EXCLUSIVE_ACCESS - do { - if ((cnt = __ldrex(count)) == size) { - __clrex(); - return (cnt); } - } while (__strex(cnt+1, count)); - do { - c2 = (cnt = __ldrex(first)) + 1; - if (c2 == size) c2 = 0; - } while (__strex(c2, first)); -#else - int irq_dis; - irq_dis = __disable_irq(); - if ((cnt = *count) < size) { - *count = cnt+1; - c2 = (cnt = *first) + 1; - if (c2 == size) c2 = 0; - *first = c2; - } - if(!irq_dis) __enable_irq (); -#endif - return (cnt); -} - -__inline static void rt_systick_init (void) { - /* Cortex-A doesn't have a Systick. User needs to provide an alternative timer using RTX_Conf_CM configuration */ - /* HW initialization needs to be done in os_tick_init (void) -RTX_Conf_CM.c- */ -} - -__inline static void rt_svc_init (void) { - /* Register pendSV - through SGI */ - char *reg; - - reg = (char *)(&GICD_ICDIPR0 + SGI_PENDSV/4); - reg += SGI_PENDSV % 4; - /* Write 0xff to read priority level */ - *reg = (char)0xff; - /* Read priority level and set the lowest possible*/ - *reg = *reg - 1; - - GICD_ICDISERx(SGI_PENDSV) = (U32)SGI_PENDSV_BIT; -} - -extern void rt_set_PSP (U32 stack); -extern U32 rt_get_PSP (void); -extern void os_set_env (P_TCB p_TCB); -extern void *_alloc_box (void *box_mem); -extern int _free_box (void *box_mem, void *box); - -extern void rt_init_stack (P_TCB p_TCB, FUNCP task_body); -extern void rt_ret_val (P_TCB p_TCB, U32 v0); -extern void rt_ret_val2 (P_TCB p_TCB, U32 v0, U32 v1); - -extern void dbg_init (void); -extern void dbg_task_notify (P_TCB p_tcb, BOOL create); -extern void dbg_task_switch (U32 task_id); - -#define DBG_INIT() -#define DBG_TASK_NOTIFY(p_tcb,create) -#define DBG_TASK_SWITCH(task_id) - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx_ca/rt_HAL_CM.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,276 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_HAL_CM.H - * Purpose: Hardware Abstraction Layer for Cortex-M definitions - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Definitions */ -#define INITIAL_xPSR 0x01000000 -#define DEMCR_TRCENA 0x01000000 -#define ITM_ITMENA 0x00000001 -#define MAGIC_WORD 0xE25A2EA5 - -#if defined (__CC_ARM) /* ARM Compiler */ - -#if ((__TARGET_ARCH_7_M || __TARGET_ARCH_7E_M) && !NO_EXCLUSIVE_ACCESS) - #define __USE_EXCLUSIVE_ACCESS -#else - #undef __USE_EXCLUSIVE_ACCESS -#endif - -#elif defined (__GNUC__) /* GNU Compiler */ - -#undef __USE_EXCLUSIVE_ACCESS - -#if defined (__CORTEX_M0) -#define __TARGET_ARCH_6S_M 1 -#else -#define __TARGET_ARCH_6S_M 0 -#endif - -#if defined (__VFP_FP__) && !defined(__SOFTFP__) -#define __TARGET_FPU_VFP 1 -#else -#define __TARGET_FPU_VFP 0 -#endif - -#define __inline inline -#define __weak __attribute__((weak)) - -#ifndef __CMSIS_GENERIC - -__attribute__((always_inline)) static inline void __enable_irq(void) -{ - __asm volatile ("cpsie i"); -} - -__attribute__((always_inline)) static inline U32 __disable_irq(void) -{ - U32 result; - - __asm volatile ("mrs %0, primask" : "=r" (result)); - __asm volatile ("cpsid i"); - return(result & 1); -} - -#endif - -__attribute__(( always_inline)) static inline U8 __clz(U32 value) -{ - U8 result; - - __asm volatile ("clz %0, %1" : "=r" (result) : "r" (value)); - return(result); -} - -#elif defined (__ICCARM__) /* IAR Compiler */ - -#undef __USE_EXCLUSIVE_ACCESS - -#if (__CORE__ == __ARM6M__) -#define __TARGET_ARCH_6S_M 1 -#else -#define __TARGET_ARCH_6S_M 0 -#endif - -#if defined __ARMVFP__ -#define __TARGET_FPU_VFP 1 -#else -#define __TARGET_FPU_VFP 0 -#endif - -#define __inline inline - -#ifndef __CMSIS_GENERIC - -static inline void __enable_irq(void) -{ - __asm volatile ("cpsie i"); -} - -static inline U32 __disable_irq(void) -{ - U32 result; - - __asm volatile ("mrs %0, primask" : "=r" (result)); - __asm volatile ("cpsid i"); - return(result & 1); -} - -#endif - -static inline U8 __clz(U32 value) -{ - U8 result; - - __asm volatile ("clz %0, %1" : "=r" (result) : "r" (value)); - return(result); -} - -#endif - -/* NVIC registers */ -#define NVIC_ST_CTRL (*((volatile U32 *)0xE000E010)) -#define NVIC_ST_RELOAD (*((volatile U32 *)0xE000E014)) -#define NVIC_ST_CURRENT (*((volatile U32 *)0xE000E018)) -#define NVIC_ISER ((volatile U32 *)0xE000E100) -#define NVIC_ICER ((volatile U32 *)0xE000E180) -#if (__TARGET_ARCH_6S_M) -#define NVIC_IP ((volatile U32 *)0xE000E400) -#else -#define NVIC_IP ((volatile U8 *)0xE000E400) -#endif -#define NVIC_INT_CTRL (*((volatile U32 *)0xE000ED04)) -#define NVIC_AIR_CTRL (*((volatile U32 *)0xE000ED0C)) -#define NVIC_SYS_PRI2 (*((volatile U32 *)0xE000ED1C)) -#define NVIC_SYS_PRI3 (*((volatile U32 *)0xE000ED20)) - -#define OS_PEND_IRQ() NVIC_INT_CTRL = (1<<28) -#define OS_PENDING ((NVIC_INT_CTRL >> 26) & (1<<2 | 1)) -#define OS_UNPEND(fl) NVIC_INT_CTRL = (*fl = OS_PENDING) << 25 -#define OS_PEND(fl,p) NVIC_INT_CTRL = (fl | p<<2) << 26 -#define OS_LOCK() NVIC_ST_CTRL = 0x0005 -#define OS_UNLOCK() NVIC_ST_CTRL = 0x0007 - -#define OS_X_PENDING ((NVIC_INT_CTRL >> 28) & 1) -#define OS_X_UNPEND(fl) NVIC_INT_CTRL = (*fl = OS_X_PENDING) << 27 -#define OS_X_PEND(fl,p) NVIC_INT_CTRL = (fl | p) << 28 -#if (__TARGET_ARCH_6S_M) -#define OS_X_INIT(n) NVIC_IP[n>>2] |= 0xFF << (8*(n & 0x03)); \ - NVIC_ISER[n>>5] = 1 << (n & 0x1F) -#else -#define OS_X_INIT(n) NVIC_IP[n] = 0xFF; \ - NVIC_ISER[n>>5] = 1 << (n & 0x1F) -#endif -#define OS_X_LOCK(n) NVIC_ICER[n>>5] = 1 << (n & 0x1F) -#define OS_X_UNLOCK(n) NVIC_ISER[n>>5] = 1 << (n & 0x1F) - -/* Core Debug registers */ -#define DEMCR (*((volatile U32 *)0xE000EDFC)) - -/* ITM registers */ -#define ITM_CONTROL (*((volatile U32 *)0xE0000E80)) -#define ITM_ENABLE (*((volatile U32 *)0xE0000E00)) -#define ITM_PORT30_U32 (*((volatile U32 *)0xE0000078)) -#define ITM_PORT31_U32 (*((volatile U32 *)0xE000007C)) -#define ITM_PORT31_U16 (*((volatile U16 *)0xE000007C)) -#define ITM_PORT31_U8 (*((volatile U8 *)0xE000007C)) - -/* Variables */ -extern BIT dbg_msg; - -/* Functions */ -#ifdef __USE_EXCLUSIVE_ACCESS - #define rt_inc(p) while(__strex((__ldrex(p)+1),p)) - #define rt_dec(p) while(__strex((__ldrex(p)-1),p)) -#else - #define rt_inc(p) __disable_irq();(*p)++;__enable_irq(); - #define rt_dec(p) __disable_irq();(*p)--;__enable_irq(); -#endif - -__inline static U32 rt_inc_qi (U32 size, U8 *count, U8 *first) { - U32 cnt,c2; -#ifdef __USE_EXCLUSIVE_ACCESS - do { - if ((cnt = __ldrex(count)) == size) { - __clrex(); - return (cnt); } - } while (__strex(cnt+1, count)); - do { - c2 = (cnt = __ldrex(first)) + 1; - if (c2 == size) c2 = 0; - } while (__strex(c2, first)); -#else - __disable_irq(); - if ((cnt = *count) < size) { - *count = cnt+1; - c2 = (cnt = *first) + 1; - if (c2 == size) c2 = 0; - *first = c2; - } - __enable_irq (); -#endif - return (cnt); -} - -__inline static void rt_systick_init (void) { - NVIC_ST_RELOAD = os_trv; - NVIC_ST_CURRENT = 0; - NVIC_ST_CTRL = 0x0007; - NVIC_SYS_PRI3 |= 0xFF000000; -} - -__inline static void rt_svc_init (void) { -#if !(__TARGET_ARCH_6S_M) - int sh,prigroup; -#endif - NVIC_SYS_PRI3 |= 0x00FF0000; -#if (__TARGET_ARCH_6S_M) - NVIC_SYS_PRI2 |= (NVIC_SYS_PRI3<<(8+1)) & 0xFC000000; -#else - sh = 8 - __clz (~((NVIC_SYS_PRI3 << 8) & 0xFF000000)); - prigroup = ((NVIC_AIR_CTRL >> 8) & 0x07); - if (prigroup >= sh) { - sh = prigroup + 1; - } - NVIC_SYS_PRI2 = ((0xFEFFFFFF << sh) & 0xFF000000) | (NVIC_SYS_PRI2 & 0x00FFFFFF); -#endif -} - -extern void rt_set_PSP (U32 stack); -extern U32 rt_get_PSP (void); -extern void os_set_env (void); -extern void *_alloc_box (void *box_mem); -extern int _free_box (void *box_mem, void *box); - -extern void rt_init_stack (P_TCB p_TCB, FUNCP task_body); -extern void rt_ret_val (P_TCB p_TCB, U32 v0); -extern void rt_ret_val2 (P_TCB p_TCB, U32 v0, U32 v1); - -extern void dbg_init (void); -extern void dbg_task_notify (P_TCB p_tcb, BOOL create); -extern void dbg_task_switch (U32 task_id); - -#ifdef DBG_MSG -#define DBG_INIT() dbg_init() -#define DBG_TASK_NOTIFY(p_tcb,create) if (dbg_msg) dbg_task_notify(p_tcb,create) -#define DBG_TASK_SWITCH(task_id) if (dbg_msg && (os_tsk.new!=os_tsk.run)) \ - dbg_task_switch(task_id) -#else -#define DBG_INIT() -#define DBG_TASK_NOTIFY(p_tcb,create) -#define DBG_TASK_SWITCH(task_id) -#endif - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx_ca/rt_List.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,324 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_LIST.C - * Purpose: Functions for the management of different lists - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_System.h" -#include "rt_List.h" -#include "rt_Task.h" -#include "rt_Time.h" -#ifdef __CORTEX_A9 -#include "rt_HAL_CA.h" -#else -#include "rt_HAL_CM.h" -#endif - -/*---------------------------------------------------------------------------- - * Global Variables - *---------------------------------------------------------------------------*/ - -/* List head of chained ready tasks */ -struct OS_XCB os_rdy; -/* List head of chained delay tasks */ -struct OS_XCB os_dly; - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_put_prio -----------------------------------*/ - -void rt_put_prio (P_XCB p_CB, P_TCB p_task) { - /* Put task identified with "p_task" into list ordered by priority. */ - /* "p_CB" points to head of list; list has always an element at end with */ - /* a priority less than "p_task->prio". */ - P_TCB p_CB2; - U32 prio; - BOOL sem_mbx = __FALSE; - - if (p_CB->cb_type == SCB || p_CB->cb_type == MCB || p_CB->cb_type == MUCB) { - sem_mbx = __TRUE; - } - prio = p_task->prio; - p_CB2 = p_CB->p_lnk; - /* Search for an entry in the list */ - while (p_CB2 != NULL && prio <= p_CB2->prio) { - p_CB = (P_XCB)p_CB2; - p_CB2 = p_CB2->p_lnk; - } - /* Entry found, insert the task into the list */ - p_task->p_lnk = p_CB2; - p_CB->p_lnk = p_task; - if (sem_mbx) { - if (p_CB2 != NULL) { - p_CB2->p_rlnk = p_task; - } - p_task->p_rlnk = (P_TCB)p_CB; - } - else { - p_task->p_rlnk = NULL; - } -} - - -/*--------------------------- rt_get_first ----------------------------------*/ - -P_TCB rt_get_first (P_XCB p_CB) { - /* Get task at head of list: it is the task with highest priority. */ - /* "p_CB" points to head of list. */ - P_TCB p_first; - - p_first = p_CB->p_lnk; - p_CB->p_lnk = p_first->p_lnk; - if (p_CB->cb_type == SCB || p_CB->cb_type == MCB || p_CB->cb_type == MUCB) { - if (p_first->p_lnk != NULL) { - p_first->p_lnk->p_rlnk = (P_TCB)p_CB; - p_first->p_lnk = NULL; - } - p_first->p_rlnk = NULL; - } - else { - p_first->p_lnk = NULL; - } - return (p_first); -} - - -/*--------------------------- rt_put_rdy_first ------------------------------*/ - -void rt_put_rdy_first (P_TCB p_task) { - /* Put task identified with "p_task" at the head of the ready list. The */ - /* task must have at least a priority equal to highest priority in list. */ - p_task->p_lnk = os_rdy.p_lnk; - p_task->p_rlnk = NULL; - os_rdy.p_lnk = p_task; -} - - -/*--------------------------- rt_get_same_rdy_prio --------------------------*/ - -P_TCB rt_get_same_rdy_prio (void) { - /* Remove a task of same priority from ready list if any exists. Other- */ - /* wise return NULL. */ - P_TCB p_first; - - p_first = os_rdy.p_lnk; - if (p_first->prio == os_tsk.run->prio) { - os_rdy.p_lnk = os_rdy.p_lnk->p_lnk; - return (p_first); - } - return (NULL); -} - - -/*--------------------------- rt_resort_prio --------------------------------*/ - -void rt_resort_prio (P_TCB p_task) { - /* Re-sort ordered lists after the priority of 'p_task' has changed. */ - P_TCB p_CB; - - if (p_task->p_rlnk == NULL) { - if (p_task->state == READY) { - /* Task is chained into READY list. */ - p_CB = (P_TCB)&os_rdy; - goto res; - } - } - else { - p_CB = p_task->p_rlnk; - while (p_CB->cb_type == TCB) { - /* Find a header of this task chain list. */ - p_CB = p_CB->p_rlnk; - } -res:rt_rmv_list (p_task); - rt_put_prio ((P_XCB)p_CB, p_task); - } -} - - -/*--------------------------- rt_put_dly ------------------------------------*/ - -void rt_put_dly (P_TCB p_task, U16 delay) { - /* Put a task identified with "p_task" into chained delay wait list using */ - /* a delay value of "delay". */ - P_TCB p; - U32 delta,idelay = delay; - - p = (P_TCB)&os_dly; - if (p->p_dlnk == NULL) { - /* Delay list empty */ - delta = 0; - goto last; - } - delta = os_dly.delta_time; - while (delta < idelay) { - if (p->p_dlnk == NULL) { - /* End of list found */ -last: p_task->p_dlnk = NULL; - p->p_dlnk = p_task; - p_task->p_blnk = p; - p->delta_time = (U16)(idelay - delta); - p_task->delta_time = 0; - return; - } - p = p->p_dlnk; - delta += p->delta_time; - } - /* Right place found */ - p_task->p_dlnk = p->p_dlnk; - p->p_dlnk = p_task; - p_task->p_blnk = p; - if (p_task->p_dlnk != NULL) { - p_task->p_dlnk->p_blnk = p_task; - } - p_task->delta_time = (U16)(delta - idelay); - p->delta_time -= p_task->delta_time; -} - - -/*--------------------------- rt_dec_dly ------------------------------------*/ - -void rt_dec_dly (void) { - /* Decrement delta time of list head: remove tasks having a value of zero.*/ - P_TCB p_rdy; - - if (os_dly.p_dlnk == NULL) { - return; - } - os_dly.delta_time--; - while ((os_dly.delta_time == 0) && (os_dly.p_dlnk != NULL)) { - p_rdy = os_dly.p_dlnk; - if (p_rdy->p_rlnk != NULL) { - /* Task is really enqueued, remove task from semaphore/mailbox */ - /* timeout waiting list. */ - p_rdy->p_rlnk->p_lnk = p_rdy->p_lnk; - if (p_rdy->p_lnk != NULL) { - p_rdy->p_lnk->p_rlnk = p_rdy->p_rlnk; - p_rdy->p_lnk = NULL; - } - p_rdy->p_rlnk = NULL; - } - rt_put_prio (&os_rdy, p_rdy); - os_dly.delta_time = p_rdy->delta_time; - if (p_rdy->state == WAIT_ITV) { - /* Calculate the next time for interval wait. */ - p_rdy->delta_time = p_rdy->interval_time + (U16)os_time; - } - p_rdy->state = READY; - os_dly.p_dlnk = p_rdy->p_dlnk; - if (p_rdy->p_dlnk != NULL) { - p_rdy->p_dlnk->p_blnk = (P_TCB)&os_dly; - p_rdy->p_dlnk = NULL; - } - p_rdy->p_blnk = NULL; - } -} - - -/*--------------------------- rt_rmv_list -----------------------------------*/ - -void rt_rmv_list (P_TCB p_task) { - /* Remove task identified with "p_task" from ready, semaphore or mailbox */ - /* waiting list if enqueued. */ - P_TCB p_b; - - if (p_task->p_rlnk != NULL) { - /* A task is enqueued in semaphore / mailbox waiting list. */ - p_task->p_rlnk->p_lnk = p_task->p_lnk; - if (p_task->p_lnk != NULL) { - p_task->p_lnk->p_rlnk = p_task->p_rlnk; - } - return; - } - - p_b = (P_TCB)&os_rdy; - while (p_b != NULL) { - /* Search the ready list for task "p_task" */ - if (p_b->p_lnk == p_task) { - p_b->p_lnk = p_task->p_lnk; - return; - } - p_b = p_b->p_lnk; - } -} - - -/*--------------------------- rt_rmv_dly ------------------------------------*/ - -void rt_rmv_dly (P_TCB p_task) { - /* Remove task identified with "p_task" from delay list if enqueued. */ - P_TCB p_b; - - p_b = p_task->p_blnk; - if (p_b != NULL) { - /* Task is really enqueued */ - p_b->p_dlnk = p_task->p_dlnk; - if (p_task->p_dlnk != NULL) { - /* 'p_task' is in the middle of list */ - p_b->delta_time += p_task->delta_time; - p_task->p_dlnk->p_blnk = p_b; - p_task->p_dlnk = NULL; - } - else { - /* 'p_task' is at the end of list */ - p_b->delta_time = 0; - } - p_task->p_blnk = NULL; - } -} - - -/*--------------------------- rt_psq_enq ------------------------------------*/ - -void rt_psq_enq (OS_ID entry, U32 arg) { - /* Insert post service request "entry" into ps-queue. */ - U32 idx; - - idx = rt_inc_qi (os_psq->size, &os_psq->count, &os_psq->first); - if (idx < os_psq->size) { - os_psq->q[idx].id = entry; - os_psq->q[idx].arg = arg; - } - else { - os_error (OS_ERR_FIFO_OVF); - } -} - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx_ca/rt_List.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_LIST.H - * Purpose: Functions for the management of different lists - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Definitions */ - -/* Values for 'cb_type' */ -#define TCB 0 -#define MCB 1 -#define SCB 2 -#define MUCB 3 -#define HCB 4 - -/* Variables */ -extern struct OS_XCB os_rdy; -extern struct OS_XCB os_dly; - -/* Functions */ -extern void rt_put_prio (P_XCB p_CB, P_TCB p_task); -extern P_TCB rt_get_first (P_XCB p_CB); -extern void rt_put_rdy_first (P_TCB p_task); -extern P_TCB rt_get_same_rdy_prio (void); -extern void rt_resort_prio (P_TCB p_task); -extern void rt_put_dly (P_TCB p_task, U16 delay); -extern void rt_dec_dly (void); -extern void rt_rmv_list (P_TCB p_task); -extern void rt_rmv_dly (P_TCB p_task); -extern void rt_psq_enq (OS_ID entry, U32 arg); - -/* This is a fast macro generating in-line code */ -#define rt_rdy_prio(void) (os_rdy.p_lnk->prio) - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx_ca/rt_Mailbox.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,296 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_MAILBOX.C - * Purpose: Implements waits and wake-ups for mailbox messages - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_System.h" -#include "rt_List.h" -#include "rt_Mailbox.h" -#include "rt_MemBox.h" -#include "rt_Task.h" -#ifdef __CORTEX_A9 -#include "rt_HAL_CA.h" -#else -#include "rt_HAL_CM.h" -#endif - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_mbx_init -----------------------------------*/ - -void rt_mbx_init (OS_ID mailbox, U16 mbx_size) { - /* Initialize a mailbox */ - P_MCB p_MCB = mailbox; - - p_MCB->cb_type = MCB; - p_MCB->state = 0; - p_MCB->isr_st = 0; - p_MCB->p_lnk = NULL; - p_MCB->first = 0; - p_MCB->last = 0; - p_MCB->count = 0; - p_MCB->size = (mbx_size + sizeof(void *) - sizeof(struct OS_MCB)) / - (U32)sizeof (void *); -} - - -/*--------------------------- rt_mbx_send -----------------------------------*/ - -OS_RESULT rt_mbx_send (OS_ID mailbox, void *p_msg, U16 timeout) { - /* Send message to a mailbox */ - P_MCB p_MCB = mailbox; - P_TCB p_TCB; - - if ((p_MCB->p_lnk != NULL) && (p_MCB->state == 1)) { - /* A task is waiting for message */ - p_TCB = rt_get_first ((P_XCB)p_MCB); -#ifdef __CMSIS_RTOS - rt_ret_val2(p_TCB, 0x10/*osEventMessage*/, (U32)p_msg); -#else - *p_TCB->msg = p_msg; - rt_ret_val (p_TCB, OS_R_MBX); -#endif - rt_rmv_dly (p_TCB); - rt_dispatch (p_TCB); - } - else { - /* Store message in mailbox queue */ - if (p_MCB->count == p_MCB->size) { - /* No free message entry, wait for one. If message queue is full, */ - /* then no task is waiting for message. The 'p_MCB->p_lnk' list */ - /* pointer can now be reused for send message waits task list. */ - if (timeout == 0) { - return (OS_R_TMO); - } - if (p_MCB->p_lnk != NULL) { - rt_put_prio ((P_XCB)p_MCB, os_tsk.run); - } - else { - p_MCB->p_lnk = os_tsk.run; - os_tsk.run->p_lnk = NULL; - os_tsk.run->p_rlnk = (P_TCB)p_MCB; - /* Task is waiting to send a message */ - p_MCB->state = 2; - } - os_tsk.run->msg = p_msg; - rt_block (timeout, WAIT_MBX); - return (OS_R_TMO); - } - /* Yes, there is a free entry in a mailbox. */ - p_MCB->msg[p_MCB->first] = p_msg; - rt_inc (&p_MCB->count); - if (++p_MCB->first == p_MCB->size) { - p_MCB->first = 0; - } - } - return (OS_R_OK); -} - - -/*--------------------------- rt_mbx_wait -----------------------------------*/ - -OS_RESULT rt_mbx_wait (OS_ID mailbox, void **message, U16 timeout) { - /* Receive a message; possibly wait for it */ - P_MCB p_MCB = mailbox; - P_TCB p_TCB; - - /* If a message is available in the fifo buffer */ - /* remove it from the fifo buffer and return. */ - if (p_MCB->count) { - *message = p_MCB->msg[p_MCB->last]; - if (++p_MCB->last == p_MCB->size) { - p_MCB->last = 0; - } - if ((p_MCB->p_lnk != NULL) && (p_MCB->state == 2)) { - /* A task is waiting to send message */ - p_TCB = rt_get_first ((P_XCB)p_MCB); -#ifdef __CMSIS_RTOS - rt_ret_val(p_TCB, 0/*osOK*/); -#else - rt_ret_val(p_TCB, OS_R_OK); -#endif - p_MCB->msg[p_MCB->first] = p_TCB->msg; - if (++p_MCB->first == p_MCB->size) { - p_MCB->first = 0; - } - rt_rmv_dly (p_TCB); - rt_dispatch (p_TCB); - } - else { - rt_dec (&p_MCB->count); - } - return (OS_R_OK); - } - /* No message available: wait for one */ - if (timeout == 0) { - return (OS_R_TMO); - } - if (p_MCB->p_lnk != NULL) { - rt_put_prio ((P_XCB)p_MCB, os_tsk.run); - } - else { - p_MCB->p_lnk = os_tsk.run; - os_tsk.run->p_lnk = NULL; - os_tsk.run->p_rlnk = (P_TCB)p_MCB; - /* Task is waiting to receive a message */ - p_MCB->state = 1; - } - rt_block(timeout, WAIT_MBX); -#ifndef __CMSIS_RTOS - os_tsk.run->msg = message; -#endif - return (OS_R_TMO); -} - - -/*--------------------------- rt_mbx_check ----------------------------------*/ - -OS_RESULT rt_mbx_check (OS_ID mailbox) { - /* Check for free space in a mailbox. Returns the number of messages */ - /* that can be stored to a mailbox. It returns 0 when mailbox is full. */ - P_MCB p_MCB = mailbox; - - return (p_MCB->size - p_MCB->count); -} - - -/*--------------------------- isr_mbx_send ----------------------------------*/ - -void isr_mbx_send (OS_ID mailbox, void *p_msg) { - /* Same function as "os_mbx_send", but to be called by ISRs. */ - P_MCB p_MCB = mailbox; - - rt_psq_enq (p_MCB, (U32)p_msg); - rt_psh_req (); -} - - -/*--------------------------- isr_mbx_receive -------------------------------*/ - -OS_RESULT isr_mbx_receive (OS_ID mailbox, void **message) { - /* Receive a message in the interrupt function. The interrupt function */ - /* should not wait for a message since this would block the rtx os. */ - P_MCB p_MCB = mailbox; - - if (p_MCB->count) { - /* A message is available in the fifo buffer. */ - *message = p_MCB->msg[p_MCB->last]; - if (p_MCB->state == 2) { - /* A task is locked waiting to send message */ - rt_psq_enq (p_MCB, 0); - rt_psh_req (); - } - rt_dec (&p_MCB->count); - if (++p_MCB->last == p_MCB->size) { - p_MCB->last = 0; - } - return (OS_R_MBX); - } - return (OS_R_OK); -} - - -/*--------------------------- rt_mbx_psh ------------------------------------*/ - -void rt_mbx_psh (P_MCB p_CB, void *p_msg) { - /* Store the message to the mailbox queue or pass it to task directly. */ - P_TCB p_TCB; - void *mem; - - if (p_CB->p_lnk != NULL) switch (p_CB->state) { -#ifdef __CMSIS_RTOS - case 3: - /* Task is waiting to allocate memory, remove it from the waiting list */ - mem = rt_alloc_box(p_msg); - if (mem == NULL) break; - p_TCB = rt_get_first ((P_XCB)p_CB); - rt_ret_val(p_TCB, (U32)mem); - p_TCB->state = READY; - rt_rmv_dly (p_TCB); - rt_put_prio (&os_rdy, p_TCB); - break; -#endif - case 2: - /* Task is waiting to send a message, remove it from the waiting list */ - p_TCB = rt_get_first ((P_XCB)p_CB); -#ifdef __CMSIS_RTOS - rt_ret_val(p_TCB, 0/*osOK*/); -#else - rt_ret_val(p_TCB, OS_R_OK); -#endif - p_CB->msg[p_CB->first] = p_TCB->msg; - rt_inc (&p_CB->count); - if (++p_CB->first == p_CB->size) { - p_CB->first = 0; - } - p_TCB->state = READY; - rt_rmv_dly (p_TCB); - rt_put_prio (&os_rdy, p_TCB); - break; - case 1: - /* Task is waiting for a message, pass the message to the task directly */ - p_TCB = rt_get_first ((P_XCB)p_CB); -#ifdef __CMSIS_RTOS - rt_ret_val2(p_TCB, 0x10/*osEventMessage*/, (U32)p_msg); -#else - *p_TCB->msg = p_msg; - rt_ret_val (p_TCB, OS_R_MBX); -#endif - p_TCB->state = READY; - rt_rmv_dly (p_TCB); - rt_put_prio (&os_rdy, p_TCB); - break; - } else { - /* No task is waiting for a message, store it to the mailbox queue */ - if (p_CB->count < p_CB->size) { - p_CB->msg[p_CB->first] = p_msg; - rt_inc (&p_CB->count); - if (++p_CB->first == p_CB->size) { - p_CB->first = 0; - } - } - else { - os_error (OS_ERR_MBX_OVF); - } - } -} - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx_ca/rt_Mailbox.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_MAILBOX.H - * Purpose: Implements waits and wake-ups for mailbox messages - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Functions */ -extern void rt_mbx_init (OS_ID mailbox, U16 mbx_size); -extern OS_RESULT rt_mbx_send (OS_ID mailbox, void *p_msg, U16 timeout); -extern OS_RESULT rt_mbx_wait (OS_ID mailbox, void **message, U16 timeout); -extern OS_RESULT rt_mbx_check (OS_ID mailbox); -extern void isr_mbx_send (OS_ID mailbox, void *p_msg); -extern OS_RESULT isr_mbx_receive (OS_ID mailbox, void **message); -extern void rt_mbx_psh (P_MCB p_CB, void *p_msg); - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx_ca/rt_MemBox.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,170 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_MEMBOX.C - * Purpose: Interface functions for fixed memory block management system - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_System.h" -#include "rt_MemBox.h" -#ifdef __CORTEX_A9 -#include "rt_HAL_CA.h" -#else -#include "rt_HAL_CM.h" -#endif - -/*---------------------------------------------------------------------------- - * Global Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- _init_box -------------------------------------*/ - -int _init_box (void *box_mem, U32 box_size, U32 blk_size) { - /* Initialize memory block system, returns 0 if OK, 1 if fails. */ - void *end; - void *blk; - void *next; - U32 sizeof_bm; - - /* Create memory structure. */ - if (blk_size & BOX_ALIGN_8) { - /* Memory blocks 8-byte aligned. */ - blk_size = ((blk_size & ~BOX_ALIGN_8) + 7) & ~7; - sizeof_bm = (sizeof (struct OS_BM) + 7) & ~7; - } - else { - /* Memory blocks 4-byte aligned. */ - blk_size = (blk_size + 3) & ~3; - sizeof_bm = sizeof (struct OS_BM); - } - if (blk_size == 0) { - return (1); - } - if ((blk_size + sizeof_bm) > box_size) { - return (1); - } - /* Create a Memory structure. */ - blk = ((U8 *) box_mem) + sizeof_bm; - ((P_BM) box_mem)->free = blk; - end = ((U8 *) box_mem) + box_size; - ((P_BM) box_mem)->end = end; - ((P_BM) box_mem)->blk_size = blk_size; - - /* Link all free blocks using offsets. */ - end = ((U8 *) end) - blk_size; - while (1) { - next = ((U8 *) blk) + blk_size; - if (next > end) break; - *((void **)blk) = next; - blk = next; - } - /* end marker */ - *((void **)blk) = 0; - return (0); -} - -/*--------------------------- rt_alloc_box ----------------------------------*/ - -void *rt_alloc_box (void *box_mem) { - /* Allocate a memory block and return start address. */ - void **free; -#ifndef __USE_EXCLUSIVE_ACCESS - int irq_dis; - - irq_dis = __disable_irq (); - free = ((P_BM) box_mem)->free; - if (free) { - ((P_BM) box_mem)->free = *free; - } - if (!irq_dis) __enable_irq (); -#else - do { - if ((free = (void **)__ldrex(&((P_BM) box_mem)->free)) == 0) { - __clrex(); - break; - } - } while (__strex((U32)*free, &((P_BM) box_mem)->free)); -#endif - return (free); -} - - -/*--------------------------- _calloc_box -----------------------------------*/ - -void *_calloc_box (void *box_mem) { - /* Allocate a 0-initialized memory block and return start address. */ - void *free; - U32 *p; - U32 i; - - free = _alloc_box (box_mem); - if (free) { - p = free; - for (i = ((P_BM) box_mem)->blk_size; i; i -= 4) { - *p = 0; - p++; - } - } - return (free); -} - - -/*--------------------------- rt_free_box -----------------------------------*/ - -int rt_free_box (void *box_mem, void *box) { - /* Free a memory block, returns 0 if OK, 1 if box does not belong to box_mem */ -#ifndef __USE_EXCLUSIVE_ACCESS - int irq_dis; -#endif - - if (box < box_mem || box >= ((P_BM) box_mem)->end) { - return (1); - } - -#ifndef __USE_EXCLUSIVE_ACCESS - irq_dis = __disable_irq (); - *((void **)box) = ((P_BM) box_mem)->free; - ((P_BM) box_mem)->free = box; - if (!irq_dis) __enable_irq (); -#else - do { - *((void **)box) = (void *)__ldrex(&((P_BM) box_mem)->free); - } while (__strex ((U32)box, &((P_BM) box_mem)->free)); -#endif - return (0); -} - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx_ca/rt_MemBox.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_MEMBOX.H - * Purpose: Interface functions for fixed memory block management system - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Functions */ -#define rt_init_box _init_box -#define rt_calloc_box _calloc_box -extern int _init_box (void *box_mem, U32 box_size, U32 blk_size); -extern void *rt_alloc_box (void *box_mem); -extern void * _calloc_box (void *box_mem); -extern int rt_free_box (void *box_mem, void *box); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx_ca/rt_Memory.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,140 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_MEMORY.C - * Purpose: Interface functions for Dynamic Memory Management System - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "rt_Memory.h" - - -/* Functions */ - -// Initialize Dynamic Memory pool -// Parameters: -// pool: Pointer to memory pool -// size: Size of memory pool in bytes -// Return: 0 - OK, 1 - Error - -int rt_init_mem (void *pool, U32 size) { - MEMP *ptr; - - if ((pool == NULL) || (size < sizeof(MEMP))) return (1); - - ptr = (MEMP *)pool; - ptr->next = (MEMP *)((U32)pool + size - sizeof(MEMP *)); - ptr->next->next = NULL; - ptr->len = 0; - - return (0); -} - -// Allocate Memory from Memory pool -// Parameters: -// pool: Pointer to memory pool -// size: Size of memory in bytes to allocate -// Return: Pointer to allocated memory - -void *rt_alloc_mem (void *pool, U32 size) { - MEMP *p, *p_search, *p_new; - U32 hole_size; - - if ((pool == NULL) || (size == 0)) return NULL; - - /* Add header offset to 'size' */ - size += sizeof(MEMP); - /* Make sure that block is 4-byte aligned */ - size = (size + 3) & ~3; - - p_search = (MEMP *)pool; - while (1) { - hole_size = (U32)p_search->next - (U32)p_search; - hole_size -= p_search->len; - /* Check if hole size is big enough */ - if (hole_size >= size) break; - p_search = p_search->next; - if (p_search->next == NULL) { - /* Failed, we are at the end of the list */ - return NULL; - } - } - - if (p_search->len == 0) { - /* No block is allocated, set the Length of the first element */ - p_search->len = size; - p = (MEMP *)(((U32)p_search) + sizeof(MEMP)); - } else { - /* Insert new list element into the memory list */ - p_new = (MEMP *)((U32)p_search + p_search->len); - p_new->next = p_search->next; - p_new->len = size; - p_search->next = p_new; - p = (MEMP *)(((U32)p_new) + sizeof(MEMP)); - } - - return (p); -} - -// Free Memory and return it to Memory pool -// Parameters: -// pool: Pointer to memory pool -// mem: Pointer to memory to free -// Return: 0 - OK, 1 - Error - -int rt_free_mem (void *pool, void *mem) { - MEMP *p_search, *p_prev, *p_return; - - if ((pool == NULL) || (mem == NULL)) return (1); - - p_return = (MEMP *)((U32)mem - sizeof(MEMP)); - - /* Set list header */ - p_prev = NULL; - p_search = (MEMP *)pool; - while (p_search != p_return) { - p_prev = p_search; - p_search = p_search->next; - if (p_search == NULL) { - /* Valid Memory block not found */ - return (1); - } - } - - if (p_prev == NULL) { - /* First block to be released, only set length to 0 */ - p_search->len = 0; - } else { - /* Discard block from chain list */ - p_prev->next = p_search->next; - } - - return (0); -}
--- a/rtx_ca/rt_Memory.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_MEMORY.H - * Purpose: Interface functions for Dynamic Memory Management System - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Types */ -typedef struct mem { /* << Memory Pool management struct >> */ - struct mem *next; /* Next Memory Block in the list */ - U32 len; /* Length of data block */ -} MEMP; - -/* Functions */ -extern int rt_init_mem (void *pool, U32 size); -extern void *rt_alloc_mem (void *pool, U32 size); -extern int rt_free_mem (void *pool, void *mem);
--- a/rtx_ca/rt_Mutex.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,204 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_MUTEX.C - * Purpose: Implements mutex synchronization objects - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_List.h" -#include "rt_Task.h" -#include "rt_Mutex.h" -#ifdef __CORTEX_A9 -#include "rt_HAL_CA.h" -#else -#include "rt_HAL_CM.h" -#endif - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_mut_init -----------------------------------*/ - -void rt_mut_init (OS_ID mutex) { - /* Initialize a mutex object */ - P_MUCB p_MCB = mutex; - - p_MCB->cb_type = MUCB; - p_MCB->prio = 0; - p_MCB->level = 0; - p_MCB->p_lnk = NULL; - p_MCB->owner = NULL; -} - - -/*--------------------------- rt_mut_delete ---------------------------------*/ - -#ifdef __CMSIS_RTOS -OS_RESULT rt_mut_delete (OS_ID mutex) { - /* Delete a mutex object */ - P_MUCB p_MCB = mutex; - P_TCB p_TCB; - - __DMB(); - /* Restore owner task's priority. */ - if (p_MCB->level != 0) { - p_MCB->owner->prio = p_MCB->prio; - if (p_MCB->owner != os_tsk.run) { - rt_resort_prio (p_MCB->owner); - } - } - - while (p_MCB->p_lnk != NULL) { - /* A task is waiting for mutex. */ - p_TCB = rt_get_first ((P_XCB)p_MCB); - rt_ret_val(p_TCB, 0/*osOK*/); - rt_rmv_dly(p_TCB); - p_TCB->state = READY; - rt_put_prio (&os_rdy, p_TCB); - } - - if (os_rdy.p_lnk && (os_rdy.p_lnk->prio > os_tsk.run->prio)) { - /* preempt running task */ - rt_put_prio (&os_rdy, os_tsk.run); - os_tsk.run->state = READY; - rt_dispatch (NULL); - } - - p_MCB->cb_type = 0; - - return (OS_R_OK); -} -#endif - - -/*--------------------------- rt_mut_release --------------------------------*/ - -OS_RESULT rt_mut_release (OS_ID mutex) { - /* Release a mutex object */ - P_MUCB p_MCB = mutex; - P_TCB p_TCB; - - if (p_MCB->level == 0 || p_MCB->owner != os_tsk.run) { - /* Unbalanced mutex release or task is not the owner */ - return (OS_R_NOK); - } - __DMB(); - if (--p_MCB->level != 0) { - return (OS_R_OK); - } - /* Restore owner task's priority. */ - os_tsk.run->prio = p_MCB->prio; - if (p_MCB->p_lnk != NULL) { - /* A task is waiting for mutex. */ - p_TCB = rt_get_first ((P_XCB)p_MCB); -#ifdef __CMSIS_RTOS - rt_ret_val(p_TCB, 0/*osOK*/); -#else - rt_ret_val(p_TCB, OS_R_MUT); -#endif - rt_rmv_dly (p_TCB); - /* A waiting task becomes the owner of this mutex. */ - p_MCB->level = 1; - p_MCB->owner = p_TCB; - p_MCB->prio = p_TCB->prio; - /* Priority inversion, check which task continues. */ - if (os_tsk.run->prio >= rt_rdy_prio()) { - rt_dispatch (p_TCB); - } - else { - /* Ready task has higher priority than running task. */ - rt_put_prio (&os_rdy, os_tsk.run); - rt_put_prio (&os_rdy, p_TCB); - os_tsk.run->state = READY; - p_TCB->state = READY; - rt_dispatch (NULL); - } - } - else { - /* Check if own priority raised by priority inversion. */ - if (rt_rdy_prio() > os_tsk.run->prio) { - rt_put_prio (&os_rdy, os_tsk.run); - os_tsk.run->state = READY; - rt_dispatch (NULL); - } - } - return (OS_R_OK); -} - - -/*--------------------------- rt_mut_wait -----------------------------------*/ - -OS_RESULT rt_mut_wait (OS_ID mutex, U16 timeout) { - /* Wait for a mutex, continue when mutex is free. */ - P_MUCB p_MCB = mutex; - - if (p_MCB->level == 0) { - p_MCB->owner = os_tsk.run; - p_MCB->prio = os_tsk.run->prio; - goto inc; - } - if (p_MCB->owner == os_tsk.run) { - /* OK, running task is the owner of this mutex. */ -inc:p_MCB->level++; - __DMB(); - return (OS_R_OK); - } - /* Mutex owned by another task, wait until released. */ - if (timeout == 0) { - return (OS_R_TMO); - } - /* Raise the owner task priority if lower than current priority. */ - /* This priority inversion is called priority inheritance. */ - if (p_MCB->prio < os_tsk.run->prio) { - p_MCB->owner->prio = os_tsk.run->prio; - rt_resort_prio (p_MCB->owner); - } - if (p_MCB->p_lnk != NULL) { - rt_put_prio ((P_XCB)p_MCB, os_tsk.run); - } - else { - p_MCB->p_lnk = os_tsk.run; - os_tsk.run->p_lnk = NULL; - os_tsk.run->p_rlnk = (P_TCB)p_MCB; - } - rt_block(timeout, WAIT_MUT); - return (OS_R_TMO); -} - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx_ca/rt_Mutex.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_MUTEX.H - * Purpose: Implements mutex synchronization objects - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Functions */ -extern void rt_mut_init (OS_ID mutex); -extern OS_RESULT rt_mut_delete (OS_ID mutex); -extern OS_RESULT rt_mut_release (OS_ID mutex); -extern OS_RESULT rt_mut_wait (OS_ID mutex, U16 timeout); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx_ca/rt_Robin.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,88 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_ROBIN.C - * Purpose: Round Robin Task switching - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_List.h" -#include "rt_Task.h" -#include "rt_Time.h" -#include "rt_Robin.h" -#ifdef __CORTEX_A9 -#include "rt_HAL_CA.h" -#else -#include "rt_HAL_CM.h" -#endif - -/*---------------------------------------------------------------------------- - * Global Variables - *---------------------------------------------------------------------------*/ - -struct OS_ROBIN os_robin; - - -/*---------------------------------------------------------------------------- - * Global Functions - *---------------------------------------------------------------------------*/ - -/*--------------------------- rt_init_robin ---------------------------------*/ - -__weak void rt_init_robin (void) { - /* Initialize Round Robin variables. */ - os_robin.task = NULL; - os_robin.tout = (U16)os_rrobin; -} - -/*--------------------------- rt_chk_robin ----------------------------------*/ - -__weak void rt_chk_robin (void) { - /* Check if Round Robin timeout expired and switch to the next ready task.*/ - P_TCB p_new; - - if (os_robin.task != os_rdy.p_lnk) { - /* New task was suspended, reset Round Robin timeout. */ - os_robin.task = os_rdy.p_lnk; - os_robin.time = (U16)os_time + os_robin.tout - 1; - } - if (os_robin.time == (U16)os_time) { - /* Round Robin timeout has expired, swap Robin tasks. */ - os_robin.task = NULL; - p_new = rt_get_first (&os_rdy); - rt_put_prio ((P_XCB)&os_rdy, p_new); - } -} - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx_ca/rt_Robin.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_ROBIN.H - * Purpose: Round Robin Task switching definitions - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Variables */ -extern struct OS_ROBIN os_robin; - -/* Functions */ -extern void rt_init_robin (void); -extern void rt_chk_robin (void); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx_ca/rt_Semaphore.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,191 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_SEMAPHORE.C - * Purpose: Implements binary and counting semaphores - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_System.h" -#include "rt_List.h" -#include "rt_Task.h" -#include "rt_Semaphore.h" -#ifdef __CORTEX_A9 -#include "rt_HAL_CA.h" -#else -#include "rt_HAL_CM.h" -#endif - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_sem_init -----------------------------------*/ - -void rt_sem_init (OS_ID semaphore, U16 token_count) { - /* Initialize a semaphore */ - P_SCB p_SCB = semaphore; - - p_SCB->cb_type = SCB; - p_SCB->p_lnk = NULL; - p_SCB->tokens = token_count; -} - - -/*--------------------------- rt_sem_delete ---------------------------------*/ - -#ifdef __CMSIS_RTOS -OS_RESULT rt_sem_delete (OS_ID semaphore) { - /* Delete semaphore */ - P_SCB p_SCB = semaphore; - P_TCB p_TCB; - - __DMB(); - while (p_SCB->p_lnk != NULL) { - /* A task is waiting for token */ - p_TCB = rt_get_first ((P_XCB)p_SCB); - rt_ret_val(p_TCB, 0); - rt_rmv_dly(p_TCB); - p_TCB->state = READY; - rt_put_prio (&os_rdy, p_TCB); - } - - if (os_rdy.p_lnk && (os_rdy.p_lnk->prio > os_tsk.run->prio)) { - /* preempt running task */ - rt_put_prio (&os_rdy, os_tsk.run); - os_tsk.run->state = READY; - rt_dispatch (NULL); - } - - p_SCB->cb_type = 0; - - return (OS_R_OK); -} -#endif - - -/*--------------------------- rt_sem_send -----------------------------------*/ - -OS_RESULT rt_sem_send (OS_ID semaphore) { - /* Return a token to semaphore */ - P_SCB p_SCB = semaphore; - P_TCB p_TCB; - - __DMB(); - if (p_SCB->p_lnk != NULL) { - /* A task is waiting for token */ - p_TCB = rt_get_first ((P_XCB)p_SCB); -#ifdef __CMSIS_RTOS - rt_ret_val(p_TCB, 1); -#else - rt_ret_val(p_TCB, OS_R_SEM); -#endif - rt_rmv_dly (p_TCB); - rt_dispatch (p_TCB); - } - else { - /* Store token. */ - p_SCB->tokens++; - } - return (OS_R_OK); -} - - -/*--------------------------- rt_sem_wait -----------------------------------*/ - -OS_RESULT rt_sem_wait (OS_ID semaphore, U16 timeout) { - /* Obtain a token; possibly wait for it */ - P_SCB p_SCB = semaphore; - - if (p_SCB->tokens) { - p_SCB->tokens--; - __DMB(); - return (OS_R_OK); - } - /* No token available: wait for one */ - if (timeout == 0) { - return (OS_R_TMO); - } - if (p_SCB->p_lnk != NULL) { - rt_put_prio ((P_XCB)p_SCB, os_tsk.run); - } - else { - p_SCB->p_lnk = os_tsk.run; - os_tsk.run->p_lnk = NULL; - os_tsk.run->p_rlnk = (P_TCB)p_SCB; - } - rt_block(timeout, WAIT_SEM); - return (OS_R_TMO); -} - - -/*--------------------------- isr_sem_send ----------------------------------*/ - -void isr_sem_send (OS_ID semaphore) { - /* Same function as "os_sem"send", but to be called by ISRs */ - P_SCB p_SCB = semaphore; - - rt_psq_enq (p_SCB, 0); - rt_psh_req (); -} - - -/*--------------------------- rt_sem_psh ------------------------------------*/ - -void rt_sem_psh (P_SCB p_CB) { - /* Check if task has to be waken up */ - P_TCB p_TCB; - - __DMB(); - if (p_CB->p_lnk != NULL) { - /* A task is waiting for token */ - p_TCB = rt_get_first ((P_XCB)p_CB); - rt_rmv_dly (p_TCB); - p_TCB->state = READY; -#ifdef __CMSIS_RTOS - rt_ret_val(p_TCB, 1); -#else - rt_ret_val(p_TCB, OS_R_SEM); -#endif - rt_put_prio (&os_rdy, p_TCB); - } - else { - /* Store token */ - p_CB->tokens++; - } -} - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx_ca/rt_Semaphore.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_SEMAPHORE.H - * Purpose: Implements binary and counting semaphores - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Functions */ -extern void rt_sem_init (OS_ID semaphore, U16 token_count); -extern OS_RESULT rt_sem_delete(OS_ID semaphore); -extern OS_RESULT rt_sem_send (OS_ID semaphore); -extern OS_RESULT rt_sem_wait (OS_ID semaphore, U16 timeout); -extern void isr_sem_send (OS_ID semaphore); -extern void rt_sem_psh (P_SCB p_CB); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx_ca/rt_System.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,304 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_SYSTEM.C - * Purpose: System Task Manager - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_Task.h" -#include "rt_System.h" -#include "rt_Event.h" -#include "rt_List.h" -#include "rt_Mailbox.h" -#include "rt_Semaphore.h" -#include "rt_Time.h" -#include "rt_Timer.h" -#include "rt_Robin.h" -#ifdef __CORTEX_A9 -#include "rt_HAL_CA.h" -#else -#include "rt_HAL_CM.h" -#endif - -/*---------------------------------------------------------------------------- - * Global Variables - *---------------------------------------------------------------------------*/ - -int os_tick_irqn; - -/*---------------------------------------------------------------------------- - * Local Variables - *---------------------------------------------------------------------------*/ - -static volatile BIT os_lock; -static volatile BIT os_psh_flag; -#ifndef __CORTEX_A9 -static U8 pend_flags; -#endif -/*---------------------------------------------------------------------------- - * Global Functions - *---------------------------------------------------------------------------*/ - -#if defined (__CC_ARM) -__asm void $$RTX$$version (void) { - /* Export a version number symbol for a version control. */ - - EXPORT __RL_RTX_VER - -__RL_RTX_VER EQU 0x450 -} -#endif - - -/*--------------------------- rt_suspend ------------------------------------*/ - -U32 rt_suspend (void) { - /* Suspend OS scheduler */ - U32 delta = 0xFFFF; - - rt_tsk_lock(); - - if (os_dly.p_dlnk) { - delta = os_dly.delta_time; - } -#ifndef __CMSIS_RTOS - if (os_tmr.next) { - if (os_tmr.tcnt < delta) delta = os_tmr.tcnt; - } -#endif - - return (delta); -} - - -/*--------------------------- rt_resume -------------------------------------*/ - -void rt_resume (U32 sleep_time) { - /* Resume OS scheduler after suspend */ - P_TCB next; - U32 delta; - - os_tsk.run->state = READY; - rt_put_rdy_first (os_tsk.run); - - os_robin.task = NULL; - - /* Update delays. */ - if (os_dly.p_dlnk) { - delta = sleep_time; - if (delta >= os_dly.delta_time) { - delta -= os_dly.delta_time; - os_time += os_dly.delta_time; - os_dly.delta_time = 1; - while (os_dly.p_dlnk) { - rt_dec_dly(); - if (delta == 0) break; - delta--; - os_time++; - } - } else { - os_time += delta; - os_dly.delta_time -= delta; - } - } else { - os_time += sleep_time; - } - -#ifndef __CMSIS_RTOS - /* Check the user timers. */ - if (os_tmr.next) { - delta = sleep_time; - if (delta >= os_tmr.tcnt) { - delta -= os_tmr.tcnt; - os_tmr.tcnt = 1; - while (os_tmr.next) { - rt_tmr_tick(); - if (delta == 0) break; - delta--; - } - } else { - os_tmr.tcnt -= delta; - } - } -#endif - - /* Switch back to highest ready task */ - next = rt_get_first (&os_rdy); - rt_switch_req (next); - - rt_tsk_unlock(); -} - - -/*--------------------------- rt_tsk_lock -----------------------------------*/ - -void rt_tsk_lock (void) { - /* Prevent task switching by locking out scheduler */ - if (os_tick_irqn < 0) { - OS_LOCK(); - os_lock = __TRUE; - OS_UNPEND (&pend_flags); - } else { - OS_X_LOCK(os_tick_irqn); - os_lock = __TRUE; - OS_X_UNPEND (&pend_flags); - } -} - - -/*--------------------------- rt_tsk_unlock ---------------------------------*/ - -void rt_tsk_unlock (void) { - /* Unlock scheduler and re-enable task switching */ - if (os_tick_irqn < 0) { - OS_UNLOCK(); - os_lock = __FALSE; - OS_PEND (pend_flags, os_psh_flag); - os_psh_flag = __FALSE; - } else { - OS_X_UNLOCK(os_tick_irqn); - os_lock = __FALSE; - OS_X_PEND (pend_flags, os_psh_flag); - os_psh_flag = __FALSE; - } -} - - -/*--------------------------- rt_psh_req ------------------------------------*/ - -void rt_psh_req (void) { - /* Initiate a post service handling request if required. */ - if (os_lock == __FALSE) { - OS_PEND_IRQ (); - } - else { - os_psh_flag = __TRUE; - } -} - - -/*--------------------------- rt_pop_req ------------------------------------*/ - -void rt_pop_req (void) { - /* Process an ISR post service requests. */ - struct OS_XCB *p_CB; - P_TCB next; - U32 idx; - - os_tsk.run->state = READY; - rt_put_rdy_first (os_tsk.run); - - idx = os_psq->last; - while (os_psq->count) { - p_CB = os_psq->q[idx].id; - if (p_CB->cb_type == TCB) { - /* Is of TCB type */ - rt_evt_psh ((P_TCB)p_CB, (U16)os_psq->q[idx].arg); - } - else if (p_CB->cb_type == MCB) { - /* Is of MCB type */ - rt_mbx_psh ((P_MCB)p_CB, (void *)os_psq->q[idx].arg); - } - else { - /* Must be of SCB type */ - rt_sem_psh ((P_SCB)p_CB); - } - if (++idx == os_psq->size) idx = 0; - rt_dec (&os_psq->count); - } - os_psq->last = idx; - - next = rt_get_first (&os_rdy); - rt_switch_req (next); -} - - -/*--------------------------- os_tick_init ----------------------------------*/ - -__weak int os_tick_init (void) { - /* Initialize SysTick timer as system tick timer. */ - rt_systick_init (); - return (-1); /* Return IRQ number of SysTick timer */ -} - - -/*--------------------------- os_tick_irqack --------------------------------*/ - -__weak void os_tick_irqack (void) { - /* Acknowledge timer interrupt. */ -} - - -/*--------------------------- rt_systick ------------------------------------*/ - -extern void sysTimerTick(void); - -void rt_systick (void) { - /* Check for system clock update, suspend running task. */ - P_TCB next; - - os_tsk.run->state = READY; - rt_put_rdy_first (os_tsk.run); - - /* Check Round Robin timeout. */ - rt_chk_robin (); - - /* Update delays. */ - os_time++; - rt_dec_dly (); - - /* Check the user timers. */ -#ifdef __CMSIS_RTOS - sysTimerTick(); -#else - rt_tmr_tick (); -#endif - - /* Switch back to highest ready task */ - next = rt_get_first (&os_rdy); - rt_switch_req (next); -} - -/*--------------------------- rt_stk_check ----------------------------------*/ - -__weak void rt_stk_check (void) { - /* Check for stack overflow. */ - if ((os_tsk.run->tsk_stack < (U32)os_tsk.run->stack) || - (os_tsk.run->stack[0] != MAGIC_WORD)) { - os_error (OS_ERR_STK_OVF); - } -} - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx_ca/rt_System.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_SYSTEM.H - * Purpose: System Task Manager definitions - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Variables */ -#define os_psq ((P_PSQ)&os_fifo) -extern int os_tick_irqn; - -/* Functions */ -extern U32 rt_suspend (void); -extern void rt_resume (U32 sleep_time); -extern void rt_tsk_lock (void); -extern void rt_tsk_unlock (void); -extern void rt_psh_req (void); -extern void rt_pop_req (void); -extern void rt_systick (void); -extern void rt_stk_check (void); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx_ca/rt_Task.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,372 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_TASK.C - * Purpose: Task functions and system start up. - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_System.h" -#include "rt_Task.h" -#include "rt_List.h" -#include "rt_MemBox.h" -#include "rt_Robin.h" -#ifdef __CORTEX_A9 -#include "rt_HAL_CA.h" -#else -#include "rt_HAL_CM.h" -#endif - -/*---------------------------------------------------------------------------- - * Global Variables - *---------------------------------------------------------------------------*/ - -/* Running and next task info. */ -struct OS_TSK os_tsk; - -/* Task Control Blocks of idle demon */ -struct OS_TCB os_idle_TCB; - - -/*---------------------------------------------------------------------------- - * Local Functions - *---------------------------------------------------------------------------*/ - -static OS_TID rt_get_TID (void) { - U32 tid; - - for (tid = 1; tid <= os_maxtaskrun; tid++) { - if (os_active_TCB[tid-1] == NULL) { - return ((OS_TID)tid); - } - } - return (0); -} - - -/*--------------------------- rt_init_context -------------------------------*/ - -static void rt_init_context (P_TCB p_TCB, U8 priority, FUNCP task_body) { - /* Initialize general part of the Task Control Block. */ - p_TCB->cb_type = TCB; - p_TCB->state = READY; - p_TCB->prio = priority; - p_TCB->p_lnk = NULL; - p_TCB->p_rlnk = NULL; - p_TCB->p_dlnk = NULL; - p_TCB->p_blnk = NULL; - p_TCB->delta_time = 0; - p_TCB->interval_time = 0; - p_TCB->events = 0; - p_TCB->waits = 0; - p_TCB->stack_frame = 0; - - if (p_TCB->priv_stack == 0) { - /* Allocate the memory space for the stack. */ - p_TCB->stack = rt_alloc_box (mp_stk); - } - rt_init_stack (p_TCB, task_body); -} - - -/*--------------------------- rt_switch_req ---------------------------------*/ - -void rt_switch_req (P_TCB p_new) { - /* Switch to next task (identified by "p_new"). */ - os_tsk.new = p_new; - p_new->state = RUNNING; - DBG_TASK_SWITCH(p_new->task_id); -} - - -/*--------------------------- rt_dispatch -----------------------------------*/ - -void rt_dispatch (P_TCB next_TCB) { - /* Dispatch next task if any identified or dispatch highest ready task */ - /* "next_TCB" identifies a task to run or has value NULL (=no next task) */ - if (next_TCB == NULL) { - /* Running task was blocked: continue with highest ready task */ - next_TCB = rt_get_first (&os_rdy); - rt_switch_req (next_TCB); - } - else { - /* Check which task continues */ - if (next_TCB->prio > os_tsk.run->prio) { - /* preempt running task */ - rt_put_rdy_first (os_tsk.run); - os_tsk.run->state = READY; - rt_switch_req (next_TCB); - } - else { - /* put next task into ready list, no task switch takes place */ - next_TCB->state = READY; - rt_put_prio (&os_rdy, next_TCB); - } - } -} - - -/*--------------------------- rt_block --------------------------------------*/ - -void rt_block (U16 timeout, U8 block_state) { - /* Block running task and choose next ready task. */ - /* "timeout" sets a time-out value or is 0xffff (=no time-out). */ - /* "block_state" defines the appropriate task state */ - P_TCB next_TCB; - - if (timeout) { - if (timeout < 0xffff) { - rt_put_dly (os_tsk.run, timeout); - } - os_tsk.run->state = block_state; - next_TCB = rt_get_first (&os_rdy); - rt_switch_req (next_TCB); - } -} - - -/*--------------------------- rt_tsk_pass -----------------------------------*/ - -void rt_tsk_pass (void) { - /* Allow tasks of same priority level to run cooperatively.*/ - P_TCB p_new; - - p_new = rt_get_same_rdy_prio(); - if (p_new != NULL) { - rt_put_prio ((P_XCB)&os_rdy, os_tsk.run); - os_tsk.run->state = READY; - rt_switch_req (p_new); - } -} - - -/*--------------------------- rt_tsk_self -----------------------------------*/ - -OS_TID rt_tsk_self (void) { - /* Return own task identifier value. */ - if (os_tsk.run == NULL) { - return (0); - } - return (os_tsk.run->task_id); -} - - -/*--------------------------- rt_tsk_prio -----------------------------------*/ - -OS_RESULT rt_tsk_prio (OS_TID task_id, U8 new_prio) { - /* Change execution priority of a task to "new_prio". */ - P_TCB p_task; - - if (task_id == 0) { - /* Change execution priority of calling task. */ - os_tsk.run->prio = new_prio; -run:if (rt_rdy_prio() > new_prio) { - rt_put_prio (&os_rdy, os_tsk.run); - os_tsk.run->state = READY; - rt_dispatch (NULL); - } - return (OS_R_OK); - } - - /* Find the task in the "os_active_TCB" array. */ - if (task_id > os_maxtaskrun || os_active_TCB[task_id-1] == NULL) { - /* Task with "task_id" not found or not started. */ - return (OS_R_NOK); - } - p_task = os_active_TCB[task_id-1]; - p_task->prio = new_prio; - if (p_task == os_tsk.run) { - goto run; - } - rt_resort_prio (p_task); - if (p_task->state == READY) { - /* Task enqueued in a ready list. */ - p_task = rt_get_first (&os_rdy); - rt_dispatch (p_task); - } - return (OS_R_OK); -} - - -/*--------------------------- rt_tsk_create ---------------------------------*/ - -OS_TID rt_tsk_create (FUNCP task, U32 prio_stksz, void *stk, void *argv) { - /* Start a new task declared with "task". */ - P_TCB task_context; - U32 i; - - /* Priority 0 is reserved for idle task! */ - if ((prio_stksz & 0xFF) == 0) { - prio_stksz += 1; - } - task_context = rt_alloc_box (mp_tcb); - if (task_context == NULL) { - return (0); - } - /* If "size != 0" use a private user provided stack. */ - task_context->stack = stk; - task_context->priv_stack = prio_stksz >> 8; - /* Pass parameter 'argv' to 'rt_init_context' */ - task_context->msg = argv; - /* For 'size == 0' system allocates the user stack from the memory pool. */ - rt_init_context (task_context, prio_stksz & 0xFF, task); - - /* Find a free entry in 'os_active_TCB' table. */ - i = rt_get_TID (); - os_active_TCB[i-1] = task_context; - task_context->task_id = i; - DBG_TASK_NOTIFY(task_context, __TRUE); - rt_dispatch (task_context); - return ((OS_TID)i); -} - - -/*--------------------------- rt_tsk_delete ---------------------------------*/ - -OS_RESULT rt_tsk_delete (OS_TID task_id) { - /* Terminate the task identified with "task_id". */ - P_TCB task_context; - - if (task_id == 0 || task_id == os_tsk.run->task_id) { - /* Terminate itself. */ - os_tsk.run->state = INACTIVE; - os_tsk.run->tsk_stack = rt_get_PSP (); - rt_stk_check (); - os_active_TCB[os_tsk.run->task_id-1] = NULL; - rt_free_box (mp_stk, os_tsk.run->stack); - os_tsk.run->stack = NULL; - DBG_TASK_NOTIFY(os_tsk.run, __FALSE); - rt_free_box (mp_tcb, os_tsk.run); - os_tsk.run = NULL; - rt_dispatch (NULL); - /* The program should never come to this point. */ - } - else { - /* Find the task in the "os_active_TCB" array. */ - if (task_id > os_maxtaskrun || os_active_TCB[task_id-1] == NULL) { - /* Task with "task_id" not found or not started. */ - return (OS_R_NOK); - } - task_context = os_active_TCB[task_id-1]; - rt_rmv_list (task_context); - rt_rmv_dly (task_context); - os_active_TCB[task_id-1] = NULL; - rt_free_box (mp_stk, task_context->stack); - task_context->stack = NULL; - DBG_TASK_NOTIFY(task_context, __FALSE); - rt_free_box (mp_tcb, task_context); - } - return (OS_R_OK); -} - - -/*--------------------------- rt_sys_init -----------------------------------*/ - -#ifdef __CMSIS_RTOS -void rt_sys_init (void) { -#else -void rt_sys_init (FUNCP first_task, U32 prio_stksz, void *stk) { -#endif - /* Initialize system and start up task declared with "first_task". */ - U32 i; - - DBG_INIT(); - - /* Initialize dynamic memory and task TCB pointers to NULL. */ - for (i = 0; i < os_maxtaskrun; i++) { - os_active_TCB[i] = NULL; - } - rt_init_box (&mp_tcb, mp_tcb_size, sizeof(struct OS_TCB)); - rt_init_box (&mp_stk, mp_stk_size, BOX_ALIGN_8 | (U16)(os_stackinfo)); - rt_init_box ((U32 *)m_tmr, mp_tmr_size, sizeof(struct OS_TMR)); - - /* Set up TCB of idle demon */ - os_idle_TCB.task_id = 255; - os_idle_TCB.priv_stack = 0; - rt_init_context (&os_idle_TCB, 0, os_idle_demon); - - /* Set up ready list: initially empty */ - os_rdy.cb_type = HCB; - os_rdy.p_lnk = NULL; - /* Set up delay list: initially empty */ - os_dly.cb_type = HCB; - os_dly.p_dlnk = NULL; - os_dly.p_blnk = NULL; - os_dly.delta_time = 0; - - /* Fix SP and system variables to assume idle task is running */ - /* Transform main program into idle task by assuming idle TCB */ -#ifndef __CMSIS_RTOS - rt_set_PSP (os_idle_TCB.tsk_stack+32); -#endif - os_tsk.run = &os_idle_TCB; - os_tsk.run->state = RUNNING; - - /* Initialize ps queue */ - os_psq->first = 0; - os_psq->last = 0; - os_psq->size = os_fifo_size; - - rt_init_robin (); - - /* Initialize SVC and PendSV */ - rt_svc_init (); - -#ifndef __CMSIS_RTOS - /* Initialize and start system clock timer */ - os_tick_irqn = os_tick_init (); - if (os_tick_irqn >= 0) { - OS_X_INIT(os_tick_irqn); - } - - /* Start up first user task before entering the endless loop */ - rt_tsk_create (first_task, prio_stksz, stk, NULL); -#endif -} - - -/*--------------------------- rt_sys_start ----------------------------------*/ - -#ifdef __CMSIS_RTOS -void rt_sys_start (void) { - /* Start system */ - - /* Initialize and start system clock timer */ - os_tick_irqn = os_tick_init (); - if (os_tick_irqn >= 0) { - OS_X_INIT(os_tick_irqn); - } -} -#endif - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/rtx_ca/rt_Task.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,87 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_TASK.H - * Purpose: Task functions and system start up. - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Definitions */ - -/* Values for 'state' */ -#define INACTIVE 0 -#define READY 1 -#define RUNNING 2 -#define WAIT_DLY 3 -#define WAIT_ITV 4 -#define WAIT_OR 5 -#define WAIT_AND 6 -#define WAIT_SEM 7 -#define WAIT_MBX 8 -#define WAIT_MUT 9 - -/* Return codes */ -#define OS_R_TMO 0x01 -#define OS_R_EVT 0x02 -#define OS_R_SEM 0x03 -#define OS_R_MBX 0x04 -#define OS_R_MUT 0x05 - -#define OS_R_OK 0x00 -#define OS_R_NOK 0xff - -/* Variables */ -extern struct OS_TSK os_tsk; -extern struct OS_TCB os_idle_TCB; - -/* Functions */ -extern void rt_switch_req (P_TCB p_new); -extern void rt_dispatch (P_TCB next_TCB); -extern void rt_block (U16 timeout, U8 block_state); -extern void rt_tsk_pass (void); -extern OS_TID rt_tsk_self (void); -extern OS_RESULT rt_tsk_prio (OS_TID task_id, U8 new_prio); -extern OS_TID rt_tsk_create (FUNCP task, U32 prio_stksz, void *stk, void *argv); -extern OS_RESULT rt_tsk_delete (OS_TID task_id); -#ifdef __CMSIS_RTOS -extern void rt_sys_init (void); -extern void rt_sys_start (void); -#else -extern void rt_sys_init (FUNCP first_task, U32 prio_stksz, void *stk); -#endif - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ - - - - - -
--- a/rtx_ca/rt_Time.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,94 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_TIME.C - * Purpose: Delay and interval wait functions - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_Task.h" -#include "rt_Time.h" - -/*---------------------------------------------------------------------------- - * Global Variables - *---------------------------------------------------------------------------*/ - -/* Free running system tick counter */ -U32 os_time; - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_time_get -----------------------------------*/ - -U32 rt_time_get (void) { - /* Get system time tick */ - return (os_time); -} - - -/*--------------------------- rt_dly_wait -----------------------------------*/ - -void rt_dly_wait (U16 delay_time) { - /* Delay task by "delay_time" */ - rt_block (delay_time, WAIT_DLY); -} - - -/*--------------------------- rt_itv_set ------------------------------------*/ - -void rt_itv_set (U16 interval_time) { - /* Set interval length and define start of first interval */ - os_tsk.run->interval_time = interval_time; - os_tsk.run->delta_time = interval_time + (U16)os_time; -} - - -/*--------------------------- rt_itv_wait -----------------------------------*/ - -void rt_itv_wait (void) { - /* Wait for interval end and define start of next one */ - U16 delta; - - delta = os_tsk.run->delta_time - (U16)os_time; - os_tsk.run->delta_time += os_tsk.run->interval_time; - if ((delta & 0x8000) == 0) { - rt_block (delta, WAIT_ITV); - } -} - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx_ca/rt_Time.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_TIME.H - * Purpose: Delay and interval wait functions definitions - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Variables */ -extern U32 os_time; - -/* Functions */ -extern U32 rt_time_get (void); -extern void rt_dly_wait (U16 delay_time); -extern void rt_itv_set (U16 interval_time); -extern void rt_itv_wait (void); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx_ca/rt_Timer.c Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,129 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_TIMER.C - * Purpose: User timer functions - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_Timer.h" -#include "rt_MemBox.h" - - -/*---------------------------------------------------------------------------- - * Global Variables - *---------------------------------------------------------------------------*/ - -/* User Timer list pointer */ -struct OS_XTMR os_tmr; - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - -/*--------------------------- rt_tmr_tick -----------------------------------*/ - -void rt_tmr_tick (void) { - /* Decrement delta count of timer list head. Timers having the value of */ - /* zero are removed from the list and the callback function is called. */ - P_TMR p; - - if (os_tmr.next == NULL) { - return; - } - os_tmr.tcnt--; - while (os_tmr.tcnt == 0 && (p = os_tmr.next) != NULL) { - /* Call a user provided function to handle an elapsed timer */ - os_tmr_call (p->info); - os_tmr.tcnt = p->tcnt; - os_tmr.next = p->next; - rt_free_box ((U32 *)m_tmr, p); - } -} - -/*--------------------------- rt_tmr_create ---------------------------------*/ - -OS_ID rt_tmr_create (U16 tcnt, U16 info) { - /* Create an user timer and put it into the chained timer list using */ - /* a timeout count value of "tcnt". User parameter "info" is used as a */ - /* parameter for the user provided callback function "os_tmr_call ()". */ - P_TMR p_tmr, p; - U32 delta,itcnt = tcnt; - - if (tcnt == 0 || m_tmr == NULL) { - return (NULL); - } - p_tmr = rt_alloc_box ((U32 *)m_tmr); - if (!p_tmr) { - return (NULL); - } - p_tmr->info = info; - p = (P_TMR)&os_tmr; - delta = p->tcnt; - while (delta < itcnt && p->next != NULL) { - p = p->next; - delta += p->tcnt; - } - /* Right place found, insert timer into the list */ - p_tmr->next = p->next; - p_tmr->tcnt = (U16)(delta - itcnt); - p->next = p_tmr; - p->tcnt -= p_tmr->tcnt; - return (p_tmr); -} - -/*--------------------------- rt_tmr_kill -----------------------------------*/ - -OS_ID rt_tmr_kill (OS_ID timer) { - /* Remove user timer from the chained timer list. */ - P_TMR p, p_tmr; - - p_tmr = (P_TMR)timer; - p = (P_TMR)&os_tmr; - /* Search timer list for requested timer */ - while (p->next != p_tmr) { - if (p->next == NULL) { - /* Failed, "timer" is not in the timer list */ - return (p_tmr); - } - p = p->next; - } - /* Timer was found, remove it from the list */ - p->next = p_tmr->next; - p->tcnt += p_tmr->tcnt; - rt_free_box ((U32 *)m_tmr, p_tmr); - /* Timer killed */ - return (NULL); -} - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/rtx_ca/rt_Timer.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_TIMER.H - * Purpose: User timer functions - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Variables */ -extern struct OS_XTMR os_tmr; - -/* Functions */ -extern void rt_tmr_tick (void); -extern OS_ID rt_tmr_create (U16 tcnt, U16 info); -extern OS_ID rt_tmr_kill (OS_ID timer); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/rtx_ca/rt_TypeDef.h Thu Nov 06 11:00:33 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,167 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_TYPEDEF.H - * Purpose: Type Definitions - * Rev.: V4.60 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Types */ -typedef char S8; -typedef unsigned char U8; -typedef short S16; -typedef unsigned short U16; -typedef int S32; -typedef unsigned int U32; -typedef long long S64; -typedef unsigned long long U64; -typedef unsigned char BIT; -typedef unsigned int BOOL; -typedef void (*FUNCP)(void); - -typedef U32 OS_TID; -typedef void *OS_ID; -typedef U32 OS_RESULT; - -typedef struct OS_TCB { - /* General part: identical for all implementations. */ - U8 cb_type; /* Control Block Type */ - U8 state; /* Task state */ - U8 prio; /* Execution priority */ - U8 task_id; /* Task ID value for optimized TCB access */ - struct OS_TCB *p_lnk; /* Link pointer for ready/sem. wait list */ - struct OS_TCB *p_rlnk; /* Link pointer for sem./mbx lst backwards */ - struct OS_TCB *p_dlnk; /* Link pointer for delay list */ - struct OS_TCB *p_blnk; /* Link pointer for delay list backwards */ - U16 delta_time; /* Time until time out */ - U16 interval_time; /* Time interval for periodic waits */ - U16 events; /* Event flags */ - U16 waits; /* Wait flags */ - void **msg; /* Direct message passing when task waits */ - - /* Hardware dependant part: specific for Cortex processor */ - U8 stack_frame; /* Stack frame: 0x1 Basic/Extended, 0x2 FP stacked/not stacked */ - U8 reserved; - U16 priv_stack; /* Private stack size, 0= system assigned */ - U32 tsk_stack; /* Current task Stack pointer (R13) */ - U32 *stack; /* Pointer to Task Stack memory block */ - - /* Task entry point used for uVision debugger */ - FUNCP ptask; /* Task entry address */ -} *P_TCB; -#define TCB_TID 3 /* 'task id' offset */ -#define TCB_STACKF 32 /* 'stack_frame' offset */ -#define TCB_TSTACK 36 /* 'tsk_stack' offset */ - -typedef struct OS_PSFE { /* Post Service Fifo Entry */ - void *id; /* Object Identification */ - U32 arg; /* Object Argument */ -} *P_PSFE; - -typedef struct OS_PSQ { /* Post Service Queue */ - U8 first; /* FIFO Head Index */ - U8 last; /* FIFO Tail Index */ - U8 count; /* Number of stored items in FIFO */ - U8 size; /* FIFO Size */ - struct OS_PSFE q[1]; /* FIFO Content */ -} *P_PSQ; - -typedef struct OS_TSK { - P_TCB run; /* Current running task */ - P_TCB new; /* Scheduled task to run */ -} *P_TSK; - -typedef struct OS_ROBIN { /* Round Robin Control */ - P_TCB task; /* Round Robin task */ - U16 time; /* Round Robin switch time */ - U16 tout; /* Round Robin timeout */ -} *P_ROBIN; - -typedef struct OS_XCB { - U8 cb_type; /* Control Block Type */ - struct OS_TCB *p_lnk; /* Link pointer for ready/sem. wait list */ - struct OS_TCB *p_rlnk; /* Link pointer for sem./mbx lst backwards */ - struct OS_TCB *p_dlnk; /* Link pointer for delay list */ - struct OS_TCB *p_blnk; /* Link pointer for delay list backwards */ - U16 delta_time; /* Time until time out */ -} *P_XCB; - -typedef struct OS_MCB { - U8 cb_type; /* Control Block Type */ - U8 state; /* State flag variable */ - U8 isr_st; /* State flag variable for isr functions */ - struct OS_TCB *p_lnk; /* Chain of tasks waiting for message */ - U16 first; /* Index of the message list begin */ - U16 last; /* Index of the message list end */ - U16 count; /* Actual number of stored messages */ - U16 size; /* Maximum number of stored messages */ - void *msg[1]; /* FIFO for Message pointers 1st element */ -} *P_MCB; - -typedef struct OS_SCB { - U8 cb_type; /* Control Block Type */ - U8 mask; /* Semaphore token mask */ - U16 tokens; /* Semaphore tokens */ - struct OS_TCB *p_lnk; /* Chain of tasks waiting for tokens */ -} *P_SCB; - -typedef struct OS_MUCB { - U8 cb_type; /* Control Block Type */ - U8 prio; /* Owner task default priority */ - U16 level; /* Call nesting level */ - struct OS_TCB *p_lnk; /* Chain of tasks waiting for mutex */ - struct OS_TCB *owner; /* Mutex owner task */ -} *P_MUCB; - -typedef struct OS_XTMR { - struct OS_TMR *next; - U16 tcnt; -} *P_XTMR; - -typedef struct OS_TMR { - struct OS_TMR *next; /* Link pointer to Next timer */ - U16 tcnt; /* Timer delay count */ - U16 info; /* User defined call info */ -} *P_TMR; - -typedef struct OS_BM { - void *free; /* Pointer to first free memory block */ - void *end; /* Pointer to memory block end */ - U32 blk_size; /* Memory block size */ -} *P_BM; - -/* Definitions */ -#define __TRUE 1 -#define __FALSE 0 -#define NULL ((void *) 0) - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -