Commit 1ec980f8 authored by Christopher Reis's avatar Christopher Reis

initial RTOS commit

Nothing but the rtos in this one
parents
721c3a93a7b800ea74280f56263302aae433ab63 66
721c3a93a7b800ea74280f56263302aae433ab63 default
File added
[paths]
default = /filer/web_data/published_repositories/18819/29897
revlogv1
store
fncache
dotencode
data/rtx/TARGET_CORTEX_M/cmsis_os.h.i
data/rtx/rt_List.c.i
data/rtx/TARGET_CORTEX_M/os_tcb.h.i
data/rtx/rt_CMSIS.c.i
data/rtos/RtosTimer.cpp.i
data/rtx/TARGET_CORTEX_A/rt_Mutex.h.i
data/rtx/TARGET_CORTEX_M/rt_Time.c.i
data/rtx_ca/HAL_CM.c.i
data/rtx_ca/rt_Memory.c.i
data/rtx_ca/rt_Robin.h.i
data/rtx/TARGET_CORTEX_A/HAL_CM.c.i
data/rtx_ca/rt_System.c.i
data/rtx/TARGET_CORTEX_M/rt_Semaphore.c.i
data/rtx/TARGET_M4/TOOLCHAIN_ARM/SVC_Table.s.i
data/rtx_ca/rt_Timer.c.i
data/rtx/rt_Task.h.i
data/rtx/TARGET_CORTEX_M/rt_TypeDef.h.i
data/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/SVC_Table.s.i
data/rtx/TARGET_CORTEX_A/rt_System.h.i
data/rtx/TARGET_CORTEX_M/rt_Mailbox.c.i
data/rtx/RTX_Conf.h.i
data/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/SVC_Table.s.i
data/rtx/TARGET_M0P/TOOLCHAIN_ARM/SVC_Table.s.i
data/rtx/TARGET_CORTEX_M/rt_Task.c.i
data/rtx/TARGET_M0/TOOLCHAIN_GCC/SVC_Table.s.i
data/rtx_ca/rt_Event.h.i
data/rtx/rt_MemBox.h.i
data/rtx/LPC1768/ARM/SVC_Table.s.i
data/rtx/TARGET_CORTEX_M/rt_System.c.i
data/rtx/TARGET_M0/TOOLCHAIN_ARM/HAL_CM0.c.i
data/rtx_ca/rt_Mailbox.h.i
data/rtx/TARGET_CORTEX_A/rt_MemBox.h.i
data/rtx/TARGET_CORTEX_M/rt_List.h.i
data/rtx/rt_Mailbox.h.i
data/rtx/LPC4088/ARM/SVC_Table.s.i
data/rtx/RTX_CM_lib.h.i
data/rtx/KL25Z/ARM/HAL_CM0.c.i
data/rtx/LPC4088/ARM/HAL_CM4.c.i
data/rtx_ca/rt_HAL_CM.h.i
data/rtx/TARGET_CORTEX_M/rt_Event.c.i
data/rtos.lib.i
data/rtx/TARGET_CORTEX_A/rt_HAL_CM.h.i
data/rtx/TARGET_CORTEX_M/rt_System.h.i
data/rtx/TARGET_CORTEX_A/rt_Task.h.i
data/rtx/TARGET_M4/TOOLCHAIN_GCC/SVC_Table.s.i
data/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_ARM/HAL_CM4.c.i
data/RTX_Conf_CM.c.i
data/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/HAL_CM0.s.i
data/rtos/Mail.h.i
data/rtx/TARGET_CORTEX_M/rt_MemBox.c.i
data/rtx/TARGET_CORTEX_A/rt_Time.h.i
data/rtx/rt_Task.c.i
data/rtx/TARGET_CORTEX_A/rt_Task.c.i
data/rtx_ca/rt_List.c.i
data/rtx/cmsis_os.h.i
data/rtx/TARGET_M4/TOOLCHAIN_GCC/HAL_CM4.s.i
data/rtx/TARGET_CORTEX_A/rt_TypeDef.h.i
data/rtos/Semaphore.cpp.i
data/rtx/TARGET_CORTEX_A/rt_MemBox.c.i
data/rtx_ca/rt_MemBox.h.i
data/rtx/rt_Mutex.h.i
data/rtx/TARGET_CORTEX_M/RTX_Conf.h.i
data/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/SVC_Table.s.i
data/rtx/TARGET_CORTEX_A/ARM/SVC_Table.s.i
data/rtx_ca/rt_List.h.i
data/rtx_ca/ARM/SVC_Table.s.i
data/rtx/TARGET_CORTEX_A/rt_Event.c.i
data/rtx_ca/cmsis_os.h.i
data/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/HAL_CM3.s.i
data/rtx/TARGET_CORTEX_M/rt_CMSIS.c.i
data/rtx/TARGET_CORTEX_A/rt_List.h.i
data/rtx/RTX_Config.h.i
data/rtx_ca/rt_Timer.h.i
data/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_IAR/SVC_Table.s.i
data/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/SVC_Table.s.i
data/rtx_ca/rt_Mailbox.c.i
data/rtx/TARGET_CORTEX_M/rt_Event.h.i
data/rtx/TARGET_CORTEX_M/RTX_Conf_CM.c.i
data/rtx/TARGET_CORTEX_A/rt_Semaphore.h.i
data/rtx/TARGET_M0P/TOOLCHAIN_ARM/HAL_CM0.c.i
data/rtx/rt_System.h.i
data/rtx_ca/rt_CMSIS.c.i
data/rtx/TARGET_M4/TOOLCHAIN_ARM/HAL_CM4.c.i
data/rtx/TARGET_CORTEX_M/rt_Time.h.i
data/rtx/TARGET_CORTEX_M/RTX_CM_lib.h.i
data/rtx/TARGET_CORTEX_A/rt_Semaphore.c.i
data/rtx/TARGET_M0/TOOLCHAIN_GCC/HAL_CM0.s.i
data/rtx/rt_Mutex.c.i
data/rtx/rt_Event.c.i
data/rtx/rt_Event.h.i
data/rtx/rt_System.c.i
data/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/HAL_CM3.c.i
data/rtos/Thread.cpp.i
data/rtx_ca/rt_Robin.c.i
data/rtx/LPC1768/ARM/HAL_CM3.c.i
data/rtx/TARGET_CORTEX_M/rt_Mailbox.h.i
data/rtx_ca/ARM/HAL_CA9.c.i
data/rtos/Thread.h.i
data/rtx/TARGET_CORTEX_A/rt_Mailbox.h.i
data/rtx/LPC1768/GCC_ARM/HAL_CM3.s.i
data/rtx_ca/rt_Time.h.i
data/rtx/TARGET_CORTEX_A/rt_Robin.h.i
data/rtx/rt_Robin.c.i
data/rtx_ca/rt_Mutex.c.i
data/rtx/LPC11U24/uARM/SVC_Table.s.i
data/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/HAL_CM0.s.i
data/rtx/TARGET_CORTEX_M/rt_Mutex.h.i
data/rtx/rt_HAL_CM.h.i
data/rtx/TARGET_CORTEX_A/cmsis_os.h.i
data/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/HAL_CM0.s.i
data/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/SVC_Table.s.i
data/rtx_ca/rt_MemBox.c.i
data/rtx/TARGET_M3/TOOLCHAIN_ARM/SVC_Table.s.i
data/rtx_ca/rt_Task.h.i
data/rtx/TARGET_CORTEX_A/rt_Timer.h.i
data/rtos/Queue.h.i
data/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/HAL_CM0.c.i
data/rtx/rt_Semaphore.h.i
data/rtx/TARGET_CORTEX_A/rt_System.c.i
data/rtx/LPC1768/GCC_ARM/SVC_Table.s.i
data/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/SVC_Table.s.i
data/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/HAL_CM3.s.i
data/rtx/TARGET_CORTEX_A/rt_Timer.c.i
data/rtx/TARGET_M0/TOOLCHAIN_ARM/SVC_Table.s.i
data/rtx_ca/rt_Task.c.i
data/rtx/TARGET_CORTEX_M/rt_Mutex.c.i
data/rtx_ca/rt_Time.c.i
data/rtx/TARGET_M0P/TOOLCHAIN_GCC/HAL_CM0.s.i
data/rtx/TARGET_M3/TOOLCHAIN_ARM/HAL_CM3.c.i
data/rtx/rt_MemBox.c.i
data/rtx/HAL_CM.c.i
data/rtx/TARGET_CORTEX_A/rt_Mailbox.c.i
data/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_GCC/HAL_CM4.s.i
data/rtx/rt_Robin.h.i
data/rtx_ca/RTX_CM_lib.h.i
data/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/HAL_CM0.s.i
data/rtx/TARGET_CORTEX_A/rt_Event.h.i
data/rtx/LPC4088/GCC_CR/SVC_Table.s.i
data/rtx_ca/rt_Memory.h.i
data/rtx/rt_Time.h.i
data/rtx/RTX_Conf_CM.c.i
data/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_IAR/HAL_CM4.s.i
data/rtx/LPC11U24/GCC_ARM/HAL_CM0.s.i
data/rtx/TARGET_CORTEX_M/rt_HAL_CM.h.i
data/rtx/rt_TypeDef.h.i
data/rtx/TARGET_CORTEX_M/rt_MemBox.h.i
data/rtx/TARGET_M0P/TOOLCHAIN_GCC/SVC_Table.s.i
data/rtx/LPC11U24/GCC_ARM/SVC_Table.s.i
data/rtx/LPC11U24/uARM/HAL_CM0.c.i
data/rtx/TARGET_CORTEX_A/rt_CMSIS.c.i
data/rtx/TARGET_CORTEX_A/rt_Memory.c.i
data/rtx_ca/RTX_Conf_CA.c.i
data/rtx/TARGET_CORTEX_M/rt_Task.h.i
data/rtos/Semaphore.h.i
data/rtx_ca/rt_Event.c.i
data/rtx.lib.i
data/rtx/TARGET_CORTEX_A/RTX_Config.h.i
data/rtx/rt_Mailbox.c.i
data/rtos/rtos.h.i
data/rtx/TARGET_CORTEX_M/rt_Robin.c.i
data/rtx/rt_List.h.i
data/rtx/TARGET_CORTEX_A/rt_HAL_CA.h.i
data/rtx/rt_Semaphore.c.i
data/rtx/TARGET_CORTEX_A/RTX_Conf_CA.c.i
data/rtx_ca/rt_Semaphore.h.i
data/rtx/TARGET_CORTEX_A/RTX_CM_lib.h.i
data/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_ARM/SVC_Table.s.i
data/rtx/os_tcb.h.i
data/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/SVC_Table.s.i
data/rtx/TARGET_CORTEX_A/ARM/HAL_CA9.c.i
data/rtx/KL25Z/ARM/SVC_Table.s.i
data/rtx_ca/rt_Semaphore.c.i
data/rtx/TARGET_CORTEX_A/HAL_CA.c.i
data/rtos/Mutex.h.i
data/rtx/TARGET_CORTEX_M/rt_Robin.h.i
data/rtos/Mutex.cpp.i
data/rtx_ca/RTX_Config.h.i
data/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/HAL_CM0.c.i
data/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/SVC_Table.s.i
data/rtx/TARGET_CORTEX_M/HAL_CM.c.i
data/rtx/TARGET_CORTEX_A/rt_List.c.i
data/rtx/TARGET_M3/TOOLCHAIN_GCC/HAL_CM3.s.i
data/rtos/MemoryPool.h.i
data/rtx/TARGET_CORTEX_M/rt_List.c.i
data/rtx_ca/HAL_CA.c.i
data/rtx_ca/rt_System.h.i
data/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/SVC_Table.s.i
data/rtx/TARGET_CORTEX_A/rt_Time.c.i
data/rtos/RtosTimer.h.i
data/rtx_ca/rt_HAL_CA.h.i
data/rtx/TARGET_CORTEX_M/rt_Semaphore.h.i
data/rtx/rt_Time.c.i
data/rtx/TARGET_CORTEX_A/rt_Memory.h.i
data/rtx/LPC4088/GCC_CR/HAL_CM4.s.i
data/rtx/TARGET_CORTEX_A/rt_Robin.c.i
data/rtx/TARGET_M3/TOOLCHAIN_GCC/SVC_Table.s.i
data/rtx_ca/rt_TypeDef.h.i
data/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_GCC/SVC_Table.s.i
data/rtx_ca/rt_Mutex.h.i
data/rtx/TARGET_CORTEX_A/rt_Mutex.c.i
File added
default
\ No newline at end of file
0
pull
file:///filer/web_data/published_repositories/18819/29897
<meta http-equiv="refresh" content="0; url=http://developer.mbed.org/handbook/ExportToOfflineToolchain#NUCLEO_L152RE#coide"/>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Project version="2G - 1.7.5" name="mbed-rtos">
<Target name="mbed-rtos" isCurrent="1">
<Device manufacturerId="9" manufacturerName="ST" chipId="561" chipName="STM32L152RD" boardId="" boardName=""/>
<BuildOption>
<Compile>
<Option name="OptimizationLevel" value="4"/>
<Option name="UseFPU" value="0"/>
<Option name="UserEditCompiler" value="-fno-common; -fmessage-length=0; -Wall; -fno-strict-aliasing; -fno-rtti; -fno-exceptions; -ffunction-sections; -fdata-sections; -std=gnu++98"/>
<Option name="FPU" value="1"/>
<Option name="SupportCPlusplus" value="1"/>
<Includepaths>
<Includepath path="."/> <Includepath path="rtx"/> <Includepath path="rtx/TARGET_CORTEX_M"/> <Includepath path="rtx/TARGET_CORTEX_M/TARGET_M3"/> <Includepath path="rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC"/> <Includepath path="rtos"/>
</Includepaths>
<DefinedSymbols>
<Define name="TARGET_NUCLEO_L152RE"/> <Define name="TARGET_M3"/> <Define name="TARGET_CORTEX_M"/> <Define name="TARGET_STM"/> <Define name="TARGET_STM32L1"/> <Define name="TARGET_STM32L152RE"/> <Define name="TOOLCHAIN_GCC_ARM"/> <Define name="TOOLCHAIN_GCC"/> <Define name="__CORTEX_M3"/> <Define name="ARM_MATH_CM3"/> <Define name="MBED_BUILD_TIMESTAMP=1425006333.06"/> <Define name="__MBED__=1"/> <Define name="TARGET_FF_ARDUINO"/> <Define name="TARGET_FF_MORPHO"/>
</DefinedSymbols>
</Compile>
<Link useDefault="0">
<Option name="DiscardUnusedSection" value="1"/>
<Option name="UserEditLinkder" value=""/>
<Option name="UseMemoryLayout" value="0"/>
<Option name="LTO" value="0"/>
<Option name="IsNewStartupCode" value="1"/>
<Option name="Library" value="Not use C Library"/>
<Option name="nostartfiles" value="0"/>
<Option name="UserEditLinker" value="-Wl,--wrap,main; --specs=nano.specs; -u _printf_float; -u _scanf_float; "/>
<LinkedLibraries>
<Libset dir="" libs="stdc++"/>
<Libset dir="" libs="supc++"/>
<Libset dir="" libs="m"/>
<Libset dir="" libs="gcc"/>
<Libset dir="" libs="c"/>
<Libset dir="" libs="nosys"/>
</LinkedLibraries>
<MemoryAreas debugInFlashNotRAM="1">
<Memory name="IROM1" type="ReadOnly" size="0x00080000" startValue="0x08000000"/>
<Memory name="IRAM1" type="ReadWrite" size="0x00013EC4" startValue="0x2000013C"/>
<Memory name="IROM2" type="ReadOnly" size="" startValue=""/>
<Memory name="IRAM2" type="ReadWrite" size="" startValue=""/>
</MemoryAreas>
<LocateLinkFile path="" type="0"/>
</Link>
<Output>
<Option name="OutputFileType" value="0"/>
<Option name="Path" value="./"/>
<Option name="Name" value="mbed-rtos"/>
<Option name="HEX" value="1"/>
<Option name="BIN" value="1"/>
</Output>
<User>
<UserRun name="Run#1" type="Before" checked="0" value=""/>
<UserRun name="Run#1" type="After" checked="0" value=""/>
</User>
</BuildOption>
<DebugOption>
<Option name="org.coocox.codebugger.gdbjtag.core.adapter" value="ST-Link"/>
<Option name="org.coocox.codebugger.gdbjtag.core.debugMode" value="SWD"/>
<Option name="org.coocox.codebugger.gdbjtag.core.clockDiv" value="1M"/>
<Option name="org.coocox.codebugger.gdbjtag.corerunToMain" value="1"/>
<Option name="org.coocox.codebugger.gdbjtag.core.jlinkgdbserver" value=""/>
<Option name="org.coocox.codebugger.gdbjtag.core.userDefineGDBScript" value=""/>
<Option name="org.coocox.codebugger.gdbjtag.core.targetEndianess" value="0"/>
<Option name="org.coocox.codebugger.gdbjtag.core.jlinkResetMode" value="Type 0: Normal"/>
<Option name="org.coocox.codebugger.gdbjtag.core.resetMode" value="SYSRESETREQ"/>
<Option name="org.coocox.codebugger.gdbjtag.core.ifSemihost" value="0"/>
<Option name="org.coocox.codebugger.gdbjtag.core.ifCacheRom" value="1"/>
<Option name="org.coocox.codebugger.gdbjtag.core.ipAddress" value="127.0.0.1"/>
<Option name="org.coocox.codebugger.gdbjtag.core.portNumber" value="2009"/>
<Option name="org.coocox.codebugger.gdbjtag.core.autoDownload" value="1"/>
<Option name="org.coocox.codebugger.gdbjtag.core.verify" value="1"/>
<Option name="org.coocox.codebugger.gdbjtag.core.downloadFuction" value="Erase Effected"/>
<Option name="org.coocox.codebugger.gdbjtag.core.defaultAlgorithm" value="stm32l1xx_384.elf"/>
</DebugOption>
<ExcludeFile/>
</Target>
<Components path="./"/>
<Files>
<File name="sources/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/HAL_CM3.s" path="rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/HAL_CM3.s" type="1"/>
<File name="sources/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/SVC_Table.s" path="rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/SVC_Table.s" type="1"/>
<File name="sources/rtx/TARGET_CORTEX_M/rt_Task.c" path="rtx/TARGET_CORTEX_M/rt_Task.c" type="1"/>
<File name="sources/rtx/TARGET_CORTEX_M/rt_MemBox.c" path="rtx/TARGET_CORTEX_M/rt_MemBox.c" type="1"/>
<File name="sources/rtx/TARGET_CORTEX_M/rt_Robin.c" path="rtx/TARGET_CORTEX_M/rt_Robin.c" type="1"/>
<File name="sources/rtx/TARGET_CORTEX_M/rt_Mailbox.c" path="rtx/TARGET_CORTEX_M/rt_Mailbox.c" type="1"/>
<File name="sources/rtx/TARGET_CORTEX_M/rt_System.c" path="rtx/TARGET_CORTEX_M/rt_System.c" type="1"/>
<File name="sources/rtx/TARGET_CORTEX_M/rt_CMSIS.c" path="rtx/TARGET_CORTEX_M/rt_CMSIS.c" type="1"/>
<File name="sources/rtx/TARGET_CORTEX_M/rt_Event.c" path="rtx/TARGET_CORTEX_M/rt_Event.c" type="1"/>
<File name="sources/rtx/TARGET_CORTEX_M/rt_Semaphore.c" path="rtx/TARGET_CORTEX_M/rt_Semaphore.c" type="1"/>
<File name="sources/rtx/TARGET_CORTEX_M/RTX_Conf_CM.c" path="rtx/TARGET_CORTEX_M/RTX_Conf_CM.c" type="1"/>
<File name="sources/rtx/TARGET_CORTEX_M/rt_Time.c" path="rtx/TARGET_CORTEX_M/rt_Time.c" type="1"/>
<File name="sources/rtx/TARGET_CORTEX_M/rt_Mutex.c" path="rtx/TARGET_CORTEX_M/rt_Mutex.c" type="1"/>
<File name="sources/rtx/TARGET_CORTEX_M/rt_List.c" path="rtx/TARGET_CORTEX_M/rt_List.c" type="1"/>
<File name="sources/rtx/TARGET_CORTEX_M/HAL_CM.c" path="rtx/TARGET_CORTEX_M/HAL_CM.c" type="1"/>
<File name="sources/rtos/RtosTimer.cpp" path="rtos/RtosTimer.cpp" type="1"/>
<File name="sources/rtos/Thread.cpp" path="rtos/Thread.cpp" type="1"/>
<File name="sources/rtos/Mutex.cpp" path="rtos/Mutex.cpp" type="1"/>
<File name="sources/rtos/Semaphore.cpp" path="rtos/Semaphore.cpp" type="1"/>
<File name="headers/rtx/TARGET_CORTEX_M/RTX_Conf.h" path="rtx/TARGET_CORTEX_M/RTX_Conf.h" type="1"/>
<File name="headers/rtx/TARGET_CORTEX_M/rt_MemBox.h" path="rtx/TARGET_CORTEX_M/rt_MemBox.h" type="1"/>
<File name="headers/rtx/TARGET_CORTEX_M/cmsis_os.h" path="rtx/TARGET_CORTEX_M/cmsis_os.h" type="1"/>
<File name="headers/rtx/TARGET_CORTEX_M/rt_Mutex.h" path="rtx/TARGET_CORTEX_M/rt_Mutex.h" type="1"/>
<File name="headers/rtx/TARGET_CORTEX_M/rt_Task.h" path="rtx/TARGET_CORTEX_M/rt_Task.h" type="1"/>
<File name="headers/rtx/TARGET_CORTEX_M/rt_System.h" path="rtx/TARGET_CORTEX_M/rt_System.h" type="1"/>
<File name="headers/rtx/TARGET_CORTEX_M/rt_Semaphore.h" path="rtx/TARGET_CORTEX_M/rt_Semaphore.h" type="1"/>
<File name="headers/rtx/TARGET_CORTEX_M/rt_Robin.h" path="rtx/TARGET_CORTEX_M/rt_Robin.h" type="1"/>
<File name="headers/rtx/TARGET_CORTEX_M/rt_TypeDef.h" path="rtx/TARGET_CORTEX_M/rt_TypeDef.h" type="1"/>
<File name="headers/rtx/TARGET_CORTEX_M/rt_Time.h" path="rtx/TARGET_CORTEX_M/rt_Time.h" type="1"/>
<File name="headers/rtx/TARGET_CORTEX_M/rt_HAL_CM.h" path="rtx/TARGET_CORTEX_M/rt_HAL_CM.h" type="1"/>
<File name="headers/rtx/TARGET_CORTEX_M/os_tcb.h" path="rtx/TARGET_CORTEX_M/os_tcb.h" type="1"/>
<File name="headers/rtx/TARGET_CORTEX_M/rt_Event.h" path="rtx/TARGET_CORTEX_M/rt_Event.h" type="1"/>
<File name="headers/rtx/TARGET_CORTEX_M/rt_Mailbox.h" path="rtx/TARGET_CORTEX_M/rt_Mailbox.h" type="1"/>
<File name="headers/rtx/TARGET_CORTEX_M/RTX_CM_lib.h" path="rtx/TARGET_CORTEX_M/RTX_CM_lib.h" type="1"/>
<File name="headers/rtx/TARGET_CORTEX_M/rt_List.h" path="rtx/TARGET_CORTEX_M/rt_List.h" type="1"/>
<File name="headers/rtos/Semaphore.h" path="rtos/Semaphore.h" type="1"/>
<File name="headers/rtos/RtosTimer.h" path="rtos/RtosTimer.h" type="1"/>
<File name="headers/rtos/Queue.h" path="rtos/Queue.h" type="1"/>
<File name="headers/rtos/Thread.h" path="rtos/Thread.h" type="1"/>
<File name="headers/rtos/Mail.h" path="rtos/Mail.h" type="1"/>
<File name="headers/rtos/rtos.h" path="rtos/rtos.h" type="1"/>
<File name="headers/rtos/MemoryPool.h" path="rtos/MemoryPool.h" type="1"/>
<File name="headers/rtos/Mutex.h" path="rtos/Mutex.h" type="1"/>
</Files>
</Project>
\ No newline at end of file
/* mbed Microcontroller Library
* Copyright (c) 2006-2012 ARM Limited
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef MAIL_H
#define MAIL_H
#include <stdint.h>
#include <string.h>
#include "cmsis_os.h"
namespace rtos {
/** The Mail class allow to control, send, receive, or wait for mail.
A mail is a memory block that is send to a thread or interrupt service routine.
@tparam T data type of a single message element.
@tparam queue_sz maximum number of messages in queue.
*/
template<typename T, uint32_t queue_sz>
class Mail {
public:
/** Create and Initialise Mail queue. */
Mail() {
#ifdef CMSIS_OS_RTX
memset(_mail_q, 0, sizeof(_mail_q));
_mail_p[0] = _mail_q;
memset(_mail_m, 0, sizeof(_mail_m));
_mail_p[1] = _mail_m;
_mail_def.pool = _mail_p;
_mail_def.queue_sz = queue_sz;
_mail_def.item_sz = sizeof(T);
#endif
_mail_id = osMailCreate(&_mail_def, NULL);
}
/** Allocate a memory block of type T
@param millisec timeout value or 0 in case of no time-out. (default: 0).
@return pointer to memory block that can be filled with mail or NULL in case error.
*/
T* alloc(uint32_t millisec=0) {
return (T*)osMailAlloc(_mail_id, millisec);
}
/** Allocate a memory block of type T and set memory block to zero.
@param millisec timeout value or 0 in case of no time-out. (default: 0).
@return pointer to memory block that can be filled with mail or NULL in case error.
*/
T* calloc(uint32_t millisec=0) {
return (T*)osMailCAlloc(_mail_id, millisec);
}
/** Put a mail in the queue.
@param mptr memory block previously allocated with Mail::alloc or Mail::calloc.
@return status code that indicates the execution status of the function.
*/
osStatus put(T *mptr) {
return osMailPut(_mail_id, (void*)mptr);
}
/** Get a mail from a queue.
@param millisec timeout value or 0 in case of no time-out. (default: osWaitForever).
@return event that contains mail information or error code.
*/
osEvent get(uint32_t millisec=osWaitForever) {
return osMailGet(_mail_id, millisec);
}
/** Free a memory block from a mail.
@param mptr pointer to the memory block that was obtained with Mail::get.
@return status code that indicates the execution status of the function.
*/
osStatus free(T *mptr) {
return osMailFree(_mail_id, (void*)mptr);
}
private:
osMailQId _mail_id;
osMailQDef_t _mail_def;
#ifdef CMSIS_OS_RTX
uint32_t _mail_q[4+(queue_sz)];
uint32_t _mail_m[3+((sizeof(T)+3)/4)*(queue_sz)];
void *_mail_p[2];
#endif
};
}
#endif
/* mbed Microcontroller Library
* Copyright (c) 2006-2012 ARM Limited
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef MEMORYPOOL_H
#define MEMORYPOOL_H
#include <stdint.h>
#include <string.h>
#include "cmsis_os.h"
namespace rtos {
/** Define and manage fixed-size memory pools of objects of a given type.
@tparam T data type of a single object (element).
@tparam queue_sz maximum number of objects (elements) in the memory pool.
*/
template<typename T, uint32_t pool_sz>
class MemoryPool {
public:
/** Create and Initialize a memory pool. */
MemoryPool() {
#ifdef CMSIS_OS_RTX
memset(_pool_m, 0, sizeof(_pool_m));
_pool_def.pool = _pool_m;
_pool_def.pool_sz = pool_sz;
_pool_def.item_sz = sizeof(T);
#endif
_pool_id = osPoolCreate(&_pool_def);
}
/** Allocate a memory block of type T from a memory pool.
@return address of the allocated memory block or NULL in case of no memory available.
*/
T* alloc(void) {
return (T*)osPoolAlloc(_pool_id);
}
/** Allocate a memory block of type T from a memory pool and set memory block to zero.
@return address of the allocated memory block or NULL in case of no memory available.
*/
T* calloc(void) {
return (T*)osPoolCAlloc(_pool_id);
}
/** Return an allocated memory block back to a specific memory pool.
@param address of the allocated memory block that is returned to the memory pool.
@return status code that indicates the execution status of the function.
*/
osStatus free(T *block) {
return osPoolFree(_pool_id, (void*)block);
}
private:
osPoolId _pool_id;
osPoolDef_t _pool_def;
#ifdef CMSIS_OS_RTX
uint32_t _pool_m[3+((sizeof(T)+3)/4)*(pool_sz)];
#endif
};
}
#endif
/* mbed Microcontroller Library
* Copyright (c) 2006-2012 ARM Limited
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "Mutex.h"
#include <string.h>
#include "mbed_error.h"
namespace rtos {
Mutex::Mutex() {
#ifdef CMSIS_OS_RTX
memset(_mutex_data, 0, sizeof(_mutex_data));
_osMutexDef.mutex = _mutex_data;
#endif
_osMutexId = osMutexCreate(&_osMutexDef);
if (_osMutexId == NULL) {
error("Error initializing the mutex object\n");
}
}
osStatus Mutex::lock(uint32_t millisec) {
return osMutexWait(_osMutexId, millisec);
}
bool Mutex::trylock() {
return (osMutexWait(_osMutexId, 0) == osOK);
}
osStatus Mutex::unlock() {
return osMutexRelease(_osMutexId);
}
Mutex::~Mutex() {
osMutexDelete(_osMutexId);
}
}
/* mbed Microcontroller Library
* Copyright (c) 2006-2012 ARM Limited
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef MUTEX_H
#define MUTEX_H
#include <stdint.h>
#include "cmsis_os.h"
namespace rtos {
/** The Mutex class is used to synchronise the execution of threads.
This is for example used to protect access to a shared resource.
*/
class Mutex {
public:
/** Create and Initialize a Mutex object */
Mutex();
/** Wait until a Mutex becomes available.
@param millisec timeout value or 0 in case of no time-out. (default: osWaitForever)
@return status code that indicates the execution status of the function.
*/
osStatus lock(uint32_t millisec=osWaitForever);
/** Try to lock the mutex, and return immediately
@return true if the mutex was acquired, false otherwise.
*/
bool trylock();
/** Unlock the mutex that has previously been locked by the same thread
@return status code that indicates the execution status of the function.
*/
osStatus unlock();
~Mutex();
private:
osMutexId _osMutexId;
osMutexDef_t _osMutexDef;
#ifdef CMSIS_OS_RTX
int32_t _mutex_data[3];
#endif
};
}
#endif
/* mbed Microcontroller Library
* Copyright (c) 2006-2012 ARM Limited
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef QUEUE_H
#define QUEUE_H
#include <stdint.h>
#include <string.h>
#include "cmsis_os.h"
#include "mbed_error.h"
namespace rtos {
/** The Queue class allow to control, send, receive, or wait for messages.
A message can be a integer or pointer value to a certain type T that is send
to a thread or interrupt service routine.
@tparam T data type of a single message element.
@tparam queue_sz maximum number of messages in queue.
*/
template<typename T, uint32_t queue_sz>
class Queue {
public:
/** Create and initialise a message Queue. */
Queue() {
#ifdef CMSIS_OS_RTX
memset(_queue_q, 0, sizeof(_queue_q));
_queue_def.pool = _queue_q;
_queue_def.queue_sz = queue_sz;
#endif
_queue_id = osMessageCreate(&_queue_def, NULL);
if (_queue_id == NULL) {
error("Error initialising the queue object\n");
}
}
/** Put a message in a Queue.
@param data message pointer.
@param millisec timeout value or 0 in case of no time-out. (default: 0)
@return status code that indicates the execution status of the function.
*/
osStatus put(T* data, uint32_t millisec=0) {
return osMessagePut(_queue_id, (uint32_t)data, millisec);
}
/** Get a message or Wait for a message from a Queue.
@param millisec timeout value or 0 in case of no time-out. (default: osWaitForever).
@return event information that includes the message and the status code.
*/
osEvent get(uint32_t millisec=osWaitForever) {
return osMessageGet(_queue_id, millisec);
}
private:
osMessageQId _queue_id;
osMessageQDef_t _queue_def;
#ifdef CMSIS_OS_RTX
uint32_t _queue_q[4+(queue_sz)];
#endif
};
}
#endif
/* mbed Microcontroller Library
* Copyright (c) 2006-2012 ARM Limited
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "RtosTimer.h"
#include <string.h>
#include "cmsis_os.h"
#include "mbed_error.h"
namespace rtos {
RtosTimer::RtosTimer(void (*periodic_task)(void const *argument), os_timer_type type, void *argument) {
#ifdef CMSIS_OS_RTX
_timer.ptimer = periodic_task;
memset(_timer_data, 0, sizeof(_timer_data));
_timer.timer = _timer_data;
#endif
_timer_id = osTimerCreate(&_timer, type, argument);
}
osStatus RtosTimer::start(uint32_t millisec) {
return osTimerStart(_timer_id, millisec);
}
osStatus RtosTimer::stop(void) {
return osTimerStop(_timer_id);
}
RtosTimer::~RtosTimer() {
osTimerDelete(_timer_id);
}
}
/* mbed Microcontroller Library
* Copyright (c) 2006-2012 ARM Limited
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef RTOS_TIMER_H
#define RTOS_TIMER_H
#include <stdint.h>
#include "cmsis_os.h"
namespace rtos {
/** The RtosTimer class allow creating and and controlling of timer functions in the system.
A timer function is called when a time period expires whereby both on-shot and
periodic timers are possible. A timer can be started, restarted, or stopped.
Timers are handled in the thread osTimerThread.
Callback functions run under control of this thread and may use CMSIS-RTOS API calls.
*/
class RtosTimer {
public:
/** Create and Start timer.
@param task name of the timer call back function.
@param type osTimerOnce for one-shot or osTimerPeriodic for periodic behaviour. (default: osTimerPeriodic)
@param argument argument to the timer call back function. (default: NULL)
*/
RtosTimer(void (*task)(void const *argument),
os_timer_type type=osTimerPeriodic,
void *argument=NULL);
/** Stop the timer.
@return status code that indicates the execution status of the function.
*/
osStatus stop(void);
/** start a timer.
@param millisec time delay value of the timer.
@return status code that indicates the execution status of the function.
*/
osStatus start(uint32_t millisec);
~RtosTimer();
private:
osTimerId _timer_id;
osTimerDef_t _timer;
#ifdef CMSIS_OS_RTX
uint32_t _timer_data[5];
#endif
};
}
#endif
/* mbed Microcontroller Library
* Copyright (c) 2006-2012 ARM Limited
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "Semaphore.h"
#include <string.h>
namespace rtos {
Semaphore::Semaphore(int32_t count) {
#ifdef CMSIS_OS_RTX
memset(_semaphore_data, 0, sizeof(_semaphore_data));
_osSemaphoreDef.semaphore = _semaphore_data;
#endif
_osSemaphoreId = osSemaphoreCreate(&_osSemaphoreDef, count);
}
int32_t Semaphore::wait(uint32_t millisec) {
return osSemaphoreWait(_osSemaphoreId, millisec);
}
osStatus Semaphore::release(void) {
return osSemaphoreRelease(_osSemaphoreId);
}
Semaphore::~Semaphore() {
osSemaphoreDelete(_osSemaphoreId);
}
}
/* mbed Microcontroller Library
* Copyright (c) 2006-2012 ARM Limited
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef SEMAPHORE_H
#define SEMAPHORE_H
#include <stdint.h>
#include "cmsis_os.h"
namespace rtos {
/** The Semaphore class is used to manage and protect access to a set of shared resources. */
class Semaphore {
public:
/** Create and Initialize a Semaphore object used for managing resources.
@param number of available resources; maximum index value is (count-1).
*/
Semaphore(int32_t count);
/** Wait until a Semaphore resource becomes available.
@param millisec timeout value or 0 in case of no time-out. (default: osWaitForever).
@return number of available tokens, or -1 in case of incorrect parameters
*/
int32_t wait(uint32_t millisec=osWaitForever);
/** Release a Semaphore resource that was obtain with Semaphore::wait.
@return status code that indicates the execution status of the function.
*/
osStatus release(void);
~Semaphore();
private:
osSemaphoreId _osSemaphoreId;
osSemaphoreDef_t _osSemaphoreDef;
#ifdef CMSIS_OS_RTX
uint32_t _semaphore_data[2];
#endif
};
}
#endif
/* mbed Microcontroller Library
* Copyright (c) 2006-2012 ARM Limited
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "Thread.h"
#include "mbed_error.h"
namespace rtos {
Thread::Thread(void (*task)(void const *argument), void *argument,
osPriority priority, uint32_t stack_size, unsigned char *stack_pointer) {
#ifdef CMSIS_OS_RTX
_thread_def.pthread = task;
_thread_def.tpriority = priority;
_thread_def.stacksize = stack_size;
#ifndef __MBED_CMSIS_RTOS_CA9
if (stack_pointer != NULL) {
_thread_def.stack_pointer = (uint32_t*)stack_pointer;
_dynamic_stack = false;
} else {
_thread_def.stack_pointer = new uint32_t[stack_size/sizeof(uint32_t)];
if (_thread_def.stack_pointer == NULL)
error("Error allocating the stack memory\n");
_dynamic_stack = true;
}
#endif
#endif
_tid = osThreadCreate(&_thread_def, argument);
}
osStatus Thread::terminate() {
return osThreadTerminate(_tid);
}
osStatus Thread::set_priority(osPriority priority) {
return osThreadSetPriority(_tid, priority);
}
osPriority Thread::get_priority() {
return osThreadGetPriority(_tid);
}
int32_t Thread::signal_set(int32_t signals) {
return osSignalSet(_tid, signals);
}
Thread::State Thread::get_state() {
#ifndef __MBED_CMSIS_RTOS_CA9
return ((State)_thread_def.tcb.state);
#else
uint8_t status;
status = osThreadGetState(_tid);
return ((State)status);
#endif
}
osEvent Thread::signal_wait(int32_t signals, uint32_t millisec) {
return osSignalWait(signals, millisec);
}
osStatus Thread::wait(uint32_t millisec) {
return osDelay(millisec);
}
osStatus Thread::yield() {
return osThreadYield();
}
osThreadId Thread::gettid() {
return osThreadGetId();
}
Thread::~Thread() {
terminate();
#ifndef __MBED_CMSIS_RTOS_CA9
if (_dynamic_stack) {
delete[] (_thread_def.stack_pointer);
}
#endif
}
}
/* mbed Microcontroller Library
* Copyright (c) 2006-2012 ARM Limited
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef THREAD_H
#define THREAD_H
#include <stdint.h>
#include "cmsis_os.h"
namespace rtos {
/** The Thread class allow defining, creating, and controlling thread functions in the system. */
class Thread {
public:
/** Create a new thread, and start it executing the specified function.
@param task function to be executed by this thread.
@param argument pointer that is passed to the thread function as start argument. (default: NULL).
@param priority initial priority of the thread function. (default: osPriorityNormal).
@param stack_size stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE).
@param stack_pointer pointer to the stack area to be used by this thread (default: NULL).
*/
Thread(void (*task)(void const *argument), void *argument=NULL,
osPriority priority=osPriorityNormal,
uint32_t stack_size=DEFAULT_STACK_SIZE,
unsigned char *stack_pointer=NULL);
/** Terminate execution of a thread and remove it from Active Threads
@return status code that indicates the execution status of the function.
*/
osStatus terminate();
/** Set priority of an active thread
@param priority new priority value for the thread function.
@return status code that indicates the execution status of the function.
*/
osStatus set_priority(osPriority priority);
/** Get priority of an active thread
@return current priority value of the thread function.
*/
osPriority get_priority();
/** Set the specified Signal Flags of an active thread.
@param 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.
*/
int32_t signal_set(int32_t signals);
/** State of the Thread */
enum State {
Inactive, /**< Not created or terminated */
Ready, /**< Ready to run */
Running, /**< Running */
WaitingDelay, /**< Waiting for a delay to occur */
WaitingInterval, /**< Waiting for an interval to occur */
WaitingOr, /**< Waiting for one event in a set to occur */
WaitingAnd, /**< Waiting for multiple events in a set to occur */
WaitingSemaphore, /**< Waiting for a semaphore event to occur */
WaitingMailbox, /**< Waiting for a mailbox event to occur */
WaitingMutex, /**< Waiting for a mutex event to occur */
};
/** State of this Thread
@return the State of this Thread
*/
State get_state();
/** Wait for one or more Signal Flags to become signaled for the current RUNNING thread.
@param signals wait until all specified signal flags set or 0 for any single signal flag.
@param millisec timeout value or 0 in case of no time-out. (default: osWaitForever).
@return event flag information or error code.
*/
static osEvent signal_wait(int32_t signals, uint32_t millisec=osWaitForever);
/** Wait for a specified time period in millisec:
@param millisec time delay value
@return status code that indicates the execution status of the function.
*/
static osStatus wait(uint32_t millisec);
/** Pass control to next thread that is in state READY.
@return status code that indicates the execution status of the function.
*/
static osStatus yield();
/** Get the thread id of the current running thread.
@return thread ID for reference by other functions or NULL in case of error.
*/
static osThreadId gettid();
virtual ~Thread();
private:
osThreadId _tid;
osThreadDef_t _thread_def;
bool _dynamic_stack;
};
}
#endif
/* mbed Microcontroller Library
* Copyright (c) 2006-2012 ARM Limited
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef RTOS_H
#define RTOS_H
#include "Thread.h"
#include "Mutex.h"
#include "RtosTimer.h"
#include "Semaphore.h"
#include "Mail.h"
#include "MemoryPool.h"
#include "Queue.h"
using namespace rtos;
#endif
/*----------------------------------------------------------------------------
* 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
*---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* 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_K22F)
#define INITIAL_SP (0x20010000UL)
#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) || defined(TARGET_LPC4088_DM)
#define INITIAL_SP (0x10010000UL)
#elif defined(TARGET_LPC4330)
#define INITIAL_SP (0x10008000UL)
#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_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)
#elif defined(TARGET_STM32F405RG)
#define INITIAL_SP (0x20020000UL)
#elif defined(TARGET_STM32F429ZI)
#define INITIAL_SP (0x20030000UL)
#elif defined(TARGET_STM32L053R8) || defined(TARGET_STM32L053C8)
#define INITIAL_SP (0x20002000UL)
#elif defined(TARGET_STM32F072RB)
#define INITIAL_SP (0x20004000UL)
#elif defined(TARGET_STM32F091RC)
#define INITIAL_SP (0x20008000UL)
#elif defined(TARGET_STM32F401VC)
#define INITIAL_SP (0x20010000UL)
#else
#error "no target defined"
#endif
#ifdef __CC_ARM
extern uint32_t Image$$RW_IRAM1$$ZI$$Limit[];
#define HEAP_START (Image$$RW_IRAM1$$ZI$$Limit)
#elif defined(__GNUC__)
extern uint32_t __end__[];
#define HEAP_START (__end__)
#elif defined(__ICCARM__)
#pragma section="HEAP"
#define HEAP_START (void *)__section_begin("HEAP")
#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 void* __vector_table;
extern int __low_level_init(void);
extern void __iar_data_init3(void);
extern __weak void __iar_init_core( void );
extern __weak void __iar_init_vfp( void );
extern void __iar_dynamic_initialization(void);
extern void mbed_sdk_init(void);
extern void exit(int arg);
#pragma required=__vector_table
void __iar_program_start( void )
{
__iar_init_core();
__iar_init_vfp();
int a;
if (__low_level_init() != 0) {
__iar_data_init3();
mbed_sdk_init();
__iar_dynamic_initialization();
}
osKernelInitialize();
set_main_stack();
osThreadCreate(&os_thread_def_main, NULL);
a = osKernelStart();
exit(a);
}
#endif
/*----------------------------------------------------------------------------
* end of file
*---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* 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
*---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* 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_LPC4088_DM) || defined(TARGET_LPC4330) || 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_STM32F411RE) || defined(TARGET_STM32F405RG) || defined(TARGET_K22F) || defined(TARGET_STM32F429ZI) || defined(TARGET_STM32F401VC)
# 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) \
|| defined(TARGET_STM32L053R8) || defined(TARGET_STM32L053C8) || defined(TARGET_STM32F072RB) || defined(TARGET_STM32F091RC)
# 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_LPC4088_DM) || defined(TARGET_LPC4330) || 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_STM32F411RE) || defined(TARGET_STM32F405RG) || defined(TARGET_K22F) || defined(TARGET_STM32F429ZI) || defined(TARGET_STM32F401VC)
# 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_STM32F072RB) || defined(TARGET_STM32F091RC)
# define OS_SCHEDULERSTKSIZE 128
# elif defined(TARGET_STM32F334R8) || defined(TARGET_STM32F334C8) || defined(TARGET_STM32L053R8) || defined(TARGET_STM32L053C8)
# define OS_SCHEDULERSTKSIZE 112
# 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_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) || defined(TARGET_STM32F072RB) || defined(TARGET_STM32F091RC)
# 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_LPC4088_DM) || defined(TARGET_K64F) || defined(TARGET_K22F)
# define OS_CLOCK 120000000
# elif defined(TARGET_LPC4330)
# define OS_CLOCK 204000000
# elif defined(TARGET_LPC4337)
# define OS_CLOCK 204000000
# elif defined(TARGET_STM32F407) || defined(TARGET_F407VG)
# define OS_CLOCK 168000000
# elif defined(TARGET_STM32F401RE)
# define OS_CLOCK 84000000
# elif defined(TARGET_STM32F411RE)
# define OS_CLOCK 100000000
#elif defined(TARGET_STM32F103RB)
# define OS_CLOCK 72000000
#elif defined(TARGET_STM32F429ZI)
# define OS_CLOCK 168000000
#elif defined(TARGET_STM32F302R8)
# define OS_CLOCK 64000000
#elif defined(TARGET_STM32L053R8) || defined(TARGET_STM32L053C8)
# define OS_CLOCK 32000000
#elif defined(TARGET_STM32F401VC)
# define OS_CLOCK 84000000
# 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
*---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* 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, 40
/*----------------------------------------------------------------------------
* 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
*---------------------------------------------------------------------------*/
;/*----------------------------------------------------------------------------
; * 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
*---------------------------------------------------------------------------*/
/* ----------------------------------------------------------------------
* 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) || defined(TOOLCHAIN_IAR)
# 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
#elif defined (__ICCARM__)
#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
uint32_t *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) \
uint32_t os_thread_def_stack_##name [stacksz / sizeof(uint32_t)]; \
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
#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 reserved1;
U16 reserved2;
U32 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
/*----------------------------------------------------------------------------
* 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 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 RET_osEvent osEvent
#define RET_osCallback osCallback
#define SVC_Setup(f) \
__asm( \
"mov r12,%0\n" \
:: "r"(&f): "r12" \
);
#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 SVC_1_1
#define SVC_1_3 SVC_1_1
#define SVC_2_3 SVC_2_1
#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;
/* Utilize the user provided stack. */
task_context->stack = (U32*)thread_def->stack_pointer;
task_context->priv_stack = thread_def->stacksize;
/* 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;
/* Pass parameter 'argv' to 'rt_init_context' */
task_context->msg = argument;
/* Initialize thread context structure, including the thread's stack. */
rt_init_context (task_context, priority, (FUNCP)thread_def->pthread);
/* Dispatch this task to the scheduler for execution. */
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;
}
/*----------------------------------------------------------------------------
* 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
*---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* 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
*---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* 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
*---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* 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
*---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* 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
*---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* 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
*---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* 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
*---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* 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
*---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* 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
*---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* 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
*---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* 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
*---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* 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
*---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* 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
*---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* 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
*---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* 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
*---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* 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
*---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* 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
*---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* 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
*---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* 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);
/*----------------------------------------------------------------------------
* 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
*---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* 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
*---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* 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 40 /* '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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment