JEK changes enabling proper recording of IMU/GPS datastrams - 02-APR-2013
Fork of GPS_Incremental by
Revision 4:68268737ff89, committed 2013-03-29
- Comitter:
- jekain314
- Date:
- Fri Mar 29 20:52:24 2013 +0000
- Parent:
- 3:5913df46f94a
- Child:
- 5:46903325b61f
- Commit message:
- from Jim's site - March 29th,2013
Changed in this revision
--- a/ADIS16488.h Fri Mar 22 01:33:24 2013 +0000 +++ b/ADIS16488.h Fri Mar 29 20:52:24 2013 +0000 @@ -31,21 +31,7 @@ void IMUDataReadyISR(void) { - imuRec.GPSTime = GPSTimemsecs + timeFromPPS.read_us()/1000000.0; - spi.write((int) HIGH_REGISTER[0]); // next read will return results from HIGH_REGITER[0] - for (int i=0; i<6; i++) //read the 6 rate and accel variables - { - wd.pt[1] = (unsigned short)spi.write((int) LOW_REGISTER[i]) ; - if (i<5) // dont this on the last because this was pre-called - { - wd.pt[0] = (unsigned short)spi.write((int) HIGH_REGISTER[i+1]); - } - imuRec.dataWord[i] = wd.dataWord; //data word is a signed long - - } - IMUDataReady = true; - IMURecordCounter++; - + IMUDataReady = true; return; }
--- a/MODSERIAL/ChangeLog.c Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,165 +0,0 @@ -/* $Id:$ - -1.23 25th July 2012 - - * LPC1768 code as was. This release includes "alpha" support for the LPC11U24 - -1.22 19th April 2012 - - * http://mbed.org/forum/bugs-suggestions/topic/2936/ - * Bug fix, protect important buffer pointers from IRQ corruption. - Credits: - Anthony Wieser http://mbed.org/users/WieserSoftwareLtd/ for the fix. - BlazeX http://mbed.org/users/BlazeX/ for the alert that a fix was needed! - -1.21 10 May 2011 - - * http://mbed.org/forum/mbed/topic/2264 - -1.20 26 April 2011 - - * Bug fix, not blocking on transmit - by Erik Petrich, http://mbed.org/forum/bugs-suggestions/topic/2200 - -1.19 20 April 2011 - - * Fixed some doxygen comment bugs. - -1.18 20 April 2011 - - * All callbacks now use MODSERIAL_callback (rather than Mbed's FunctionPointer[1] type) - to store and invoke it's callbacks. This allows MODSERIAL to pass a parameter - to callbacks. The function prototype is now void func(MODSERIAL_IRQ_INFO *q). - * Callbacks now pass a pointer to a MODSERIAL_IRQ_INFO class type. - This class holds a pointer to the MODSERIAL object that invoked the callback - thus freeing callbacks need to use the global variable of the original - MODSERIAL instance. - * MODSERIAL_IRQ_INFO also declares public functions that are protected within MODSERIAL - thus allowing certain functions to be restricted to callback context only. - * New function MODSERIAL_IRQ_INFO::rxDiscardLastChar() allows an rxCallback function - to remove the character that was just placed into the RX buffer. - - [1] http://mbed.org/users/AjK/libraries/FPointer/latest/docs/ - -1.17 08/Mar/2011 - Fixed a memory leak in the DMA code. - -1.16 - 12 Feb 2011 - - * Missed one, doh! - -1.15 - 12 Feb 2011 - - * Fixed some typos. - -1.14 - 7 Feb 2011 - - * Fixed a bug in __putc() that caused the output buffer pointer to - become corrupted. - -1.13 - 20/01/2011 - - * Added extra documentation. - * Fixed some typos. - -1.12 - 20/01/2011 - - * Added new "autoDetectChar()" function. To use:- - 1st: Add a callback to invoke when the char is detected:- - .attach(&detectedChar, MODSERIAL::RxAutoDetect); - 2nd: Send the char to detect. - .autoDectectChar('\n'); - Whenever that char goes into the RX buffer your callback will be invoked. - Added example2.cpp to demo a simple messaging system using this auto feature. - - -1.11 - 23/11/2010 - - * Fixed a minor issue with 1.10 missed an alteration of name change. - -1.10 - 23/11/2010 - - * Rename the DMA callback from attach_dma_complete() to attach_dmaSendComplete() - -1.9 - 23/11/2010 - - * Added support for DMA sending of characters. Required is - the MODDMA library module:- - http://mbed.org/users/AjK/libraries/MODDMA/latest - See example_dma.cpp for more information. - -1.8 - 22/11/2010 - - * Added code so that if a buffer is set to zero length then - MODSERIAL defaults to just using the FIFO for that stream - thus making the library "fall back" to teh same operation - that the Mbed Serial library performs. - * Removed dmaSend() function that should have been removed - at 1.7 - -1.7 - 21/11/2010 - - * Remove the DMA enum from MODSERIAL.h as it's not currently - ready for release. - * Added page doxygen comments. - -1.6 - 21/11/2010 - - * Version 1.5 solved a blocking problem on putc() when called - from another ISR. However, isr_tx() invokes a callback of it's - own when a byte is tranferred from TX buffer to TX FIFO. User - programs may interpret that as an IRQ callback. That's an ISR - call from within an existing ISR which is not good. So the - TxIrq callback from isr_tx is now conditional. It will only - be called when isr_tx() is actually within it's own ISR and - not when called from alternate ISR handlers. - -1.5 - 21/11/2010 - - * Calling putc() (or any derived function that uses it like - printf()) while inside an interrupt service routine can - cause the system to lock up if the TX buffer is full. This - is because bytes are only transferred from the TX buffer to - the TX FIFO via the TX ISR. If we are, say in an RX ISR already, - then the TX ISR will never trigger. The TX buffer stays full and - there is never space to putc() the byte. So, while putc() blocks - waiting for space it calls isr_tx() to ensure if TX FIFO space - becomes available it will move bytes from the TX buffer to TX - FIFO thus removing the blocking condition within putc(). - -1.4 - 21/11/2010 - - * Removed all the new DMA code. I wish mbed.org had proper SVN - versioning, I'm use to working in HEAD and BRANCHES after I've - released a project. Getting bug reports in current releases - while trying to dev new code is hard to manage without source - control of some type! - -1.3 - 21/11/2010 - - * Fixed a macro problem with txIsBusy() - * Started adding code to use "block data" sending using DMA - * Removed #include "IOMACROS.h" - -1.2 - 21/11/2010 - - * Removed unsed variables from flushBuffer() - * Fixed a bug where both RX AND TX fifos are cleared/reset - when just TX OR RX should be cleared. - * Fixed a bug that cleared IIR when in fact it should be left - alone so that any pending interrupt after flush is handled. - * Merged setBase() into init() as it wasn't required anywhere else. - * Changed init() to enforce _uidx is set by Serial to define the _base - address of the Uart in use. - -1.1 - 20/11/2010 - - * Added this file - * Removed cruft from GETC.cpp - * "teh" should be "the", why do my fingers do that? - -1.0 - 20/11/2010 - - * First release. - -*/ \ No newline at end of file
--- a/MODSERIAL/FLUSH.cpp Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/* - Copyright (c) 2010 Andy Kirkham - - 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 "MODSERIAL.h" -#include "MACROS.h" - -namespace AjK { - -void -MODSERIAL::flushBuffer(IrqType type) -{ - uint32_t ier = _IER; - switch(type) { - case TxIrq: _IER &= ~(1UL << 1); break; - case RxIrq: _IER &= ~(1UL << 0); break; - } - buffer_in[type] = 0; - buffer_out[type] = 0; - buffer_count[type] = 0; - buffer_overflow[type] = 0; - switch(type) { - case TxIrq: _FCR = MODSERIAL_FIFO_TX_RESET; break; - case RxIrq: _FCR = MODSERIAL_FIFO_RX_RESET; break; - } - _IER = ier; -} - -}; // namespace AjK ends
--- a/MODSERIAL/GETC.cpp Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/* - Copyright (c) 2010 Andy Kirkham - - 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 "MODSERIAL.h" -#include "MACROS.h" - -namespace AjK { - -int -MODSERIAL::__getc(bool block) -{ - // If no buffer is in use fall back to standard RX FIFO usage. - // Note, we must block in this case and ignore bool "block" - // so as to maintain compat with Mbed Serial. - if (buffer_size[RxIrq] == 0 || buffer[RxIrq] == (char *)NULL) { - while(! MODSERIAL_RBR_HAS_DATA ) ; - return (int)(_RBR & 0xFF); - } - - if (block) { while ( MODSERIAL_RX_BUFFER_EMPTY ) ; } // Blocks. - else if ( MODSERIAL_RX_BUFFER_EMPTY ) return -1; - - int c = buffer[RxIrq][buffer_out[RxIrq]]; - buffer_out[RxIrq]++; - if (buffer_out[RxIrq] >= buffer_size[RxIrq]) { - buffer_out[RxIrq] = 0; - } - - // If we have made space in the RX Buffer then copy over - // any characters in the RX FIFO that my reside there. - // Temporarily disable the RX IRQ so that we do not re-enter - // it under interrupts. - if ( ! MODSERIAL_RX_BUFFER_FULL ) { - uint32_t ier = _IER; - _IER &= ~(1UL << 0); - isr_rx(); - _IER = ier; - } - - __disable_irq(); - buffer_count[RxIrq]--; - __enable_irq(); - return c; -} - -}; // namespace AjK ends
--- a/MODSERIAL/INIT.cpp Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -/* - Copyright (c) 2010 Andy Kirkham - - 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 "MODSERIAL.h" -#include "MACROS.h" - -namespace AjK { - -void -MODSERIAL::init( int txSize, int rxSize ) -{ - disableIrq(); - - callbackInfo.setSerial(this); - -#ifdef __LPC11UXX_H__ - - _base = LPC_USART; - -#else - switch(_uidx) { - case 0: _base = LPC_UART0; break; - case 1: _base = LPC_UART1; break; - case 2: _base = LPC_UART2; break; - case 3: _base = LPC_UART3; break; - default : _base = NULL; break; - } -#endif - - dmaSendChannel = -1; - moddma_p = (void *)NULL; - - if (_base != NULL) { - buffer_size[RxIrq] = rxSize; - buffer[RxIrq] = rxSize > 0 ? (char *)malloc(buffer_size[RxIrq]) : (char *)NULL; - buffer_in[RxIrq] = 0; - buffer_out[RxIrq] = 0; - buffer_count[RxIrq] = 0; - buffer_overflow[RxIrq] = 0; - Serial::attach(this, &MODSERIAL::isr_rx, Serial::RxIrq); - - buffer_size[TxIrq] = txSize; - buffer[TxIrq] = txSize > 0 ? (char *)malloc(buffer_size[TxIrq]) : (char *)NULL; - buffer_in[TxIrq] = 0; - buffer_out[TxIrq] = 0; - buffer_count[TxIrq] = 0; - buffer_overflow[TxIrq] = 0; - Serial::attach(this, &MODSERIAL::isr_tx, Serial::TxIrq); - } - else { - error("MODSERIAL must have a defined UART to function."); - } - - _FCR = MODSERIAL_FIFO_ENABLE | MODSERIAL_FIFO_RX_RESET | MODSERIAL_FIFO_TX_RESET; - - auto_detect_char = 0; - - enableIrq(); -} - -}; // namespace AjK ends
--- a/MODSERIAL/ISR_RX.cpp Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -/* - Copyright (c) 2010 Andy Kirkham - - 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 "MODSERIAL.h" -#include "MACROS.h" - -namespace AjK { - -void -MODSERIAL::isr_rx(void) -{ - if (! _base || buffer_size[RxIrq] == 0 || buffer[RxIrq] == (char *)NULL) { - _isr[RxIrq].call(&this->callbackInfo); - return; - } - - while( MODSERIAL_RBR_HAS_DATA ) { - rxc = (char)(_RBR & 0xFF); - if ( MODSERIAL_RX_BUFFER_FULL ) { - buffer_overflow[RxIrq] = rxc; // Oh dear, no room in buffer. - _isr[RxOvIrq].call(&this->callbackInfo); - } - else { - if (buffer[RxIrq] != (char *)NULL) { - buffer[RxIrq][buffer_in[RxIrq]] = rxc; - buffer_count[RxIrq]++; - buffer_in[RxIrq]++; - if (buffer_in[RxIrq] >= buffer_size[RxIrq]) { - buffer_in[RxIrq] = 0; - } - } - _isr[RxIrq].call(&this->callbackInfo); - } - if (auto_detect_char == rxc) { - _isr[RxAutoDetect].call(&this->callbackInfo); - } - } -} - -}; // namespace AjK ends -
--- a/MODSERIAL/ISR_TX.cpp Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -/* - Copyright (c) 2010 Andy Kirkham - - 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 "MODSERIAL.h" -#include "MACROS.h" - -namespace AjK { - -void -MODSERIAL::isr_tx(bool doCallback) -{ - if (! _base || buffer_size[TxIrq] == 0 || buffer[TxIrq] == (char *)NULL) { - _isr[TxIrq].call(&this->callbackInfo); - return; - } - - while (! MODSERIAL_TX_BUFFER_EMPTY && MODSERIAL_THR_HAS_SPACE ) { - _THR = txc = (uint8_t)(buffer[TxIrq][buffer_out[TxIrq]]); - buffer_count[TxIrq]--; - buffer_out[TxIrq]++; - if (buffer_out[TxIrq] >= buffer_size[TxIrq]) { - buffer_out[TxIrq] = 0; - } - if (doCallback) _isr[TxIrq].call(&this->callbackInfo); - } - - if ( MODSERIAL_TX_BUFFER_EMPTY ) { - _IER = 1; - _isr[TxEmpty].call(&this->callbackInfo); - } -} - -}; // namespace AjK ends - -
--- a/MODSERIAL/MACROS.h Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -/* - Copyright (c) 2010 Andy Kirkham - - 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 MODSERIAL_MACROS_H -#define MODSERIAL_MACROS_H - -#define MODSERIAL_RBR 0x00 -#define MODSERIAL_THR 0x00 -#define MODSERIAL_DLL 0x00 -#define MODSERIAL_IER 0x04 -#define MODSERIAL_DML 0x04 -#define MODSERIAL_IIR 0x08 -#define MODSERIAL_FCR 0x08 -#define MODSERIAL_LCR 0x0C -#define MODSERIAL_LSR 0x14 -#define MODSERIAL_SCR 0x1C -#define MODSERIAL_ACR 0x20 -#define MODSERIAL_ICR 0x24 -#define MODSERIAL_FDR 0x28 -#define MODSERIAL_TER 0x30 - -#define MODSERIAL_LSR_RDR (1UL << 0) -#define MODSERIAL_LSR_OE (1UL << 1) -#define MODSERIAL_LSR_PE (1UL << 2) -#define MODSERIAL_LSR_FE (1UL << 3) -#define MODSERIAL_LSR_BR (1UL << 4) -#define MODSERIAL_LSR_THRE (1UL << 5) -#define MODSERIAL_LSR_TEMT (1UL << 6) -#define MODSERIAL_LSR_RXFE (1UL << 7) - -#define MODSERIAL_FIFO_ENABLE 1 -#define MODSERIAL_FIFO_RX_RESET 2 -#define MODSERIAL_FIFO_TX_RESET 4 - -#define _RBR *((char *)_base+MODSERIAL_RBR) -#define _THR *((char *)_base+MODSERIAL_THR) -#define _IIR *((char *)_base+MODSERIAL_IIR) -#define _IER *((char *)_base+MODSERIAL_IER) -#define _LSR *((char *)_base+MODSERIAL_LSR) -#define _FCR *((char *)_base+MODSERIAL_FCR) - -#define MODSERIAL_TX_BUFFER_EMPTY (buffer_count[TxIrq]==0) -#define MODSERIAL_RX_BUFFER_EMPTY (buffer_count[RxIrq]==0) -#define MODSERIAL_TX_BUFFER_FULL (buffer_count[TxIrq]==buffer_size[TxIrq]) -#define MODSERIAL_RX_BUFFER_FULL (buffer_count[RxIrq]==buffer_size[RxIrq]) - -#define MODSERIAL_THR_HAS_SPACE ((int)_LSR&MODSERIAL_LSR_THRE) -#define MODSERIAL_TEMT_IS_EMPTY ((int)_LSR&MODSERIAL_LSR_TEMT) -#define MODSERIAL_RBR_HAS_DATA ((int)_LSR&MODSERIAL_LSR_RDR) - -#endif
--- a/MODSERIAL/MODSERIAL.cpp Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,137 +0,0 @@ -/* - Copyright (c) 2010 Andy Kirkham - - 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. - - @file MODSERIAL.h - @purpose Extends Serial to provide fully buffered IO - @version 1.6 - @date Nov 2010 - @author Andy Kirkham -*/ - -#include "MODSERIAL.h" -#include "MACROS.h" - -namespace AjK { - -MODSERIAL::MODSERIAL( PinName tx, PinName rx, const char *name ) : Serial( tx, rx, name ) -{ - init( MODSERIAL_DEFAULT_TX_BUFFER_SIZE, MODSERIAL_DEFAULT_RX_BUFFER_SIZE ); -} - -MODSERIAL::MODSERIAL( PinName tx, PinName rx, int bufferSize, const char *name ) : Serial( tx, rx, name ) -{ - init( bufferSize, bufferSize ); -} - -MODSERIAL::MODSERIAL( PinName tx, PinName rx, int txSize, int rxSize, const char *name ) : Serial( tx, rx, name ) -{ - init( txSize, rxSize ); -} - -MODSERIAL::~MODSERIAL() -{ - disableIrq(); - if ( buffer[0] != NULL) free((char *)buffer[0] ); - if ( buffer[1] != NULL) free((char *)buffer[1] ); -} - -bool -MODSERIAL::txBufferFull( void ) -{ - return MODSERIAL_TX_BUFFER_FULL; -} - -bool -MODSERIAL::rxBufferFull( void ) -{ - return MODSERIAL_RX_BUFFER_FULL; -} - -bool -MODSERIAL::txBufferEmpty( void ) -{ - return MODSERIAL_TX_BUFFER_EMPTY; -} - -bool -MODSERIAL::rxBufferEmpty( void ) -{ - return MODSERIAL_RX_BUFFER_EMPTY; -} - -bool -MODSERIAL::txIsBusy( void ) -{ - return ( _LSR & ( 3UL << 5 ) == 0 ) ? true : false; -} - -void -MODSERIAL::disableIrq( void ) -{ - -#ifdef __LPC11UXX_H__ - NVIC_DisableIRQ( UART_IRQn ); -#else - switch(_uidx) { - case 0: NVIC_DisableIRQ( UART0_IRQn ); break; - case 1: NVIC_DisableIRQ( UART1_IRQn ); break; - case 2: NVIC_DisableIRQ( UART2_IRQn ); break; - case 3: NVIC_DisableIRQ( UART3_IRQn ); break; - } -#endif -} - -void -MODSERIAL::enableIrq(void) -{ -#ifdef __LPC11UXX_H__ - NVIC_EnableIRQ( UART_IRQn ); -#else - switch( _uidx ) { - case 0: NVIC_EnableIRQ( UART0_IRQn ); break; - case 1: NVIC_EnableIRQ( UART1_IRQn ); break; - case 2: NVIC_EnableIRQ( UART2_IRQn ); break; - case 3: NVIC_EnableIRQ( UART3_IRQn ); break; - } -#endif -} - -int -MODSERIAL::rxDiscardLastChar( void ) -{ - // This function can only be called indirectly from - // an rxCallback function. Therefore, we know we - // just placed a char into the buffer. - char c = buffer[RxIrq][buffer_in[RxIrq]]; - - if (buffer_count[RxIrq]) { - buffer_count[RxIrq]--; - buffer_in[RxIrq]--; - if (buffer_in[RxIrq] < 0) { - buffer_in[RxIrq] = buffer_size[RxIrq] - 1; - } - } - - return (int)c; -} - - -}; // namespace AjK ends
--- a/MODSERIAL/MODSERIAL.h Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1091 +0,0 @@ -/* - Copyright (c) 2010 Andy Kirkham - - 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. - - @file MODSERIAL.h - @purpose Extends Serial to provide fully buffered IO - @version see ChangeLog.c - @date Nov 2010 - @author Andy Kirkham -*/ - -#ifndef MODSERIAL_H -#define MODSERIAL_H - -/** @defgroup API The MODSERIAL API */ -/** @defgroup MISC Misc MODSERIAL functions */ -/** @defgroup INTERNALS MODSERIAL Internals */ - -#ifndef MODSERIAL_DEFAULT_RX_BUFFER_SIZE -#define MODSERIAL_DEFAULT_RX_BUFFER_SIZE 256 -#endif - -#ifndef MODSERIAL_DEFAULT_TX_BUFFER_SIZE -#define MODSERIAL_DEFAULT_TX_BUFFER_SIZE 256 -#endif - -#include "mbed.h" - -namespace AjK { - -// Forward reference. -class MODSERIAL; - -/** - * @author Andy Kirkham - * @see http://mbed.org/cookbook/MODSERIAL - * @see example3a.cpp - * @see example3b.cpp - * @see API - * - * <b>MODSERIAL_IRQ_INFO</b> is a class used to pass information (and access to protected - * MODSERIAL functions) to IRQ callbacks. - */ -class MODSERIAL_IRQ_INFO -{ -public: - friend class MODSERIAL; - - MODSERIAL *serial; - - MODSERIAL_IRQ_INFO() { serial = 0; } - - /** rxDiscardLastChar() - * - * Remove the last char placed into the rx buffer. - * This is an operation that can only be performed - * by an rxCallback function. - * @ingroup API - * @return The byte removed from the buffer. - */ - int rxDiscardLastChar(void); - -protected: - - /** setSerial() - * - * Used internally by MODSERIAL to set the "this" pointer - * of the MODSERIAL that created this object. - * @ingroup INTERNAL - * @param A pointer to a MODSERIAL object instance. - */ - void setSerial(MODSERIAL *s) { serial = s; } -}; - -// Forward reference dummy class. -class MODSERIAL_callback_dummy; - -/** - * @author Andy Kirkham - * @see http://mbed.org/cookbook/MODSERIAL - * @see example3a.cpp - * @see example3b.cpp - * @see API - * - * <b>MODSERIAL_callback</b> is a class used to hold application callbacks that - * MODSERIAL can invoke on certain events. - */ -class MODSERIAL_callback -{ -protected: - - //! C callback function pointer. - void (*c_callback)(MODSERIAL_IRQ_INFO *); - - //! C++ callback object/method pointer (the object part). - MODSERIAL_callback_dummy *obj_callback; - - //! C++ callback object/method pointer (the method part). - void (MODSERIAL_callback_dummy::*method_callback)(MODSERIAL_IRQ_INFO *); - -public: - - /** Constructor - */ - MODSERIAL_callback() { - c_callback = 0; - obj_callback = 0; - method_callback = 0; - } - - /** attach - Overloaded attachment function. - * - * Attach a C type function pointer as the callback. - * - * Note, the callback function prototype must be:- - * @code - * void myCallbackFunction(MODSERIAL_IRQ_INFO *); - * @endcode - * @param A C function pointer to call. - */ - void attach(void (*function)(MODSERIAL_IRQ_INFO *) = 0) { c_callback = function; } - - /** attach - Overloaded attachment function. - * - * Attach a C++ type object/method pointer as the callback. - * - * Note, the callback method prototype must be:- - * @code - * public: - * void myCallbackFunction(MODSERIAL_IRQ_INFO *); - * @endcode - * @param A C++ object pointer. - * @param A C++ method within the object to call. - */ - template<class T> - void attach(T* item, void (T::*method)(MODSERIAL_IRQ_INFO *)) { - obj_callback = (MODSERIAL_callback_dummy *)item; - method_callback = (void (MODSERIAL_callback_dummy::*)(MODSERIAL_IRQ_INFO *))method; - } - - /** call - Overloaded callback initiator. - * - * call the callback function. - * - * @param A pointer to a MODSERIAL_IRQ_INFO object. - */ - void call(MODSERIAL_IRQ_INFO *arg) { - if (c_callback != 0) { - (*c_callback)(arg); - } - else { - if (obj_callback != 0 && method_callback != 0) { - (obj_callback->*method_callback)(arg); - } - } - } -}; - -/** - * @author Andy Kirkham - * @see http://mbed.org/cookbook/MODSERIAL - * @see http://mbed.org/handbook/Serial - * @see example1.cpp - * @see example2.cpp - * @see example3a.cpp - * @see example3b.cpp - * @see example_dma.cpp - * @see API - * - * <b>MODSERIAL</b> extends the Mbed library <a href="/handbook/Serial">Serial</a> to provide fully buffered - * TX and RX streams. Buffer length is fully customisable. - * - * Before using MODSERIAL users should be familar with Mbed's standard <a href="/handbook/Serial">Serial</a> - * library object. MODSERIAL is a direct "drop in" replacement for <a href="/handbook/Serial">Serial</a>. Where - * previously Serial was used, MODSERIAL can be used as adirect replacement instantly offering standard - * TX and RX buffering. By default, both TX and RX buffers are 256 bytes in length. - * - * @image html /media/uploads/mbedofficial/serial_interfaces.png - * - * Standard example: - * @code - * #include "mbed.h" - * #include "MODSERIAL.h" - * - * MODSERIAL pc(USBTX, USBRX); // tx, rx - * - * int main() { - * pc.printf("Hello World!"); - * while(1) { - * pc.putc(pc.getc() + 1); - * } - * } - * @endcode - * - * Example with alternate buffer length: - * @code - * #include "mbed.h" - * #include "MODSERIAL.h" - * - * // Make TX and RX buffers 512byes in length - * MODSERIAL pc(USBTX, USBRX, 512); // tx, rx - * - * int main() { - * pc.printf("Hello World!"); - * while(1) { - * pc.putc(pc.getc() + 1); - * } - * } - * @endcode - * - * Example with alternate buffer length: - * @code - * #include "mbed.h" - * #include "MODSERIAL.h" - * - * // Make TX 1024bytes and RX 512byes in length - * MODSERIAL pc(USBTX, USBRX, 1024, 512); // tx, rx - * - * int main() { - * pc.printf("Hello World!"); - * while(1) { - * pc.putc(pc.getc() + 1); - * } - * } - * @endcode - */ -class MODSERIAL : public Serial -{ -public: - - // Allow instances of MODSERIAL_IRQ_INFO to use protected properties and methods. - friend class MODSERIAL_IRQ_INFO; - - //! A copy of the Serial parity enum - /** @see http://mbed.org/projects/libraries/api/mbed/trunk/Serial#Serial.format */ - enum Parity { - None = 0 - , Odd - , Even - , Forced1 - , Forced0 - }; - - //! A copy of the Serial IrqType enum - enum IrqType { - RxIrq = 0 - , TxIrq - , RxOvIrq - , TxOvIrq - , TxEmpty - , RxAutoDetect - , NumOfIrqTypes - }; - - //! Non-blocking functions return code. - enum Result { - Ok = 0 /*!< Ok. */ - , NoMemory = -1 /*!< Memory allocation failed. */ - , NoChar = -1 /*!< No character in buffer. */ - , BufferOversize = -2 /*!< Oversized buffer. */ - }; - - /** - * The MODSERIAL constructor is used to initialise the serial object. - * - * @param tx PinName of the TX pin. - * @param rx PinName of the TX pin. - * @param name An option name for RPC usage. - */ - MODSERIAL(PinName tx, PinName rx, const char *name = NULL); - - /** - * The MODSERIAL constructor is used to initialise the serial object. - * - * @param tx PinName of the TX pin. - * @param rx PinName of the TX pin. - * @param bufferSize Integer of the TX and RX buffer sizes. - * @param name An option name for RPC usage. - */ - MODSERIAL(PinName tx, PinName rx, int bufferSize, const char *name = NULL); - - /** - * The MODSERIAL constructor is used to initialise the serial object. - * - * @param tx PinName of the TX pin. - * @param rx PinName of the TX pin. - * @param txBufferSize Integer of the TX buffer sizes. - * @param rxBufferSize Integer of the RX buffer sizes. - * @param name An option name for RPC usage. - */ - MODSERIAL(PinName tx, PinName rx, int txBufferSize, int rxBufferSize, const char *name = NULL); - - virtual ~MODSERIAL(); - - /** - * Function: attach - * - * The Mbed standard <a href="/handbook/Serial">Serial</a> library object allows an interrupt callback - * to be made when a byte is received by the TX or RX UART hardware. MODSERIAL traps these interrupts - * to enable it's buffering system. However, after the byte has been received/sent under interrupt control, - * MODSERIAL can callback a user function as a notification of the interrupt. Note, user code should not - * directly interact with the Uart hardware, MODSERIAL does that, instead, MODSERIAL API functions should - * be used. - * - * <b>Note</b>, a character is written out then, if there is room in the TX FIFO and the TX buffer is empty, - * putc() will put the character directly into THR (the output holding register). If the TX FIFO is full and - * cannot accept the character, it is placed into the TX output buffer. The TX interrupts are then enabled - * so that when the TX FIFO empties, the TX buffer is then transferred to the THR FIFO. The TxIrq will ONLY - * be activated when this transfer of a character from BUFFER to THR FIFO takes place. If your character - * throughput is not high bandwidth, then the 16 byte TX FIFO may be enough and the TX output buffer may - * never come into play. - * - * @code - * #include "mbed.h" - * #include "MODSERIAL.h" - * - * DigitalOut led1(LED1); - * DigitalOut led2(LED2); - * DigitalOut led3(LED3); - * - * // To test, connect p9 to p10 as a loopback. - * MODSERIAL pc(p9, p10); - * - * // This function is called when a character goes into the TX buffer. - * void txCallback(void) { - * led2 = !led2; - * } - * - * // This function is called when a character goes into the RX buffer. - * void rxCallback(void) { - * led3 = !led3; - * } - * - * int main() { - * pc.baud(115200); - * pc.attach(&txCallback, MODSERIAL::TxIrq); - * pc.attach(&rxCallback, MODSERIAL::RxIrq); - * - * while(1) { - * led1 = !led1; - * wait(0.5); - * pc.putc('A'); - * wait(0.5); - * } - * ] - * @endcode - * - * @ingroup API - * @param fptr A pointer to a void function, or 0 to set as none - * @param type Which serial interrupt to attach the member function to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty) - */ - void attach(void (*fptr)(MODSERIAL_IRQ_INFO *), IrqType type = RxIrq) { _isr[type].attach(fptr); } - - /** - * Function: attach - * - * The Mbed standard <a href="/handbook/Serial">Serial</a> library object allows an interrupt callback - * to be made when a byte is received by the TX or RX UART hardware. MODSERIAL traps these interrupts - * to enable it's buffering system. However, after the byte has been received/sent under interrupt control, - * MODSERIAL can callback a user function as a notification of the interrupt. Note, user code should not - * directly interact with the Uart hardware, MODSERIAL does that, instead, MODSERIAL API functions should - * be used. - * - * <b>Note</b>, a character is written out then, if there is room in the TX FIFO and the TX buffer is empty, - * putc() will put the character directly into THR (the output holding register). If the TX FIFO is full and - * cannot accept the character, it is placed into the TX output buffer. The TX interrupts are then enabled - * so that when the TX FIFO empties, the TX buffer is then transferred to the THR FIFO. The TxIrq will ONLY - * be activated when this transfer of a character from BUFFER to THR FIFO takes place. If your character - * throughput is not high bandwidth, then the 16 byte TX FIFO may be enough and the TX output buffer may - * never come into play. - * - * @code - * #include "mbed.h" - * #include "MODSERIAL.h" - * - * DigitalOut led1(LED1); - * DigitalOut led2(LED2); - * DigitalOut led3(LED3); - * - * // To test, connect p9 to p10 as a loopback. - * MODSERIAL pc(p9, p10); - * - * class Foo { - * public: - * // This method is called when a character goes into the TX buffer. - * void txCallback(void) { led2 = !led2; } - * - * // This method is called when a character goes into the RX buffer. - * void rxCallback(void) { led3 = !led3; } - * }; - * - * Foo foo; - * - * int main() { - * pc.baud(115200); - * pc.attach(&foo, &Foo::txCallback, MODSERIAL::TxIrq); - * pc.attach(&foo, &Foo::rxCallback, MODSERIAL::RxIrq); - * - * while(1) { - * led1 = !led1; - * wait(0.5); - * pc.putc('A'); - * wait(0.5); - * } - * ] - * @endcode - * - * @ingroup API - * @param tptr A pointer to the object to call the member function on - * @param mptr A pointer to the member function to be called - * @param type Which serial interrupt to attach the member function to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty) - */ - template<typename T> - void attach(T* tptr, void (T::*mptr)(MODSERIAL_IRQ_INFO *), IrqType type = RxIrq) { - if((mptr != 0) && (tptr != 0)) { - _isr[type].attach(tptr, mptr); - } - } - - /** - * @see attach - * @ingroup API - */ - void connect(void (*fptr)(MODSERIAL_IRQ_INFO *), IrqType type = RxIrq) { _isr[RxIrq].attach(fptr); } - - /** - * @see attach - * @ingroup API - */ - template<typename T> - void connect(T* tptr, void (T::*mptr)(MODSERIAL_IRQ_INFO *), IrqType type = RxIrq) { - if((mptr != 0) && (tptr != 0)) { - _isr[type].attach(tptr, mptr); - } - } - - /** - * Function: writeable - * - * Determine if there is space available to write a byte - * - * @ingroup API - * @return 1 if there is space to write a character, else 0 - */ - int writeable() { return txBufferFull() ? 0 : 1; } - - /** - * Function: readable - * - * Determine if there is a byte available to read - * - * @ingroup API - * @return 1 if there is a character available to read, else 0 - */ - int readable() { return rxBufferEmpty() ? 0 : 1; } - - /** - * Function: txBufferSane - * - * Determine if the TX buffer has been initialized. - * - * @ingroup API - * @return true if the buffer is initialized, else false - */ - bool txBufferSane(void) { return buffer[TxIrq] != (char *)NULL ? true : false; } - - /** - * Function: rxBufferSane - * - * Determine if the RX buffer has been initialized. - * - * @ingroup API - * @return true if the buffer is initialized, else false - */ - bool rxBufferSane(void) { return buffer[TxIrq] != (char *)NULL ? true : false; } - - /** - * Function: txBufferGetCount - * - * Returns how many bytes are in the TX buffer - * - * @ingroup API - * @return The number of bytes in the TX buffer - */ - int txBufferGetCount(void) { return buffer_count[TxIrq]; } - - /** - * Function: rxBufferGetCount - * - * Returns how many bytes are in the RX buffer - * - * @ingroup API - * @return The number of bytes in the RX buffer - */ - int rxBufferGetCount(void) { return buffer_count[RxIrq]; } - - /** - * Function: txBufferGetSize - * - * Returns the current size of the TX buffer - * - * @ingroup API - * @return The length iof the TX buffer in bytes - */ - int txBufferGetSize(int size) { return buffer_size[TxIrq]; } - - /** - * Function: rxBufferGetSize - * - * Returns the current size of the RX buffer - * - * @ingroup API - * @return The length iof the RX buffer in bytes - */ - int rxBufferGetSize(int size) { return buffer_size[RxIrq]; } - - /** - * Function: txBufferFull - * - * Is the TX buffer full? - * - * @ingroup API - * @return true if the TX buffer is full, otherwise false - */ - bool txBufferFull(void); - - /** - * Function: rxBufferFull - * - * Is the RX buffer full? - * - * @ingroup API - * @return true if the RX buffer is full, otherwise false - */ - bool rxBufferFull(void); - - /** - * Function: txBufferEmpty - * - * Is the TX buffer empty? - * - * @ingroup API - * @return true if the TX buffer is empty, otherwise false - */ - bool txBufferEmpty(void); - - /** - * Function: rxBufferEmpty - * - * Is the RX buffer empty? - * - * @ingroup API - * @return true if the RX buffer is empty, otherwise false - */ - bool rxBufferEmpty(void); - - /** - * Function: txBufferSetSize - * - * Change the TX buffer size. - * - * @see Result - * @ingroup API - * @param size The new TX buffer size in bytes. - * @param m Perform a memory sanity check. Errs the Mbed if memory alloc fails. - * @return Result Ok on success. - */ - int txBufferSetSize(int size, bool m) { return resizeBuffer(size, TxIrq, m); } - - /** - * Function: rxBufferSetSize - * - * Change the RX buffer size. - * - * @see Result - * @ingroup API - * @param size The new RX buffer size in bytes. - * @param m Perform a memory sanity check. Errs the Mbed if memory alloc fails. - * @return Result Ok on success. - */ - int rxBufferSetSize(int size, bool m) { return resizeBuffer(size, RxIrq, m); } - - /** - * Function: txBufferSetSize - * - * Change the TX buffer size. - * Always performs a memory sanity check, halting the Mbed on failure. - * - * @see Result - * @ingroup API - * @param size The new TX buffer size in bytes. - * @return Result Ok on success. - */ - int txBufferSetSize(int size) { return resizeBuffer(size, TxIrq, true); } - - /** - * Function: rxBufferSetSize - * - * Change the RX buffer size. - * Always performs a memory sanity check, halting the Mbed on failure. - * - * @see Result - * @ingroup API - * @param size The new RX buffer size in bytes. - * @return Result Ok on success. - */ - int rxBufferSetSize(int size) { return resizeBuffer(size, RxIrq, true); } - - /** - * Function: txBufferFlush - * - * Remove all bytes from the TX buffer. - * @ingroup API - */ - void txBufferFlush(void) { flushBuffer(TxIrq); } - - /** - * Function: rxBufferFlush - * - * Remove all bytes from the RX buffer. - * @ingroup API - */ - void rxBufferFlush(void) { flushBuffer(RxIrq); } - - /** - * Function: getcNb - * - * Like getc() but is non-blocking. If no bytes are in the RX buffer this - * function returns Result::NoChar (-1) - * - * @ingroup API - * @return A byte from the RX buffer or Result::NoChar (-1) if bufer empty. - */ - int getcNb() { return __getc(false); } - - /** - * Function: getc - * - * Overloaded version of Serial::getc() - * - * This function blocks (if the RX buffer is empty the function will wait for a - * character to arrive and then return that character). - * - * @ingroup API - * @return A byte from the RX buffer - */ - int getc() { return __getc(true); } - - /** - * Function: txGetLastChar - * - * Rteurn the last byte to pass through the TX interrupt handler. - * - * @ingroup MISC - * @return The byte - */ - char txGetLastChar(void) { return txc; } - - /** - * Function: rxGetLastChar - * - * Return the last byte to pass through the RX interrupt handler. - * - * @ingroup MISC - * @return The byte - */ - char rxGetLastChar(void) { return rxc; } - - /** - * Function: txIsBusy - * - * If the Uart is still actively sending characters this - * function will return true. - * - * @ingroup API - * @return bool - */ - bool txIsBusy(void); - - /** - * Function: autoDetectChar - * - * Set the char that, if seen incoming, invokes the AutoDetectChar callback. - * - * @ingroup API - * @param int c The character to detect. - */ - void autoDetectChar(char c) { auto_detect_char = c; } - - /** - * Function: move - * - * Move contents of RX buffer to external buffer. Stops if "end" detected. - * - * @ingroup API - * @param char *s The destination buffer address - * @param int max The maximum number of chars to move. - * @param char end If this char is detected stop moving. - */ - int move(char *s, int max, char end) { - int counter = 0; - char c; - while(readable()) { - c = getc(); - if (c == end) break; - *(s++) = c; - counter++; - if (counter == max) break; - } - return counter; - } - - /** - * Function: move (overloaded) - * - * Move contents of RX buffer to external buffer. Stops if auto_detect_char detected. - * - * @ingroup API - * @param int max The maximum number of chars to move. - * @param char *s The destination buffer address - */ - int move(char *s, int max) { - return move(s, max, auto_detect_char); - } - - #if 0 // Inhereted from Serial/Stream, for documentation only - /** - * Function: putc - * - * Write a character - * Inhereted from Serial/Stream - * - * @see http://mbed.org/projects/libraries/api/mbed/trunk/Serial#Serial.putc - * @ingroup API - * @param c The character to write to the serial port - */ - int putc(int c); - #endif - - #if 0 // Inhereted from Serial/Stream, for documentation only - /** - * Function: printf - * - * Write a formated string - * Inhereted from Serial/Stream - * - * @see http://mbed.org/projects/libraries/api/mbed/trunk/Serial#Serial.printf - * @ingroup API - * @param format A printf-style format string, followed by the variables to use in formating the string. - */ - int printf(const char* format, ...); - #endif - - #if 0 // Inhereted from Serial/Stream, for documentation only - /** - * Function: scanf - * - * Read a formated string - * Inhereted from Serial/Stream - * - * @see http://mbed.org/projects/libraries/api/mbed/trunk/Serial#Serial.scanf - * @ingroup API - * @param format - A scanf-style format string, followed by the pointers to variables to store the results. - */ - int scanf(const char* format, ...); - #endif - -protected: - /** - * Used to pass information to callbacks. - * @ingroup INTERNALS - */ - MODSERIAL_IRQ_INFO callbackInfo; - - /** - * Remove the last char placed into the rx buffer. - * This is an operation that can only be performed - * by an rxCallback function. To protect the buffers - * this function is defined protected so that a - * regular application cannot call it directly. It - * can only be called by the public version within a - * MODSERIAL_IRQ_INFO class. - * @ingroup INTERNALS - * @return The byte removed from the buffer. - */ - int rxDiscardLastChar(void); - -private: - - /** - * A pointer to the UART peripheral base address being used. - * @ingroup INTERNALS - */ - void *_base; - - /** - * The last byte to pass through the TX IRQ handler. - * @ingroup INTERNALS - */ - volatile char txc; - - /** - * The last byte to pass through the RX IRQ handler. - * @ingroup INTERNALS - */ - volatile char rxc; - - /** - * Pointers to the TX and RX buffers. - * @ingroup INTERNALS - */ - volatile char *buffer[2]; - - /** - * Buffer in pointers. - * @ingroup INTERNALS - */ - volatile int buffer_in[2]; - - /** - * Buffer out pointers. - * @ingroup INTERNALS - */ - volatile int buffer_out[2]; - - /** - * Buffer lengths. - * @ingroup INTERNALS - */ - volatile int buffer_size[2]; - - /** - * Buffer content counters. - * @ingroup INTERNALS - */ - volatile int buffer_count[2]; - - /** - * Buffer overflow. - * @ingroup INTERNALS - */ - volatile int buffer_overflow[2]; - - /** - * Auto-detect character. - * @ingroup INTERNALS - */ - volatile char auto_detect_char; - - /** - * Callback system. - * @ingroup INTERNALS - */ - MODSERIAL_callback _isr[NumOfIrqTypes]; - - /** - * TX Interrupt Service Routine. - * @ingroup INTERNALS - */ - void isr_tx(bool doCallback); - - /** - * TX Interrupt Service Routine stub version. - * @ingroup INTERNALS - */ - void isr_tx(void) { isr_tx(true); } - - - /** - * RX Interrupt Service Routine. - * @ingroup INTERNALS - */ - void isr_rx(void); - - /** - * Disable the interrupts for this Uart. - * @ingroup INTERNALS - */ - void disableIrq(void); - - /** - * Enable the interrupts for this Uart. - * @ingroup INTERNALS - */ - void enableIrq(void); - - /** - * Get a character from the RX buffer - * @ingroup INTERNALS - * @param bool True to block (wait for input) - * @return A byte from the buffer. - */ - int __getc(bool); - - /** - * Put a character from the TX buffer - * @ingroup INTERNALS - * @param bool True to block (wait for space in the TX buffer if full) - * @return 0 on success - */ - int __putc(int c, bool); - - /** - * Function: _putc - * Overloaded virtual function. - */ - virtual int _putc(int c) { return __putc(c, true); } - - /** - * Function: _getc - * Overloaded virtual function. - */ - virtual int _getc() { return __getc(true); } - - /** - * Function: init - * Initialize the MODSERIAL object - * @ingroup INTERNALS - */ - void init(int txSize, int rxSize); - - /** - * Function: flushBuffer - * @ingroup INTERNALS - */ - void flushBuffer(IrqType type); - - /** - * Function: resizeBuffer - * @ingroup INTERNALS - */ - int resizeBuffer(int size, IrqType type = RxIrq, bool memory_check = true); - - /** - * Function: downSizeBuffer - * @ingroup INTERNALS - */ - int downSizeBuffer(int size, IrqType type, bool memory_check); - - /** - * Function: upSizeBuffer - * @ingroup INTERNALS - */ - int upSizeBuffer(int size, IrqType type, bool memory_check); - - /* - * If MODDMA is available the compile in code to handle sending - * an arbitary char buffer. Note, the parts before teh #ifdef - * are declared so that MODSERIAL can access then even if MODDMA - * isn't avaiable. Since MODDMA.h is only available at this point - * all DMA functionality must be declared inline in the class - * definition. - */ -public: - - int dmaSendChannel; - void *moddma_p; - -#ifdef MODDMA_H - - MODDMA_Config *config; - - /** - * Set the "void pointer" moddma_p to be a pointer to a - * MODDMA controller class instance. Used to manage the - * data transfer of DMA configurations. - * - * @ingroup API - * @param p A pointer to "the" instance of MODDMA. - */ - void MODDMA(MODDMA *p) { moddma_p = p; } - - /** - * Send a char buffer to the Uarts TX system - * using DMA. This blocks regular library - * sending. - * - * @param buffer A char buffer of bytes to send. - * @param len The length of the buffer to send. - * @param dmaChannel The DMA channel to use, defaults to 7 - * @return MODDMA::Status MODDMA::ok if all went ok - */ - int dmaSend(char *buffer, int len, int dmaChannel = 7) - { - if (moddma_p == (void *)NULL) return -2; - class MODDMA *dma = (class MODDMA *)moddma_p; - - dmaSendChannel = dmaChannel & 0x7; - - uint32_t conn = MODDMA::UART0_Tx; - switch(_uidx) { - case 0: conn = MODDMA::UART0_Tx; break; - case 1: conn = MODDMA::UART1_Tx; break; - case 2: conn = MODDMA::UART2_Tx; break; - case 3: conn = MODDMA::UART3_Tx; break; - } - - config = new MODDMA_Config; - config - ->channelNum ( (MODDMA::CHANNELS)(dmaSendChannel & 0x7) ) - ->srcMemAddr ( (uint32_t) buffer ) - ->transferSize ( len ) - ->transferType ( MODDMA::m2p ) - ->dstConn ( conn ) - ->attach_tc ( this, &MODSERIAL::dmaSendCallback ) - ->attach_err ( this, &MODSERIAL::dmaSendCallback ) - ; // config end - - // Setup the configuration. - if (dma->Setup(config) == 0) { - return -1; - } - - //dma.Enable( MODDMA::Channel_0 ); - dma->Enable( config->channelNum() ); - return MODDMA::Ok; - } - - /** - * Attach a callback to the DMA completion. - * - * @ingroup API - * @param fptr A function pointer to call - * @return this - */ - void attach_dmaSendComplete(void (*fptr)(MODSERIAL_IRQ_INFO *)) { - _isrDmaSendComplete.attach(fptr); - } - - /** - * Attach a callback to the DMA completion. - * - * @ingroup API - * @param tptr A template pointer to the calling object - * @param mptr A method pointer within the object to call. - * @return this - */ - template<typename T> - void attach_dmaSendComplete(T* tptr, void (T::*mptr)(MODSERIAL_IRQ_INFO *)) { - if((mptr != NULL) && (tptr != NULL)) { - _isrDmaSendComplete.attach(tptr, mptr); - } - } - - MODSERIAL_callback _isrDmaSendComplete; - -protected: - /** - * Callback for dmaSend(). - */ - void dmaSendCallback(void) - { - if (moddma_p == (void *)NULL) return; - class MODDMA *dma = (class MODDMA *)moddma_p; - - MODDMA_Config *config = dma->getConfig(); - dma->haltAndWaitChannelComplete( (MODDMA::CHANNELS)config->channelNum()); - dma->Disable( (MODDMA::CHANNELS)config->channelNum() ); - if (dma->irqType() == MODDMA::TcIrq) dma->clearTcIrq(); - if (dma->irqType() == MODDMA::ErrIrq) dma->clearErrIrq(); - dmaSendChannel = -1; - _isrDmaSendComplete.call(&this->callbackInfo); - delete(config); - } - -#endif // MODDMA_H - -}; - -}; // namespace AjK ends - -using namespace AjK; - -#endif
--- a/MODSERIAL/MODSERIAL_IRQ_INFO.cpp Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -/* - Copyright (c) 2010 Andy Kirkham - - 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. - - @file MODSERIAL_IRQ_INFO.cpp - @author Andy Kirkham -*/ - -#include "MODSERIAL.h" - -namespace AjK { - -int -MODSERIAL_IRQ_INFO::rxDiscardLastChar(void) -{ - if (!serial) return -1; - - return serial->rxDiscardLastChar(); -} - -}; // namespace AjK ends
--- a/MODSERIAL/PUTC.cpp Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -/* - Copyright (c) 2010 Andy Kirkham - - 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 "MODSERIAL.h" -#include "MACROS.h" - -namespace AjK { - -int -MODSERIAL::__putc(int c, bool block) { - - // If no buffer is in use fall back to standard TX FIFO usage. - // Note, we must block in this case and ignore bool "block" - // so as to maintain compat with Mbed Serial. - if (buffer[TxIrq] == (char *)NULL || buffer_size[TxIrq] == 0) { - while (! MODSERIAL_THR_HAS_SPACE) ; // Wait for space in the TX FIFO. - _THR = (uint32_t)c; - return 0; - } - - if ( MODSERIAL_THR_HAS_SPACE && MODSERIAL_TX_BUFFER_EMPTY && dmaSendChannel == -1 ) { - _THR = (uint32_t)c; - } - else { - if (block) { - uint32_t ier = _IER; _IER = 1; - while ( MODSERIAL_TX_BUFFER_FULL ) { // Blocks! - // If putc() is called from an ISR then we are stuffed - // because in an ISR no bytes from the TX buffer will - // get transferred to teh TX FIFOs while we block here. - // So, to work around this, instead of sitting in a - // loop waiting for space in the TX buffer (which will - // never happen in IRQ context), check to see if the - // TX FIFO has space available to move bytes from the - // TX buffer to TX FIFO to make space. The easiest way - // to do this is to poll the isr_tx() function while we - // are blocking. - isr_tx(false); - } - _IER = ier; - } - else if( MODSERIAL_TX_BUFFER_FULL ) { - buffer_overflow[TxIrq] = c; // Oh dear, no room in buffer. - _isr[TxOvIrq].call(&this->callbackInfo); - return -1; - } - _IER &= ~2; - buffer[TxIrq][buffer_in[TxIrq]] = c; - __disable_irq(); - buffer_count[TxIrq]++; - __enable_irq(); - buffer_in[TxIrq]++; - if (buffer_in[TxIrq] >= buffer_size[TxIrq]) { - buffer_in[TxIrq] = 0; - } - _IER |= 2; - } - - return 0; -} - -}; // namespace AjK ends
--- a/MODSERIAL/RESIZE.cpp Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,123 +0,0 @@ -/* - Copyright (c) 2010 Andy Kirkham - - 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 "MODSERIAL.h" -#include "MACROS.h" - -namespace AjK { - -int -MODSERIAL::resizeBuffer(int size, IrqType type, bool memory_check) -{ - int rval = Ok; - - // If the requested size is the same as the current size there's nothing to do, - // just continue to use the same buffer as it's fine as it is. - if (buffer_size[type] == size) return rval; - - // Make sure the ISR cannot use the buffers while we are manipulating them. - disableIrq(); - - // If the requested buffer size is larger than the current size, - // attempt to create a new buffer and use it. - if (buffer_size[type] < size) { - rval = upSizeBuffer(size, type, memory_check); - } - else if (buffer_size[type] > size) { - rval = downSizeBuffer(size, type, memory_check); - } - - // Start the ISR system again with the new buffers. - enableIrq(); - - return rval; -} - -int -MODSERIAL::downSizeBuffer(int size, IrqType type, bool memory_check) -{ - if (size >= buffer_count[type]) { - return BufferOversize; - } - - char *s = (char *)malloc(size); - - if (s == (char *)NULL) { - if (memory_check) { - error("Failed to allocate memory for %s buffer", type == TxIrq ? "TX" : "RX"); - } - return NoMemory; - } - - int c, new_in = 0; - - do { - c = __getc(false); - if (c != -1) s[new_in++] = (char)c; - if (new_in >= size) new_in = 0; - } - while (c != -1); - - free((char *)buffer[type]); - buffer[type] = s; - buffer_in[type] = new_in; - buffer_out[type] = 0; - return Ok; -} - -int -MODSERIAL::upSizeBuffer(int size, IrqType type, bool memory_check) -{ - char *s = (char *)malloc(size); - - if (s == (char *)NULL) { - if (memory_check) { - error("Failed to allocate memory for %s buffer", type == TxIrq ? "TX" : "RX"); - } - return NoMemory; - } - - if (buffer_count[type] == 0) { // Current buffer empty? - free((char *)buffer[type]); - buffer[type] = s; - buffer_in[type] = 0; - buffer_out[type] = 0; - } - else { // Copy the current contents into the new buffer. - int c, new_in = 0; - do { - c = __getc(false); - if (c != -1) s[new_in++] = (char)c; - if (new_in >= size) new_in = 0; // Shouldn't happen, but be sure. - } - while (c != -1); - free((char *)buffer[type]); - buffer[type] = s; - buffer_in[type] = new_in; - buffer_out[type] = 0; - } - - buffer_size[type] = size; - return Ok; -} - -}; // namespace AjK ends
--- a/MODSERIAL/example1.cpp Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,120 +0,0 @@ -#ifdef COMPILE_EXAMPLE1_CODE_MODSERIAL - -/* - * To run this test program, link p9 to p10 so the Serial loops - * back and receives characters it sends. - */ - -#include "mbed.h" -#include "MODSERIAL.h" - -DigitalOut led1(LED1); -DigitalOut led2(LED2); -DigitalOut led3(LED3); -DigitalOut led4(LED4); - -MODSERIAL pc(USBTX, USBRX); - -/* - * As experiement, you can define MODSERIAL as show here and see what - * effects it has on the LEDs. - * - * MODSERIAL uart(TX_PIN, RX_PIN, 512); - * With this, the 512 characters sent can straight into the buffer - * vary quickly. This means LED1 is only on briefly as the TX buffer - * fills. - * - * MODSERIAL uart(TX_PIN, RX_PIN, 32); - * With this, the buffer is smaller than the default 256 bytes and - * therefore LED1 stays on much longer while the system waits for - * room in the TX buffer. - */ -MODSERIAL uart(TX_PIN, RX_PIN); - -// This function is called when a character goes from the TX buffer -// to the Uart THR FIFO register. -void txCallback(MODSERIAL_IRQ_INFO *q) { - led2 = !led2; -} - -// This function is called when TX buffer goes empty -void txEmpty(MODSERIAL_IRQ_INFO *q) { - led2 = 0; - pc.puts(" Done. "); -} - -// This function is called when a character goes into the RX buffer. -void rxCallback(MODSERIAL_IRQ_INFO *q) { - led3 = !led3; - pc.putc(uart.getc()); -} - -int main() { - int c = 'A'; - - // Ensure the baud rate for the PC "USB" serial is much - // higher than "uart" baud rate below. - pc.baud(PC_BAUD); - - // Use a deliberatly slow baud to fill up the TX buffer - uart.baud(1200); - - uart.attach(&txCallback, MODSERIAL::TxIrq); - uart.attach(&rxCallback, MODSERIAL::RxIrq); - uart.attach(&txEmpty, MODSERIAL::TxEmpty); - - // Loop sending characters. We send 512 - // which is twice the default TX/RX buffer size. - - led1 = 1; // Show start of sending with LED1. - - for (int loop = 0; loop < 512; loop++) { - uart.printf("%c", c); - c++; - if (c > 'Z') c = 'A'; - } - - led1 = 0; // Show the end of sending by switching off LED1. - - // End program. Flash LED4. Notice how LED 2 and 3 continue - // to flash for a short period while the interrupt system - // continues to send the characters left in the TX buffer. - - while(1) { - led4 = !led4; - wait(0.25); - } -} - -/* - * Notes. Here is the sort of output you can expect on your PC/Mac/Linux host - * machine that is connected to the "pc" USB serial port. - * - * ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV - * WXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQR - * STUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMN - * OPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJ - * KLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF - * GHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZAB - * CDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQ Done. R - * - * Of interest is that last "R" character after the system has said "Done." - * This comes from the fact that the TxEmpty callback is made when the TX buffer - * becomes empty. MODSERIAL makes use of the fact that the Uarts built into the - * LPC17xx device use a 16 byte FIFO on both RX and TX channels. This means that - * when the TxEmpty callback is made, the TX buffer is empty, but that just means - * the "last few characters" were written to the TX FIFO. So although the TX - * buffer has gone empty, the Uart's transmit system is still sending any remaining - * characters from it's TX FIFO. If you want to be truely sure all the characters - * you have sent have left the Mbed then call txIsBusy(); This function will - * return true if characters are still being sent. If it returns false after - * the Tx buffer is empty then all your characters have been sent. - * - * In a similar way, when characters are received into the RX FIFO, the entire - * FIFO contents is moved to the RX buffer, assuming there is room left in the - * RX buffer. If there is not, any remaining characters are left in the RX FIFO - * and will be moved to the RX buffer on the next interrupt or when the running - * program removes a character(s) from the RX buffer with the getc() method. - */ - -#endif
--- a/MODSERIAL/example2.cpp Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,167 +0,0 @@ -/* - Copyright (c) 2011 Andy Kirkham - - 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. - - @file example2.cpp - @purpose Demos a simple messaging system. - @version see ChangeLog.c - @date Jan 2011 - @author Andy Kirkham -*/ - -/* - This example demostrates a simple "messaging" system. You can use it with - a terminal program to test it out or write a cusom C#/C++/VB/etc program - to read and write messages to or from the Mbed. The default baud rate in - this example is 115200. - - In this example, the LEDs are controlled and pins p21 to p24 are set as - InterruptIn and send messages out when their value changes. - - To use, hook up the MBed USB and open your fav terminal. All messages - end with the \n character, don't forget to hit carriage return!. - As an example:- - - to switch on LED1 send LED1:1\n, off is LED1:0\n and toggle is LED1:2\n - to switch on LED2 send LED2:1\n, off is LED2:0\n and toggle is LED2:2\n - to switch on LED3 send LED3:1\n, off is LED3:0\n and toggle is LED3:2\n - to switch on LED4 send LED4:1\n, off is LED4:0\n and toggle is LED4:2\n - - When a pin change on p21 to p24 happens, a message is sent. As an example - when p21 goes low PIN21:0\n is sent, when goes high PIN21:1\n is sent. - - Note, the InterruptIn pins p21 to p24 are setup to have pullups. This means - they are high. To activate them use a wire to short the pin to 0volts. - - If you find that p21 to p24 sent a lot of on/off/on/off then it's probably - due to "bounce". If you are connecting a mechanical switch to a pin you - may prefer to use the PinDetect library rather than using InterruptIn. - @see http://mbed.org/users/AjK/libraries/PinDetect/latest - - One point you may notice. Incoming messages are processed via main()'s - while(1) loop whereas pin changes have their messages directly sent. - The reason for this is when MODSERIAL makes callbacks to your application - it is in "interrupt context". And one thing you want to avoid is spending - lots of CPU time in that context. So, the callback moves the message from - the input buffer to a local holding buffer and it then sets a bool flag - which tells main()'s while(1) loop to process that buffer. This means the - time spent doing the real incoming message handing is within your program - and not within MODSERIAL's interrupt context. So you may ask, why not do - the same for out going messages? Well, because MODSERIAL output buffers - all your sent content then sending chars is very fast. MODSERIAL handles - all the nitty gritty bits for you. You can just send. This example uses - puts() to send the message. If you can, always try and use sprintf()+puts() - rathe than printf(), printf() is known to often screw things up when used - within an interrupt context. Better still, just use puts() and do away - with any of the crappy ?printf() calls if possible. But I found the code - below to work fine even at 115200baud. - -*/ - - -#ifdef COMPILE_EXAMPLE1_CODE_MODSERIAL - -#include "mbed.h" -#include "MODSERIAL.h" - -#define MESSAGE_BUFFER_SIZE 32 - -DigitalOut led1(LED1); -DigitalOut led2(LED2); -DigitalOut led3(LED3); -DigitalOut led4(LED4); - -InterruptIn P21(p21); -InterruptIn P22(p22); -InterruptIn P23(p23); -InterruptIn P24(p24); - -MODSERIAL messageSystem(USBTX, USBRX); - -char messageBufferIncoming[MESSAGE_BUFFER_SIZE]; -char messageBufferOutgoing[MESSAGE_BUFFER_SIZE]; -bool messageReceived; - -void messageReceive(MODSERIAL_IRQ_INFO *q) { - MODSERIAL *sys = q->serial; - sys->move(messageBufferIncoming, MESSAGE_BUFFER_SIZE); - messageReceived = true; - return 0; -} - -void messageProcess(void) { - if (!strncmp(messageBufferIncoming, "LED1:1", sizeof("LED1:1")-1)) led1 = 1; - else if (!strncmp(messageBufferIncoming, "LED1:0", sizeof("LED1:0")-1)) led1 = 0; - else if (!strncmp(messageBufferIncoming, "LED1:2", sizeof("LED1:2")-1)) led1 = !led1; - - else if (!strncmp(messageBufferIncoming, "LED2:1", sizeof("LED2:1")-1)) led2 = 1; - else if (!strncmp(messageBufferIncoming, "LED2:0", sizeof("LED2:0")-1)) led2 = 0; - else if (!strncmp(messageBufferIncoming, "LED2:2", sizeof("LED2:2")-1)) led2 = !led2; - - else if (!strncmp(messageBufferIncoming, "LED3:1", sizeof("LED3:1")-1)) led3 = 1; - else if (!strncmp(messageBufferIncoming, "LED3:0", sizeof("LED3:0")-1)) led3 = 0; - else if (!strncmp(messageBufferIncoming, "LED3:2", sizeof("LED3:2")-1)) led3 = !led3; - - else if (!strncmp(messageBufferIncoming, "LED4:1", sizeof("LED4:1")-1)) led4 = 1; - else if (!strncmp(messageBufferIncoming, "LED4:0", sizeof("LED4:0")-1)) led4 = 0; - else if (!strncmp(messageBufferIncoming, "LED4:2", sizeof("LED4:2")-1)) led4 = !led4; - - messageReceived = false; -} - -#define PIN_MESSAGE_SEND(x,y) \ - sprintf(messageBufferOutgoing,"PIN%02d:%d\n",x,y);\ - messageSystem.puts(messageBufferOutgoing); - -void pin21Rise(void) { PIN_MESSAGE_SEND(21, 1); } -void pin21Fall(void) { PIN_MESSAGE_SEND(21, 0); } -void pin22Rise(void) { PIN_MESSAGE_SEND(22, 1); } -void pin22Fall(void) { PIN_MESSAGE_SEND(22, 0); } -void pin23Rise(void) { PIN_MESSAGE_SEND(23, 1); } -void pin23Fall(void) { PIN_MESSAGE_SEND(23, 0); } -void pin24Rise(void) { PIN_MESSAGE_SEND(24, 1); } -void pin24Fall(void) { PIN_MESSAGE_SEND(24, 0); } - -int main() { - - messageReceived = false; - messageSystem.baud(115200); - messageSystem.attach(&messageReceive, MODSERIAL::RxAutoDetect); - messageSystem.autoDetectChar('\n'); - - // Enable pullup resistors on pins. - P21.mode(PullUp); P22.mode(PullUp); P23.mode(PullUp); P24.mode(PullUp); - - // Fix Mbed library bug, see http://mbed.org/forum/bugs-suggestions/topic/1498 - LPC_GPIOINT->IO2IntClr = (1UL << 5) | (1UL << 4) | (1UL << 3) | (1UL << 2); - - // Attach InterruptIn pin callbacks. - P21.rise(&pin21Rise); P21.fall(&pin21Fall); - P22.rise(&pin22Rise); P22.fall(&pin22Fall); - P23.rise(&pin23Rise); P23.fall(&pin23Fall); - P24.rise(&pin24Rise); P24.fall(&pin24Fall); - - while(1) { - // Process incoming messages. - if (messageReceived) messageProcess(); - } -} - -#endif
--- a/MODSERIAL/example3a.cpp Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,83 +0,0 @@ -/* - Copyright (c) 2011 Andy Kirkham - - 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. - - @file example3.cpp - @purpose Demos a simple filter. - @version see ChangeLog.c - @author Andy Kirkham -*/ - -/* - This example shows how to use the new callback system. In the old system - Mbed's FunctionPointer[1] type was used to store abd make calls to callbacks. - However, that limits the callback function prototype to void func(void); - which means we cannot pass parameters. - - This latest version of MODSERIAL now uses its own callback object. This allows - the passing of a pointer to a class that holds information about the MODSERIAL - object making the callback. As of version 1.18 one critcal piece of information - is passed, a pointer to the MODSERIAL object. This allows callbacks to use the - MODSERIAL functions and data. - - Additionally, since MODSERIAL and the callback parameter class MODSERIAL_IRQ_INFO - are friends, MODSERIAL_IRQ_INFO can access the protected functions of MODSERIAL. - This is used to ensure functions that can only be called during a callback - can be invoked from a callback. - - [1] http://mbed.org/projects/libraries/svn/mbed/trunk/FunctionPointer.h -*/ - -#ifdef COMPILE_EXAMPLE3_CODE_MODSERIAL - -#include "mbed.h" -#include "MODSERIAL.h" - -DigitalOut led1(LED1); - -MODSERIAL pc(USBTX, USBRX); - -// The following callback is defined in example3b.cpp -//! @see example3b.cpp -void rxCallback(MODSERIAL_IRQ_INFO *info); - -int main() { - - int life_counter = 0; - - pc.baud(115200); - - pc.attach(&rxCallback, MODSERIAL::RxIrq); - - while(1) { - // Echo back any chars we get except 'A' which is filtered by the rxCallback. - if (pc.readable()) { - pc.putc(pc.getc()); - } - - // Toggle LED1 every so often to show we are alive. - if (life_counter++ == 1000000) { - life_counter = 0; - led1 = !led1; - } - } -} - -#endif
--- a/MODSERIAL/example3b.cpp Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ -/* - Copyright (c) 2011 Andy Kirkham - - 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. - - @file example3b.cpp - @purpose Demos a simple filter. - @version see ChangeLog.c - @author Andy Kirkham -*/ - -/* - This example shows how to use the new callback system. In the old system - Mbed's FunctionPointer[1] type was used to store abd make calls to callbacks. - However, that limits the callback function prototype to void func(void); - which means we cannot pass parameters. - - This latest version of MODSERIAL now uses its own callback object. This allows - the passing of a pointer to a class that holds information about the MODSERIAL - object making the callback. As of version 1.18 one critcal piece of information - is passed, a pointer to the MODSERIAL object. This allows callbacks to use the - MODSERIAL functions and data. - - Additionally, since MODSERIAL and the callback parameter class MODSERIAL_IRQ_INFO - are friends, MODSERIAL_IRQ_INFO can access the protected functions of MODSERIAL. - This is used to ensure functions that can only be called during a callback - can be invoked from a callback. - - [1] http://mbed.org/projects/libraries/svn/mbed/trunk/FunctionPointer.h -*/ - - -#ifdef COMPILE_EXAMPLE3_CODE_MODSERIAL - -#include "mbed.h" -#include "MODSERIAL.h" - -void rxCallback(MODSERIAL_IRQ_INFO *info) { - - // Get the pointer to our MODSERIAL object that invoked this callback. - MODSERIAL *pc = info->serial; - - // info->serial points at the MODSERIAL instance so we can use it to call - // any of the public MODSERIAL functions that are normally available. So - // there's now no need to use the global version (pc in our case) inside - // callback functions. - char c = pc->rxGetLastChar(); // Where local pc variable is a pointer to the global MODSERIAL pc object. - - // The following is rather daft but demos the point. - // Don't allow the letter "A" go into the RX buffer. - // Basically acts as a filter to remove the letter "A" - // if it goes into the RX buffer. - if (c == 'A') { - // Note, we call the MODSERIAL_IRQ_INFO::rxDiscardLastChar() public function which - // is permitted access to the protected version of MODSERIAL::rxDiscardLastChar() - // within MODSERIAL (because they are friends). This ensures rxDiscardLastChar() - // can only be called within an rxCallback function. - info->rxDiscardLastChar(); - } -} - -#endif
--- a/MODSERIAL/example_dma.cpp Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,144 +0,0 @@ -#ifdef COMPILE_EXAMPLE_CODE_MODSERIAL_MODDMA - -/* - * To run this test program, link p9 to p10 so the Serial loops - * back and receives characters it sends. - */ - -#include "mbed.h" - -/* Note, this example requires that you also import into the Mbed - compiler the MODDMA project as well as MODSERIAL - http://mbed.org/users/AjK/libraries/MODDMA/latest - MODDMA.h MUST come before MODSERIAL.h */ -#include "MODDMA.h" // <--- Declare first -#include "MODSERIAL.h" // Flollowed by MODSERIAL - -DigitalOut led1(LED1); -DigitalOut led2(LED2); -DigitalOut led3(LED3); -DigitalOut led4(LED4); - -MODSERIAL pc(USBTX, USBRX); - -/* - * As experiement, you can define MODSERIAL as show here and see what - * effects it has on the LEDs. - * - * MODSERIAL uart(TX_PIN, RX_PIN, 512); - * With this, the 512 characters sent can straight into the buffer - * vary quickly. This means LED1 is only on briefly as the TX buffer - * fills. - * - * MODSERIAL uart(TX_PIN, RX_PIN, 32); - * With this, the buffer is smaller than the default 256 bytes and - * therefore LED1 stays on much longer while the system waits for - * room in the TX buffer. - */ -MODSERIAL uart(TX_PIN, RX_PIN); - -MODDMA dma; - -// This function is called when a character goes from the TX buffer -// to the Uart THR FIFO register. -void txCallback(void) { - led2 = !led2; -} - -// This function is called when TX buffer goes empty -void txEmpty(void) { - led2 = 0; - pc.puts(" Done. "); -} - -void dmaComplete(void) { - led1 = 1; -} - -// This function is called when a character goes into the RX buffer. -void rxCallback(void) { - led3 = !led3; - pc.putc(uart.getc()); -} - -int main() { - char s1[] = " *DMA* *DMA* *DMA* *DMA* *DMA* *DMA* *DMA* "; - int c = 'A'; - - // Tell MODSERIAL where the MODDMA controller is. - pc.MODDMA( &dma ); - - // Ensure the baud rate for the PC "USB" serial is much - // higher than "uart" baud rate below. - pc.baud( PC_BAUD ); - - // Use a deliberatly slow baud to fill up the TX buffer - uart.baud(1200); - - uart.attach( &txCallback, MODSERIAL::TxIrq ); - uart.attach( &rxCallback, MODSERIAL::RxIrq ); - uart.attach( &txEmpty, MODSERIAL::TxEmpty ); - - // Loop sending characters. We send 512 - // which is twice the default TX/RX buffer size. - - led1 = 0; - - // Send the buffer s using DMA channel 7 - pc.attach_dmaSendComplete( &dmaComplete ); - pc.dmaSend( s1, sizeof(s1), MODDMA::Channel_7 ); - - for (int loop = 0; loop < 512; loop++) { - uart.printf("%c", c); - c++; - if (c > 'Z') c = 'A'; - } - - led1 = 0; // Show the end of sending by switching off LED1. - - // End program. Flash LED4. Notice how LED 2 and 3 continue - // to flash for a short period while the interrupt system - // continues to send the characters left in the TX buffer. - - while(1) { - led4 = !led4; - wait(0.25); - } -} - -/* - * Notes. Here is the sort of output you can expect on your PC/Mac/Linux host - * machine that is connected to the "pc" USB serial port. - * - * *DMA* *DMA* *DMA* *DMA* *DMA* *DMA* *DMA* ABCDEFGHIJKLMNOPQRSTUVWXYZABCDE - * FGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZA - * BCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVW - * XYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRS - * TUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNO - * PQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJK - * LMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFG - * HIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQ Done. R - * - * Note how the DMA blocks the TX buffer sending under standard interrupt control. - * Not until the DMA transfer is complete will "normal" buffered TX sending resume. - * - * Of interest is that last "R" character after the system has said "Done." - * This comes from the fact that the TxEmpty callback is made when the TX buffer - * becomes empty. MODSERIAL makes use of the fact that the Uarts built into the - * LPC17xx device use a 16 byte FIFO on both RX and TX channels. This means that - * when the TxEmpty callback is made, the TX buffer is empty, but that just means - * the "last few characters" were written to the TX FIFO. So although the TX - * buffer has gone empty, the Uart's transmit system is still sending any remaining - * characters from it's TX FIFO. If you want to be truely sure all the characters - * you have sent have left the Mbed then call txIsBusy(); This function will - * return true if characters are still being sent. If it returns false after - * the Tx buffer is empty then all your characters have been sent. - * - * In a similar way, when characters are received into the RX FIFO, the entire - * FIFO contents is moved to the RX buffer, assuming there is room left in the - * RX buffer. If there is not, any remaining characters are left in the RX FIFO - * and will be moved to the RX buffer on the next interrupt or when the running - * program removes a character(s) from the RX buffer with the getc() method. - */ - -#endif
--- a/OEM615.h Fri Mar 22 01:33:24 2013 +0000 +++ b/OEM615.h Fri Mar 29 20:52:24 2013 +0000 @@ -7,7 +7,7 @@ char synch44; //2nd synch word char synch12; //3rd synch word unsigned char headerLength; //always 28 - unsigned short messageID; + unsigned short messageID; //42 (BESTPOS) , 43 (RANGE) , or 99 (BESTVEL), char messageType; //always = 0 for binary unsigned char portAddress; //0x20 for COM1 unsigned short messageLength; //not including header or CRC
--- a/main.cpp Fri Mar 22 01:33:24 2013 +0000 +++ b/main.cpp Fri Mar 29 20:52:24 2013 +0000 @@ -11,6 +11,8 @@ #include "ADIS16488.h" #include <string> +//these are defines for the messages that are sent from the PC across the USB +//these messages produce reactions on the mbed #define STATUS_MSG 0 #define POSVEL_MSG 1 #define STARTDATA_MSG 2 @@ -19,33 +21,39 @@ #define STOPSTREAM_MSG 5 #define STARTLOGINFO_MSG 6 #define STOPLOGINFO_MSG 7 + #define DEGREES_TO_RADIANS (3.14519/180.0) -//general items for this application +//general digital I/O specifications for this application //SDFileSystem(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name); SDFileSystem sd(p11,p12,p13,p14,"sd"); //Serial debug(USBTX, USBRX); // tx, rx USB communication to the PC for debug purposes -DigitalOut ppsled(LED1); -DigitalOut trig1led(LED2); -DigitalOut recordDataled(LED4); -InterruptIn camera1Int(p30); -DigitalOut camera2Pin(p29); +DigitalOut ppsled(LED1); //blink an LED at the 1PPS +DigitalOut trig1led(LED2); //blink an LED at the camera trigger detection +DigitalOut recordDataled(LED4); //set the led when the record is on +InterruptIn camera1Int(p30); // camera interrupt in +DigitalOut camera2Pin(p29); // i dont believe we use the second camera interrupt //USB serial data stream back to the PC Serial toPC(USBTX, USBRX); //connect the GPS TX, RX to p9 and p10 -bool detectedGPS1PPS = false; -bool recordData = false; -int PPSCounter = 0; -int byteCounter = 0; -unsigned short perSecMessageCounter=0; -bool lookingForMessages = true; -bool messageDetected = false; -int savedIMUClockCounter=0; +bool detectedGPS1PPS = false; //flag set in the ISR and reset after processing the 1PPS event +bool recordData = false; //set to true when commanded from the PC +int PPSCounter = 0; //counts the 1PPS occurrences +int byteCounter = 0; //byte counter -- where used?? +unsigned short perSecMessageCounter=0; //counts the number of messages in a sec based on the header detection +bool lookingForMessages = true; //set in the PPS ISR and set false after the message processing in the main +bool messageDetected = false; //have detected a message header +int savedIMUClockCounter=0; +unsigned long IMUbytesWritten = 0; +int savedByteCounter = 0; +int savedPerSecMessageCounter=0; int IMUClockCounter = 0; bool camera1EventDetected = false; double camera1Time; char serBuf[128]; int serBufChars=0; + +//flags to control the PC command actions bool sendPosVel=false; bool sendStatus=false; bool sendRecData=false; @@ -54,41 +62,69 @@ bool logMsgInfo=false; bool sendLogMsgInfo=false; - //ISR for detection of the GPS 1PPS void detect1PPSISR(void) { - timeFromPPS.reset(); - savedIMUClockCounter = IMUClockCounter; - IMUClockCounter = 0; - GPS_COM1.rxBufferFlush(); + timeFromPPS.reset(); //reset the 1PPS timer upon 1PPS detection + savedIMUClockCounter = IMUClockCounter; //number of IMU clocks received since last 1PPS + savedByteCounter = byteCounter; + savedPerSecMessageCounter = perSecMessageCounter; + IMUClockCounter = 0; //counts number of IMU samples between 1PPS events + GPS_COM1.rxBufferFlush(); //flush the GPS serial buffer -- likely not needed but OK + byteCounter = 0; + perSecMessageCounter = 0; - detectedGPS1PPS = true; - lookingForMessages = true; - PPSCounter++; - PPSTimeOffset++; - ppsled = !ppsled; + detectedGPS1PPS = true; //reset in the main when 1PPS actions are complete + lookingForMessages = true; //means we should begin looking for new GPS messages + PPSCounter++; //count number of 1PPS epochs + PPSTimeOffset++; //counts the 1PPS events between occurrences when we have matching POS and VEL messages + ppsled = !ppsled; //blink an LED at the 1PPS }; //ISR for detection of the hotshoe trigger 1 void camera1ISR(void) { + //PPSTimeOffset keeps track of missed camera1Time = GPSTime + (double)PPSTimeOffset + timeFromPPS.read(); - trig1led = !trig1led; - camera1EventDetected = true; + + trig1led = !trig1led; //blink an LEWD at the camera event detection + camera1EventDetected = true; //reset to false in main after processing the image detection }; void readFromPC() { + + //better solution + //start a timer when we get a char from the PC and set a bool: detectingPCMessage = true + //keep reading bytes until elapsed time from the first byte is : 0.01 secs of numByes > 16 + //the messages are from 10 to 16 bytes -- this will take from 10/921600 to 16/921600 secs at 921600 baud + //8*115200 = 921600 + //this is about 2e-5 or 20usec. + //so we could wait 50usec from the first char reeived and be certain we had all the chars for a message. + //the steps are below .... + //(1) convert this procedures to a ISR per byte + //(2) in the ISR, start the timer on the first byte received when !detectingPCMessage + //(3) set detectingPCMessage = true + //(4) in the main loop, test the timer for >50usec and parse the bytes to test fr a message + //(5) reset the timer to zero in the main loop after parsing the message + //(6) set detectingPCMessage = false; + + //The received commands obnly occur at the initialization stage -- time is not that critical there. + //during the real-time action, we will never pass the followong if test ( no characters received) if (toPC.readable()) //read a PC serial byte and test it for a command { // Read in next character char inChar = toPC.getc(); serBuf[serBufChars++] = inChar; + // Append end of string character + //why do this for every character we read? + //answer: we always assume we have a complete message and test for this below serBuf[serBufChars] = '\0'; + // Need to parse message to determine behavior // Need to clean this up + //need to do this outside the read byte --- char msgList[8][32]; sprintf(msgList[STATUS_MSG], "WMsg STATUS"); sprintf(msgList[POSVEL_MSG], "WMsg POSVEL"); @@ -98,16 +134,19 @@ sprintf(msgList[STOPSTREAM_MSG], "WMsg POSSTREAM N"); sprintf(msgList[STARTLOGINFO_MSG], "WMsg LOGINFO Y"); sprintf(msgList[STOPLOGINFO_MSG], "WMsg LOGINFO N"); + //message length is from 10 to 16 chars + // assume an invalid message which needs to be reset bool validMessage = false; bool resetMessage = true; + // Check for valid message - for (int m = 0; m < 8 && !validMessage; m++) + for (int m = 0; m < 8 && !validMessage; m++) //check for all messages ... { if (strncmp(serBuf, msgList[m], serBufChars) == 0) { validMessage = true; - // buffer length is same as message length + //test that chars in the serial buffer is same as message length if (serBufChars == strlen(msgList[m])) { switch(m) @@ -143,6 +182,7 @@ } } } + // if message should be reset if (resetMessage) { @@ -154,7 +194,7 @@ { // start a new message serBuf[serBufChars++] = inChar; - serBuf[serBufChars] == '\0'; + serBuf[serBufChars] = '\0'; } // Append end of string character serBuf[serBufChars] = '\0'; @@ -164,6 +204,10 @@ void sendASCII(char* ASCI_message, int numChars) { + ///////////////////////////////////////////////// + //send an ASCII command to the GPS receiver + ///////////////////////////////////////////////// + //char ASCI_message[] = "unlogall COM1"; int as = numChars - 1; unsigned char CR = 0x0d; //ASCII Carriage Return @@ -195,7 +239,7 @@ //toPC.baud(1*115200); wait_ms(100); toPC.printf("\n\n released GPS from RESET and set to high baud rate \n\n"); - //just wait to lauinch the GPS receiver + //just wait to launch the GPS receiver for (int i=0; i<5; i++) { toPC.printf(" to start: %3d \n", 4-i); wait(1); } @@ -210,29 +254,36 @@ else toPC.printf(" opened the IMUGPS data file \n"); */ - + + //NOTE: we do not assume that the GPS receiver has been pre-set up for the WALDO_FCS functionality + //we alwsys start with a reset and reprogram the receiver with our data out products + // this prevents failure because of a blown NVRAM as occurred for the older camera systems + //this is the COM1 port from th GPS receiuver to the mbed //it should be always started at 9600 baud because thats the default for the GPS receiver GPS_COM1.baud(9600); wait_ms(100); // this ASCII command sets up the serial data from the GPS receiver on its COM1 char ch7[] = "serialconfig COM1 9600 n 8 1 n off"; - // this is a software reset and has the same effect as a hardware reset (why do it??) - char ch0[] = "RESET"; + // this is a software reset and has the same effect as a hardware reset (why do it?) + //char ch0[] = "RESET"; //this command stops all communication from the GPS receiver on COM1 - //logs should still be presented on USB port so the CDU can be used in parallel + //logs should still be presented on USB port so the Novatel CDU application can be used on the PC in parallel char ch1[] = "unlogall COM1"; //set the final baud rate that we will use from here //allowable baud rate values: 9600 115200 230400 460800 921600 - char ch2[] = "serialconfig COM1 921600 n 8 1 n off"; + //char ch2[] = "serialconfig COM1 921600 n 8 1 n off"; + char ch2[] = "serialconfig COM1 460800 n 8 1 n off"; //the below commands request the POS, VEL, RANGE, and TIME messages char ch3[] = "log COM1 BESTPOSB ONTIME 1"; //messageID = 42 char ch4[] = "log COM1 BESTVelB ONTIME 1"; //messageID = 99 char ch5[] = "log COM1 RANGEB ONTIME 1"; //messageID = 43 - char ch6[] = "log COM1 TIMEB ONTIME 1"; //messageID = 101 + //char ch6[] = "log COM1 TIMEB ONTIME 1"; //messageID = 101 //set up VARF to be 100Hz with 1X10^4 * 10^-8 = 10^-4 sec (10usec) pulse width + //in fact, we do not use this output but it is available. + //originally planned to use this to command the IMU data char ch8[] = "FREQUENCYOUT enable 10000 1000000"; toPC.printf("set serial config \n"); @@ -259,7 +310,8 @@ //set the mbed COM port to match the GPS transmit rate //the below baud rate must match the COM1 rate coming from the GPS receiver - GPS_COM1.baud(921600); wait_ms(500); //without this wait -- the baud rate is not detected when using MODSERIAL + GPS_COM1.baud(460800); wait_ms(500); //without this wait -- the baud rate is not detected when using MODSERIAL + //GPS_COM1.baud(921600); wait_ms(500); //without this wait -- the baud rate is not detected when using MODSERIAL }; void setupTriggers() @@ -274,8 +326,8 @@ int test = 0; unsigned short messageCounter = 0; unsigned short savedMessageCounter = 0; -unsigned char msgBuffer[1536]; -unsigned short messageLocation[6] = {0}; +unsigned char msgBuffer[1536]; //array to contain one full second of GPS bytes +unsigned short messageLocation[6] = {0}; //stores the message location start within the message buffer //see the mbed COOKBOOK for MODSERIAL //MODSERIAL is an easy to use library that extends Serial to add fully buffered input and output. @@ -296,19 +348,41 @@ perSecMessageCounter++; messageDetected = true; } + //byteCounter reset to zero in main after the 1PPS is detected -- its NOT reset in the 1PPS ISR byteCounter++; //total per-sec byte counter (reset to zero in main when 1PPS detected) }; +void earthCoefficients(double latitudeRad, double longitudeRad, double height, double &latRateFac, double &lonRateFac) +{ + //compute the lat and lon factors for use in the interpolation of the lat and lon between 1 sec epochs + //see this document (page 32) www.fas.org/spp/military/program/nav/basicnav.pdf + double eccen = 0.0818191908426; //WGS84 earth eccentricity + double earthRadius = 6378137; //WGS84 earthRadius in meters + double eccenSinLat = eccen * sin(latitudeRad); + double temp1 = 1.0 - eccenSinLat*eccenSinLat; + double temp2 = sqrt(temp1); + double r_meridian = earthRadius * ( 1.0 - eccen*eccen)/ (temp1 * temp2); + double r_normal = earthRadius / temp2; + + //multiply latRateFac times V-north to get the latitude rate in radians [er sec + latRateFac = 1.0 / (r_meridian + height); + + //multiply lonRatFac by VEast to get the longitude rate in radians per sec + lonRateFac = 1.0 / ( (r_normal + height) * cos(latitudeRad) ); +} + int main() { //FILE *fpIMU = NULL; //FILE *fpGPS = NULL; FILE *fpNav = NULL; - OEM615BESTPOS posMsg; - OEM615BESTPOS curPos; - OEM615BESTVEL velMsg; - OEM615BESTVEL curVel; + + OEM615BESTPOS posMsg; //BESTPOS structure in OEMV615.h + OEM615BESTPOS curPos; //BESTPOS structure in OEMV615.h + OEM615BESTVEL velMsg; //BESTVEL structure in OEMV615.h + OEM615BESTVEL curVel; //BESTVEL structure in OEMV615.h + int msgLen; int msgEnd; @@ -320,45 +394,62 @@ //setup Hotshoe setupTriggers(); + //attempt to use the mbed RTOS library //Thread thread(writeThread); + //this doesnt show up on the PC Rich Text Box because we dont start the init til after this occurs toPC.printf("completed setting up COM ports \n"); - //set up the interrupt to catch the serial byte availability + //set up the interrupt to catch the GPS receiver serial bytes as they are presented GPS_COM1.attach(&readSerialByte, MODSERIAL::RxIrq); - timeFromPPS.start(); + timeFromPPS.start(); //start the time for measuring time from 1PPS events - //while(PPSCounter < 1000) - while(1) + while(PPSCounter < 100) + /////////////////////////////////////////////////////////////////////////// + // top of the while loop + /////////////////////////////////////////////////////////////////////////// + //while(1) { //read the USB serial data from the PC to check for commands + //in the primary real-time portion, there are no bytes from the PC so this has no impact readFromPC(); - if (sendPosVel) + //we should put the below stuff into the readPC() procedure. + //only do these actions in response to a command so no need for the tests w/o an inoput byte from the PC + //perform the activities as a response to the commands + if (sendPosVel) //true if we want to return a position solution { - sendPosVel=false; + sendPosVel=false; //set to true if a POSVEL is requested from the PC char solReady = 'N'; - if (posMsg.solStatus == 0) + if (posMsg.solStatus == 0) //how is this set?? { solReady = 'Y'; } + + //north and east velocity from the horizontal speed and heading + //velMsg may not be the "current" message --- but is the one also associated with a position message double nVel = velMsg.horizontalSpeed*cos(velMsg.heading*DEGREES_TO_RADIANS); double eVel = velMsg.horizontalSpeed*sin(velMsg.heading*DEGREES_TO_RADIANS); + // For the 1 second deltas with which we are dealing - // this calculation should be close enough for now - // approximately 1 nautical mile / minute latitude, 60 minutes/degree, 1852 meters/nautical mile + // This calculation should be close enough for now + // Approximately 1 nautical mile / minute latitude, 60 minutes/degree, 1852 meters/nautical mile double latMetersPerDeg = 60.0*1852.0; // longitude separation is approximately equal to latitude separation * cosine of latitude double lonMetersPerDeg = latMetersPerDeg*cos(posMsg.latitude*DEGREES_TO_RADIANS); // Elapsed time since last known GPS position + //PPSTimeOffset is a result of possibly missing a prior GPS position message + // timeFromPPS.read() is always the time from the moset recent 1PPS double elTime = (double)PPSTimeOffset + timeFromPPS.read(); - // Position time + + // Position time -- GPSTime is the time of the last valid GPS position message double posTime = GPSTime + elTime; // Estimated position based on previous position and velocity + // posMsg is the last time when the BESTVEL and BESTPOS messages had identical times double latPos = posMsg.latitude + (nVel/latMetersPerDeg)*elTime; double lonPos = posMsg.longitude + (eVel/lonMetersPerDeg)*elTime; double htPos = posMsg.height + velMsg.verticalSpeed/(60*1852)*elTime; @@ -374,7 +465,9 @@ velMsg.verticalSpeed ); } - if (sendStatus) + + //all this does is assess the GPS convergence -- really available in the above + if (sendStatus) //send the status message to the PC { sendStatus=false; char solReady = 'N'; @@ -387,7 +480,9 @@ solReady ); } - if (sendRecData) + + //should just record ALL the data -- can pck over it in the post-processing + if (sendRecData) //begin to (or stop) record the serial data { sendRecData=false; char recChar = 'N'; @@ -427,8 +522,11 @@ recChar ); } - recordDataled = recordData; - if (sendStreamPos) + + //this is called everytime through the loop -- wasteful + //recordDataled = recordData; + + if (sendStreamPos) //stream the position data to the PC { sendStreamPos=false; char streamChar = 'N'; @@ -440,7 +538,9 @@ streamChar ); } - if (sendLogMsgInfo) + + //not sure this is ever used .. + if (sendLogMsgInfo) //send log info to the PC { sendLogMsgInfo=false; char logChar = 'N'; @@ -452,95 +552,32 @@ logChar ); } - if (IMUDataReady) - { - //write the IMU data - //if (recordData && (fpIMU != NULL)) - if (recordData && (fpNav != NULL)) + + + //////////////////////////////////////////////////////////////////////////// + //below is where we process the complete stored GPS message for the second + //The !IMUDataReady test prevents the IMU and GPS data from being written + //to disk on the same pass through thi loop + ///////////////////////////////////////////////////////////////////////////// + if (!IMUDataReady && lookingForMessages && (timeFromPPS.read_us() > 20000)) //it takes less than 20msec to receive all messages + { + toPC.printf(" num messages = %3d time = %5d \n", perSecMessageCounter, timeFromPPS.read_us()); + + //cycle through all the bytes stored this sec (after the 1PPS as set) + // perSecMessageCounter is incremented whenever we detect a new message headet 0xAA44121C sequence + for (int i=0; i<perSecMessageCounter; i++) { - fwrite(imuRec.dataWord, sizeof(IMUREC), 1, fpNav); - } - IMUDataReady = false; - } - //if (lookingForMessages && (timeFromPPS.read() > 0.100)) //it takes less than 20msec to receive all messages - { - - //toPC.printf(" num messages = %3d time = %5d \n", perSecMessageCounter, timeFromPPS.read_us()); - for (int i=0; i<perSecMessageCounter; i++) - { - // ensure at message header has arrived before processing - if (byteCounter < (messageLocation[i] + sizeof(MESSAGEHEADER))) + msgHeader[i] = (MESSAGEHEADER*)&msgBuffer[messageLocation[i]]; + toPC.printf("WMsg MESSAGEINFO %5d %5d \n", + msgHeader[i]->messageID, + messageLocation[i]); + //test for a message 42 (BESTPOS) + if (msgHeader[i]->messageID == 42) { - // Complete message header has not been received. - // Clear processed messages and break out of message processing loop - for (int j = 0; j < i; j++) - { - messageLocation[j] = messageLocation[i+j]; - perSecMessageCounter--; - } - break; - } - msgHeader[i] = (MESSAGEHEADER*)&msgBuffer[messageLocation[i]]; - // Ensure complete message has been received - // Message length is header length + message length + CRC - msgLen = 28; - switch (msgHeader[i]->messageID) - { - case 42: - msgLen = 104; - break; - case 99: - msgLen = 76; - break; - default: - msgLen = msgHeader[i]->headerLength + msgHeader[i]->messageLength + sizeof(unsigned long); - break; + curPos = *((OEM615BESTPOS*)&msgBuffer[messageLocation[i]]); - } - msgLen = msgHeader[i]->headerLength + msgHeader[i]->messageLength + sizeof(unsigned long); - // Find last byte position of message - msgEnd = messageLocation[i] + msgLen; - if (byteCounter < msgEnd) - { - // Complete message has not been received. - // Clear processed messages and break out of message processing loop - for (int j = 0; j < i; j++) + if (streamPos) { - messageLocation[j] = messageLocation[i+j]; - perSecMessageCounter--; - } - break; - } - else if ((i < (perSecMessageCounter-1)) && - (messageLocation[i+i] < msgEnd)) // ignore CRC for now - { - // Next message was started before this mesage was completely received. - // Ignore and continue on to the next message - continue; - } - if (logMsgInfo) - { - toPC.printf("WMsg MESSAGEINFO %5d %5d %5d %5d %5d = %5d (%5d)\n", - msgHeader[i]->messageID, - messageLocation[i], - msgHeader[i]->headerLength, - msgHeader[i]->messageLength, - sizeof(unsigned long), - msgEnd, - byteCounter); - } - //toPC.printf(" %5d ", msgHeader[i]->messageID); - if ((msgHeader[i]->messageID == 42) || - (msgHeader[i]->messageID == 99)) - { - if (msgHeader[i]->messageID == 42) - { - // Wait until velocity message has also been received before using as - // base position - //memcpy(&curPos, &msgBuffer[messageLocation[i]], sizeof(OEM615BESTPOS)); - curPos = *((OEM615BESTPOS*)&msgBuffer[messageLocation[i]]); - if (streamPos) - { toPC.printf("WMsg BESTPOS %d %d %d %8.5lf %9.5lf %5.3lf %5.3f %5.3f %5.3f %5.3f %5.3f %5.3f %d %d %d %d %d\n", curPos.msgHeader.GPSTime_msecs, curPos.solStatus, @@ -559,69 +596,86 @@ curPos.numGGL1, curPos.extSolStatus, curPos.sigMask); - } - } - else if (msgHeader[i]->messageID == 99) - { - // Wait until position message has also been received before using as - // base position - //memcpy(&curVel, &msgBuffer[messageLocation[i]], sizeof(OEM615BESTVEL)); - curVel = *((OEM615BESTVEL*)&msgBuffer[messageLocation[i]]); - } - if ((curVel.msgHeader.GPSTime_msecs+250)/1000 == - (curPos.msgHeader.GPSTime_msecs+250)/1000) - { - // update position and velocity used for calculation - GPSTimemsecs = curPos.msgHeader.GPSTime_msecs; - GPSTime = (double)GPSTimemsecs/1000.0; - velMsg = curVel; - posMsg = curPos; - PPSTimeOffset = 0; } } - if (i == (perSecMessageCounter-1)) + + //check for a message 99 (BESTVEL) -- and cast it into its message structure + else if (msgHeader[i]->messageID == 99) + { + curVel = *((OEM615BESTVEL*)&msgBuffer[messageLocation[i]]); + } + + //the below test ensures that the positin and veocity are matched in time + //not sure the reason for the "250" below + if ((curVel.msgHeader.GPSTime_msecs+250)/1000 == + (curPos.msgHeader.GPSTime_msecs+250)/1000) { - if (recordData && (fpNav != NULL)) - { - fwrite(msgBuffer, byteCounter, 1, fpNav); - } - byteCounter = 0; - perSecMessageCounter = 0; + // update position and velocity used for calculation + GPSTimemsecs = curPos.msgHeader.GPSTime_msecs; + GPSTime = (double)GPSTimemsecs/1000.0; + velMsg = curVel; // + posMsg = curPos; + + ///////////////////////////////////////////////////////////////////////////////////////// + //IMPORTANT: we reset the PPSTimeOffset when we have a matching position and velocity + PPSTimeOffset = 0; + ///////////////////////////////////////////////////////////////////////////////////////// } - } - //toPC.printf(" %3d %8d \n", msgHeader[0]->timeStatus, GPSTimemsecs); - //if (recordData && (fpGPS != NULL)) - - /* + } + lookingForMessages = false; + + } //end of the GPS message processing + + //the IMU data record is read from the SPI in the ISR and the IMUDataReady is set true + //we write the IMU data here + if (IMUDataReady) //IMUDataReady is true if we have a recent IMU data record + { + imuRec.GPSTime = GPSTimemsecs + timeFromPPS.read_us()/1000000.0; + spi.write((int) HIGH_REGISTER[0]); // next read will return results from HIGH_REGITER[0] + for (int i=0; i<6; i++) //read the 6 rate and accel variables + { + wd.pt[1] = (unsigned short)spi.write((int) LOW_REGISTER[i]) ; + if (i<5) // dont this on the last because this was pre-called + { wd.pt[0] = (unsigned short)spi.write((int) HIGH_REGISTER[i+1]); } + imuRec.dataWord[i] = wd.dataWord; //data word is a signed long + + } + IMURecordCounter++; + //write the IMU data + //if (recordData && (fpIMU != NULL)) if (recordData && (fpNav != NULL)) { - fwrite(msgBuffer, byteCounter, 1, fpNav); + IMUbytesWritten += fwrite(imuRec.dataWord, sizeof(IMUREC), 1, fpNav); } - */ - //lookingForMessages = false; + IMUClockCounter++; + IMUDataReady = false; } - if (messageDetected) + + if (messageDetected) //some GPS message header has been detected { - //toPC.printf(" msgTime = %4d \n", timeFromPPS.read_us()); + toPC.printf(" msgTime = %4d \n", timeFromPPS.read_us()); messageDetected = false; } - if (camera1EventDetected) + + if (camera1EventDetected) //we have detected a camera trigger event { toPC.printf("WMsg TRIGGERTIME %5.3lf\n", camera1Time); camera1EventDetected = false; } - if (detectedGPS1PPS) + + if (detectedGPS1PPS) //true if we are exactly at a 1PPS event detection { - //toPC.printf(" PPSCounter = %4d byteCounter = %10d num Messages Received = %3d IMUClock = %4d\n", - // PPSCounter, byteCounter, perSecMessageCounter, savedIMUClockCounter); + toPC.printf(" PPSCounter=%4d byteCounter=%10d Msgs Received=%3d IMUClock=%4d bytesWritten=%8d\n", + PPSCounter, savedByteCounter, savedPerSecMessageCounter, savedIMUClockCounter, IMUbytesWritten); if (recordData && (fpNav != NULL) && (byteCounter > 0)) { - fwrite(msgBuffer, byteCounter, 1, fpNav); + // we know that we are not reading a GPS message at exactly the 1PPS occurrence + fwrite(msgBuffer, byteCounter, 1, fpNav); // this writes out a complete set of messages for ths sec } - byteCounter = 0; - perSecMessageCounter=0; detectedGPS1PPS = false; } } + + fclose(fpNav); toPC.printf(" normal termination \n"); } \ No newline at end of file
--- a/mbed-rtos/rtos.lib Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/mbed_official/code/rtos/#68e146c0e76b
--- a/mbed-rtos/rtos/Mail.h Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +0,0 @@ -/* Copyright (c) 2012 mbed.org */ -#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 -
--- a/mbed-rtos/rtos/MemoryPool.h Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -/* Copyright (c) 2012 mbed.org */ -#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
--- a/mbed-rtos/rtos/Mutex.cpp Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -#include "Mutex.h" - -#include <string.h> -#include "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); -} - -}
--- a/mbed-rtos/rtos/Mutex.h Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* Copyright (c) 2012 mbed.org */ -#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
--- a/mbed-rtos/rtos/Queue.h Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -/* Copyright (c) 2012 mbed.org */ -#ifndef QUEUE_H -#define QUEUE_H - -#include <stdint.h> -#include <string.h> - -#include "cmsis_os.h" -#include "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
--- a/mbed-rtos/rtos/RtosTimer.cpp Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -#include "RtosTimer.h" - -#include <string.h> - -#include "cmsis_os.h" -#include "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); -} - -}
--- a/mbed-rtos/rtos/RtosTimer.h Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/* Copyright (c) 2012 mbed.org */ -#ifndef TIMER_H -#define 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
--- a/mbed-rtos/rtos/Semaphore.cpp Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +0,0 @@ -#include "Semaphore.h" - -#include <string.h> -#include "error.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); -} - -}
--- a/mbed-rtos/rtos/Semaphore.h Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* Copyright (c) 2012 mbed.org */ -#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
--- a/mbed-rtos/rtos/Thread.cpp Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -#include "Thread.h" - -#include <stdlib.h> - -#include "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; - if (stack_pointer != NULL) { - _thread_def.stack_pointer = stack_pointer; - } else { - _thread_def.stack_pointer = (unsigned char*) malloc(stack_size); - if (_thread_def.stack_pointer == NULL) - error("Error allocating the stack memory"); - } -#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); -} - -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(); -} - -}
--- a/mbed-rtos/rtos/Thread.h Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -/* Copyright (c) 2012 mbed.org */ -#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); - - /*! 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(); - -private: - osThreadId _tid; - osThreadDef_t _thread_def; -}; - -} -#endif
--- a/mbed-rtos/rtos/rtos.h Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,17 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2012 ARM Limited. All rights reserved. - */ -#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
--- a/mbed-rtos/rtx.lib Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/mbed_official/code/rtx/#77454ed243ca
--- a/mbed-rtos/rtx/HAL_CM.c Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,170 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: HAL_CM.C - * Purpose: Hardware Abstraction Layer for Cortex-M - * Rev.: V4.50 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_HAL_CM.h" - - -/*---------------------------------------------------------------------------- - * Global Variables - *---------------------------------------------------------------------------*/ - -#ifdef DBG_MSG -BIT dbg_msg; -#endif - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_init_stack ---------------------------------*/ - -void rt_init_stack (P_TCB p_TCB, FUNCP task_body) { - /* Prepare TCB and saved context for a first time start of a task. */ - U32 *stk,i,size; - - /* Prepare a complete interrupt frame for first task start */ - size = p_TCB->priv_stack >> 2; - - /* Write to the top of stack. */ - stk = &p_TCB->stack[size]; - - /* Auto correct to 8-byte ARM stack alignment. */ - if ((U32)stk & 0x04) { - stk--; - } - - stk -= 16; - - /* Default xPSR and initial PC */ - stk[15] = INITIAL_xPSR; - stk[14] = (U32)task_body; - - /* Clear R4-R11,R0-R3,R12,LR registers. */ - for (i = 0; i < 14; i++) { - stk[i] = 0; - } - - /* Assign a void pointer to R0. */ - stk[8] = (U32)p_TCB->msg; - - /* Initial Task stack pointer. */ - p_TCB->tsk_stack = (U32)stk; - - /* Task entry point. */ - p_TCB->ptask = task_body; - - /* Set a magic word for checking of stack overflow. - For the main thread (ID: 0x01) the stack is in a memory area shared with the - heap, therefore the last word of the stack is a moving target. - We want to do stack/heap collision detection instead. - */ - if (p_TCB->task_id != 0x01) - p_TCB->stack[0] = MAGIC_WORD; -} - - -/*--------------------------- rt_ret_val ----------------------------------*/ - -static __inline U32 *rt_ret_regs (P_TCB p_TCB) { - /* Get pointer to task return value registers (R0..R3) in Stack */ -#if (__TARGET_FPU_VFP) - if (p_TCB->stack_frame) { - /* Extended Stack Frame: R4-R11,S16-S31,R0-R3,R12,LR,PC,xPSR,S0-S15,FPSCR */ - return (U32 *)(p_TCB->tsk_stack + 8*4 + 16*4); - } else { - /* Basic Stack Frame: R4-R11,R0-R3,R12,LR,PC,xPSR */ - return (U32 *)(p_TCB->tsk_stack + 8*4); - } -#else - /* Stack Frame: R4-R11,R0-R3,R12,LR,PC,xPSR */ - return (U32 *)(p_TCB->tsk_stack + 8*4); -#endif -} - -void rt_ret_val (P_TCB p_TCB, U32 v0) { - U32 *ret; - - ret = rt_ret_regs(p_TCB); - ret[0] = v0; -} - -void rt_ret_val2(P_TCB p_TCB, U32 v0, U32 v1) { - U32 *ret; - - ret = rt_ret_regs(p_TCB); - ret[0] = v0; - ret[1] = v1; -} - - -/*--------------------------- dbg_init --------------------------------------*/ - -#ifdef DBG_MSG -void dbg_init (void) { - if ((DEMCR & DEMCR_TRCENA) && - (ITM_CONTROL & ITM_ITMENA) && - (ITM_ENABLE & (1UL << 31))) { - dbg_msg = __TRUE; - } -} -#endif - -/*--------------------------- dbg_task_notify -------------------------------*/ - -#ifdef DBG_MSG -void dbg_task_notify (P_TCB p_tcb, BOOL create) { - while (ITM_PORT31_U32 == 0); - ITM_PORT31_U32 = (U32)p_tcb->ptask; - while (ITM_PORT31_U32 == 0); - ITM_PORT31_U16 = (create << 8) | p_tcb->task_id; -} -#endif - -/*--------------------------- dbg_task_switch -------------------------------*/ - -#ifdef DBG_MSG -void dbg_task_switch (U32 task_id) { - while (ITM_PORT31_U32 == 0); - ITM_PORT31_U8 = task_id; -} -#endif - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/mbed-rtos/rtx/LPC11U24/GCC_ARM/HAL_CM0.s Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,370 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: HAL_CM0.S - * Purpose: Hardware Abstraction Layer for Cortex-M0 - * Rev.: V4.50 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - - .file "HAL_CM0.S" - .syntax unified - - .equ TCB_TSTACK, 36 - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - .thumb - - .section ".text" - .align 2 - - -/*--------------------------- rt_set_PSP ------------------------------------*/ - -# void rt_set_PSP (U32 stack); - - .thumb_func - .type rt_set_PSP, %function - .global rt_set_PSP -rt_set_PSP: - .fnstart - .cantunwind - - MSR PSP,R0 - BX LR - - .fnend - .size rt_set_PSP, .-rt_set_PSP - - -/*--------------------------- rt_get_PSP ------------------------------------*/ - -# U32 rt_get_PSP (void); - - .thumb_func - .type rt_get_PSP, %function - .global rt_get_PSP -rt_get_PSP: - .fnstart - .cantunwind - - MRS R0,PSP - BX LR - - .fnend - .size rt_get_PSP, .-rt_get_PSP - - -/*--------------------------- os_set_env ------------------------------------*/ - -# void os_set_env (void); - /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ - - .thumb_func - .type os_set_env, %function - .global os_set_env -os_set_env: - .fnstart - .cantunwind - - MOV R0,SP /* PSP = MSP */ - MSR PSP,R0 - LDR R0,=os_flags - LDRB R0,[R0] - LSLS R0,#31 - BNE PrivilegedE - MOVS R0,#0x03 /* Unprivileged Thread mode, use PSP */ - MSR CONTROL,R0 - BX LR -PrivilegedE: - MOVS R0,#0x02 /* Privileged Thread mode, use PSP */ - MSR CONTROL,R0 - BX LR - - .fnend - .size os_set_env, .-os_set_env - - -/*--------------------------- _alloc_box ------------------------------------*/ - -# void *_alloc_box (void *box_mem); - /* Function wrapper for Unprivileged/Privileged mode. */ - - .thumb_func - .type _alloc_box, %function - .global _alloc_box -_alloc_box: - .fnstart - .cantunwind - - LDR R3,=rt_alloc_box - MOV R12,R3 - MRS R3,IPSR - LSLS R3,#24 - BNE PrivilegedA - MRS R3,CONTROL - LSLS R3,#31 - BEQ PrivilegedA - SVC 0 - BX LR -PrivilegedA: - BX R12 - - .fnend - .size _alloc_box, .-_alloc_box - - -/*--------------------------- _free_box -------------------------------------*/ - -# int _free_box (void *box_mem, void *box); - /* Function wrapper for Unprivileged/Privileged mode. */ - - .thumb_func - .type _free_box, %function - .global _free_box -_free_box: - .fnstart - .cantunwind - - LDR R3,=rt_free_box - MOV R12,R3 - MRS R3,IPSR - LSLS R3,#24 - BNE PrivilegedF - MRS R3,CONTROL - LSLS R3,#31 - BEQ PrivilegedF - SVC 0 - BX LR -PrivilegedF: - BX R12 - - .fnend - .size _free_box, .-_free_box - - -/*-------------------------- SVC_Handler ------------------------------------*/ - -# void SVC_Handler (void); - - .thumb_func - .type SVC_Handler, %function - .global SVC_Handler -SVC_Handler: - .fnstart - .cantunwind - - MRS R0,PSP /* Read PSP */ - LDR R1,[R0,#24] /* Read Saved PC from Stack */ - SUBS R1,R1,#2 /* Point to SVC Instruction */ - LDRB R1,[R1] /* Load SVC Number */ - CMP R1,#0 - BNE SVC_User /* User SVC Number > 0 */ - - MOV LR,R4 - LDMIA R0,{R0-R3,R4} /* Read R0-R3,R12 from stack */ - MOV R12,R4 - MOV R4,LR - BLX R12 /* Call SVC Function */ - - MRS R3,PSP /* Read PSP */ - STMIA R3!,{R0-R2} /* Store return values */ - - LDR R3,=os_tsk - LDMIA R3!,{R1,R2} /* os_tsk.run, os_tsk.new */ - CMP R1,R2 - BEQ SVC_Exit /* no task switch */ - - SUBS R3,#8 - CMP R1,#0 /* Runtask deleted? */ - BEQ SVC_Next - - MRS R0,PSP /* Read PSP */ - SUBS R0,R0,#32 /* Adjust Start Address */ - STR R0,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ - STMIA R0!,{R4-R7} /* Save old context (R4-R7) */ - MOV R4,R8 - MOV R5,R9 - MOV R6,R10 - MOV R7,R11 - STMIA R0!,{R4-R7} /* Save old context (R8-R11) */ - - PUSH {R2,R3} - BL rt_stk_check /* Check for Stack overflow */ - POP {R2,R3} - -SVC_Next: - STR R2,[R3] /* os_tsk.run = os_tsk.new */ - - LDR R0,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ - ADDS R0,R0,#16 /* Adjust Start Address */ - LDMIA R0!,{R4-R7} /* Restore new Context (R8-R11) */ - MOV R8,R4 - MOV R9,R5 - MOV R10,R6 - MOV R11,R7 - MSR PSP,R0 /* Write PSP */ - SUBS R0,R0,#32 /* Adjust Start Address */ - LDMIA R0!,{R4-R7} /* Restore new Context (R4-R7) */ - -SVC_Exit: - MOVS R0,#~0xFFFFFFFD /* Set EXC_RETURN value */ - MVNS R0,R0 - BX R0 /* RETI to Thread Mode, use PSP */ - - /*------------------- User SVC ------------------------------*/ - -SVC_User: - PUSH {R4,LR} /* Save Registers */ - LDR R2,=SVC_Count - LDR R2,[R2] - CMP R1,R2 - BHI SVC_Done /* Overflow */ - - LDR R4,=SVC_Table-4 - LSLS R1,R1,#2 - LDR R4,[R4,R1] /* Load SVC Function Address */ - MOV LR,R4 - - LDMIA R0,{R0-R3,R4} /* Read R0-R3,R12 from stack */ - MOV R12,R4 - BLX LR /* Call SVC Function */ - - MRS R4,PSP /* Read PSP */ - STMIA R4!,{R0-R3} /* Function return values */ -SVC_Done: - POP {R4,PC} /* RETI */ - - .fnend - .size SVC_Handler, .-SVC_Handler - - -/*-------------------------- PendSV_Handler ---------------------------------*/ - -# void PendSV_Handler (void); - - .thumb_func - .type PendSV_Handler, %function - .global PendSV_Handler - .global Sys_Switch -PendSV_Handler: - .fnstart - .cantunwind - - BL rt_pop_req - -Sys_Switch: - LDR R3,=os_tsk - LDMIA R3!,{R1,R2} /* os_tsk.run, os_tsk.new */ - CMP R1,R2 - BEQ Sys_Exit /* no task switch */ - - SUBS R3,#8 - - MRS R0,PSP /* Read PSP */ - SUBS R0,R0,#32 /* Adjust Start Address */ - STR R0,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ - STMIA R0!,{R4-R7} /* Save old context (R4-R7) */ - MOV R4,R8 - MOV R5,R9 - MOV R6,R10 - MOV R7,R11 - STMIA R0!,{R4-R7} /* Save old context (R8-R11) */ - - PUSH {R2,R3} - BL rt_stk_check /* Check for Stack overflow */ - POP {R2,R3} - - STR R2,[R3] /* os_tsk.run = os_tsk.new */ - - LDR R0,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ - ADDS R0,R0,#16 /* Adjust Start Address */ - LDMIA R0!,{R4-R7} /* Restore new Context (R8-R11) */ - MOV R8,R4 - MOV R9,R5 - MOV R10,R6 - MOV R11,R7 - MSR PSP,R0 /* Write PSP */ - SUBS R0,R0,#32 /* Adjust Start Address */ - LDMIA R0!,{R4-R7} /* Restore new Context (R4-R7) */ - -Sys_Exit: - MOVS R0,#~0xFFFFFFFD /* Set EXC_RETURN value */ - MVNS R0,R0 - BX R0 /* RETI to Thread Mode, use PSP */ - - .fnend - .size PendSV_Handler, .-PendSV_Handler - - -/*-------------------------- SysTick_Handler --------------------------------*/ - -# void SysTick_Handler (void); - - .thumb_func - .type SysTick_Handler, %function - .global SysTick_Handler -SysTick_Handler: - .fnstart - .cantunwind - - BL rt_systick - B Sys_Switch - - .fnend - .size SysTick_Handler, .-SysTick_Handler - - -/*-------------------------- OS_Tick_Handler --------------------------------*/ - -# void OS_Tick_Handler (void); - - .thumb_func - .type OS_Tick_Handler, %function - .global OS_Tick_Handler -OS_Tick_Handler: - .fnstart - .cantunwind - - BL os_tick_irqack - BL rt_systick - B Sys_Switch - - .fnend - .size OS_Tick_Handler, .-OS_Tick_Handler - - - .end - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/mbed-rtos/rtx/LPC11U24/GCC_ARM/SVC_Table.s Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -;/*---------------------------------------------------------------------------- -; * RL-ARM - RTX -; *---------------------------------------------------------------------------- -; * Name: SVC_TABLE.S -; * Purpose: Pre-defined SVC Table for Cortex-M -; * Rev.: V4.50 -; *---------------------------------------------------------------------------- -; * -; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH -; * All rights reserved. -; * Redistribution and use in source and binary forms, with or without -; * modification, are permitted provided that the following conditions are met: -; * - Redistributions of source code must retain the above copyright -; * notice, this list of conditions and the following disclaimer. -; * - Redistributions in binary form must reproduce the above copyright -; * notice, this list of conditions and the following disclaimer in the -; * documentation and/or other materials provided with the distribution. -; * - Neither the name of ARM nor the names of its contributors may be used -; * to endorse or promote products derived from this software without -; * specific prior written permission. -; * -; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE -; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -; * POSSIBILITY OF SUCH DAMAGE. -; *---------------------------------------------------------------------------*/ - - - .file "SVC_Table.S" - - - .section ".svc_table" - - .global SVC_Table -SVC_Table: -/* Insert user SVC functions here. SVC 0 used by RTL Kernel. */ -# .long __SVC_1 /* user SVC function */ -SVC_End: - - .global SVC_Count -SVC_Count: - .long (SVC_End-SVC_Table)/4 - - - .end - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/mbed-rtos/rtx/LPC11U24/uARM/HAL_CM0.c Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,301 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: HAL_CM0.C - * Purpose: Hardware Abstraction Layer for Cortex-M0 - * Rev.: V4.50 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_System.h" -#include "rt_HAL_CM.h" -#include "rt_Task.h" -#include "rt_MemBox.h" - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_set_PSP ------------------------------------*/ - -__asm void rt_set_PSP (U32 stack) { - MSR PSP,R0 - BX LR -} - - -/*--------------------------- rt_get_PSP ------------------------------------*/ - -__asm U32 rt_get_PSP (void) { - MRS R0,PSP - BX LR -} - - -/*--------------------------- os_set_env ------------------------------------*/ - -__asm void os_set_env (void) { - /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ - MOV R0,SP ; PSP = MSP - MSR PSP,R0 - LDR R0,=__cpp(&os_flags) - LDRB R0,[R0] - LSLS R0,#31 - BNE PrivilegedE - MOVS R0,#0x03 ; Unprivileged Thread mode, use PSP - MSR CONTROL,R0 - BX LR -PrivilegedE - MOVS R0,#0x02 ; Privileged Thread mode, use PSP - MSR CONTROL,R0 - BX LR - - ALIGN -} - - -/*--------------------------- _alloc_box ------------------------------------*/ - -__asm void *_alloc_box (void *box_mem) { - /* Function wrapper for Unprivileged/Privileged mode. */ - LDR R3,=__cpp(rt_alloc_box) - MOV R12,R3 - MRS R3,IPSR - LSLS R3,#24 - BNE PrivilegedA - MRS R3,CONTROL - LSLS R3,#31 - BEQ PrivilegedA - SVC 0 - BX LR -PrivilegedA - BX R12 - - ALIGN -} - - -/*--------------------------- _free_box -------------------------------------*/ - -__asm int _free_box (void *box_mem, void *box) { - /* Function wrapper for Unprivileged/Privileged mode. */ - LDR R3,=__cpp(rt_free_box) - MOV R12,R3 - MRS R3,IPSR - LSLS R3,#24 - BNE PrivilegedF - MRS R3,CONTROL - LSLS R3,#31 - BEQ PrivilegedF - SVC 0 - BX LR -PrivilegedF - BX R12 - - ALIGN -} - - -/*-------------------------- SVC_Handler ------------------------------------*/ - -__asm void SVC_Handler (void) { - PRESERVE8 - - IMPORT SVC_Count - IMPORT SVC_Table - IMPORT rt_stk_check - - MRS R0,PSP ; Read PSP - LDR R1,[R0,#24] ; Read Saved PC from Stack - SUBS R1,R1,#2 ; Point to SVC Instruction - LDRB R1,[R1] ; Load SVC Number - CMP R1,#0 - BNE SVC_User ; User SVC Number > 0 - - MOV LR,R4 - LDMIA R0,{R0-R3,R4} ; Read R0-R3,R12 from stack - MOV R12,R4 - MOV R4,LR - BLX R12 ; Call SVC Function - - MRS R3,PSP ; Read PSP - STMIA R3!,{R0-R2} ; Store return values - - LDR R3,=__cpp(&os_tsk) - LDMIA R3!,{R1,R2} ; os_tsk.run, os_tsk.new - CMP R1,R2 - BEQ SVC_Exit ; no task switch - - SUBS R3,#8 - CMP R1,#0 ; Runtask deleted? - BEQ SVC_Next - - MRS R0,PSP ; Read PSP - SUBS R0,R0,#32 ; Adjust Start Address - STR R0,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack - STMIA R0!,{R4-R7} ; Save old context (R4-R7) - MOV R4,R8 - MOV R5,R9 - MOV R6,R10 - MOV R7,R11 - STMIA R0!,{R4-R7} ; Save old context (R8-R11) - - PUSH {R2,R3} - BL rt_stk_check ; Check for Stack overflow - POP {R2,R3} - -SVC_Next - STR R2,[R3] ; os_tsk.run = os_tsk.new - - LDR R0,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack - ADDS R0,R0,#16 ; Adjust Start Address - LDMIA R0!,{R4-R7} ; Restore new Context (R8-R11) - MOV R8,R4 - MOV R9,R5 - MOV R10,R6 - MOV R11,R7 - MSR PSP,R0 ; Write PSP - SUBS R0,R0,#32 ; Adjust Start Address - LDMIA R0!,{R4-R7} ; Restore new Context (R4-R7) - -SVC_Exit - MOVS R0,#:NOT:0xFFFFFFFD ; Set EXC_RETURN value - MVNS R0,R0 - BX R0 ; RETI to Thread Mode, use PSP - - /*------------------- User SVC ------------------------------*/ - -SVC_User - PUSH {R4,LR} ; Save Registers - LDR R2,=SVC_Count - LDR R2,[R2] - CMP R1,R2 - BHI SVC_Done ; Overflow - - LDR R4,=SVC_Table-4 - LSLS R1,R1,#2 - LDR R4,[R4,R1] ; Load SVC Function Address - MOV LR,R4 - - LDMIA R0,{R0-R3,R4} ; Read R0-R3,R12 from stack - MOV R12,R4 - BLX LR ; Call SVC Function - - MRS R4,PSP ; Read PSP - STMIA R4!,{R0-R3} ; Function return values -SVC_Done - POP {R4,PC} ; RETI - - ALIGN -} - - -/*-------------------------- PendSV_Handler ---------------------------------*/ - -__asm void PendSV_Handler (void) { - PRESERVE8 - - BL __cpp(rt_pop_req) - -Sys_Switch - LDR R3,=__cpp(&os_tsk) - LDMIA R3!,{R1,R2} ; os_tsk.run, os_tsk.new - CMP R1,R2 - BEQ Sys_Exit ; no task switch - - SUBS R3,#8 - - MRS R0,PSP ; Read PSP - SUBS R0,R0,#32 ; Adjust Start Address - STR R0,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack - STMIA R0!,{R4-R7} ; Save old context (R4-R7) - MOV R4,R8 - MOV R5,R9 - MOV R6,R10 - MOV R7,R11 - STMIA R0!,{R4-R7} ; Save old context (R8-R11) - - PUSH {R2,R3} - BL rt_stk_check ; Check for Stack overflow - POP {R2,R3} - - STR R2,[R3] ; os_tsk.run = os_tsk.new - - LDR R0,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack - ADDS R0,R0,#16 ; Adjust Start Address - LDMIA R0!,{R4-R7} ; Restore new Context (R8-R11) - MOV R8,R4 - MOV R9,R5 - MOV R10,R6 - MOV R11,R7 - MSR PSP,R0 ; Write PSP - SUBS R0,R0,#32 ; Adjust Start Address - LDMIA R0!,{R4-R7} ; Restore new Context (R4-R7) - -Sys_Exit - MOVS R0,#:NOT:0xFFFFFFFD ; Set EXC_RETURN value - MVNS R0,R0 - BX R0 ; RETI to Thread Mode, use PSP - - ALIGN -} - - -/*-------------------------- SysTick_Handler --------------------------------*/ - -__asm void SysTick_Handler (void) { - PRESERVE8 - - BL __cpp(rt_systick) - B Sys_Switch - - ALIGN -} - - -/*-------------------------- OS_Tick_Handler --------------------------------*/ - -__asm void OS_Tick_Handler (void) { - PRESERVE8 - - BL __cpp(os_tick_irqack) - BL __cpp(rt_systick) - B Sys_Switch - - ALIGN -} - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/mbed-rtos/rtx/LPC11U24/uARM/SVC_Table.s Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -;/*---------------------------------------------------------------------------- -; * RL-ARM - RTX -; *---------------------------------------------------------------------------- -; * Name: SVC_TABLE.S -; * Purpose: Pre-defined SVC Table for Cortex-M -; * Rev.: V4.50 -; *---------------------------------------------------------------------------- -; * -; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH -; * All rights reserved. -; * Redistribution and use in source and binary forms, with or without -; * modification, are permitted provided that the following conditions are met: -; * - Redistributions of source code must retain the above copyright -; * notice, this list of conditions and the following disclaimer. -; * - Redistributions in binary form must reproduce the above copyright -; * notice, this list of conditions and the following disclaimer in the -; * documentation and/or other materials provided with the distribution. -; * - Neither the name of ARM nor the names of its contributors may be used -; * to endorse or promote products derived from this software without -; * specific prior written permission. -; * -; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE -; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -; * POSSIBILITY OF SUCH DAMAGE. -; *---------------------------------------------------------------------------*/ - - - AREA SVC_TABLE, CODE, READONLY - - EXPORT SVC_Count - -SVC_Cnt EQU (SVC_End-SVC_Table)/4 -SVC_Count DCD SVC_Cnt - -; Import user SVC functions here. -; IMPORT __SVC_1 - - EXPORT SVC_Table -SVC_Table -; Insert user SVC functions here. SVC 0 used by RTL Kernel. -; DCD __SVC_1 ; user SVC function - -SVC_End - - END - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/mbed-rtos/rtx/LPC1768/ARM/HAL_CM3.c Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,249 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: HAL_CM3.C - * Purpose: Hardware Abstraction Layer for Cortex-M3 - * Rev.: V4.50 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_System.h" -#include "rt_HAL_CM.h" -#include "rt_Task.h" -#include "rt_MemBox.h" - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_set_PSP ------------------------------------*/ - -__asm void rt_set_PSP (U32 stack) { - MSR PSP,R0 - BX LR -} - - -/*--------------------------- rt_get_PSP ------------------------------------*/ - -__asm U32 rt_get_PSP (void) { - MRS R0,PSP - BX LR -} - - -/*--------------------------- os_set_env ------------------------------------*/ - -__asm void os_set_env (void) { - /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ - MOV R0,SP ; PSP = MSP - MSR PSP,R0 - LDR R0,=__cpp(&os_flags) - LDRB R0,[R0] - LSLS R0,#31 - MOVNE R0,#0x02 ; Privileged Thread mode, use PSP - MOVEQ R0,#0x03 ; Unprivileged Thread mode, use PSP - MSR CONTROL,R0 - BX LR - - ALIGN -} - - -/*--------------------------- _alloc_box ------------------------------------*/ - -__asm void *_alloc_box (void *box_mem) { - /* Function wrapper for Unprivileged/Privileged mode. */ - LDR R12,=__cpp(rt_alloc_box) - MRS R3,IPSR - LSLS R3,#24 - BXNE R12 - MRS R3,CONTROL - LSLS R3,#31 - BXEQ R12 - SVC 0 - BX LR - - ALIGN -} - - -/*--------------------------- _free_box -------------------------------------*/ - -__asm int _free_box (void *box_mem, void *box) { - /* Function wrapper for Unprivileged/Privileged mode. */ - LDR R12,=__cpp(rt_free_box) - MRS R3,IPSR - LSLS R3,#24 - BXNE R12 - MRS R3,CONTROL - LSLS R3,#31 - BXEQ R12 - SVC 0 - BX LR - - ALIGN -} - - -/*-------------------------- SVC_Handler ------------------------------------*/ - -__asm void SVC_Handler (void) { - PRESERVE8 - - IMPORT SVC_Count - IMPORT SVC_Table - IMPORT rt_stk_check - - MRS R0,PSP ; Read PSP - LDR R1,[R0,#24] ; Read Saved PC from Stack - LDRB R1,[R1,#-2] ; Load SVC Number - CBNZ R1,SVC_User - - LDM R0,{R0-R3,R12} ; Read R0-R3,R12 from stack - BLX R12 ; Call SVC Function - - MRS R12,PSP ; Read PSP - STM R12,{R0-R2} ; Store return values - - LDR R3,=__cpp(&os_tsk) - LDM R3,{R1,R2} ; os_tsk.run, os_tsk.new - CMP R1,R2 - BEQ SVC_Exit ; no task switch - - CBZ R1,SVC_Next ; Runtask deleted? - STMDB R12!,{R4-R11} ; Save Old context - STR R12,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack - - PUSH {R2,R3} - BL rt_stk_check ; Check for Stack overflow - POP {R2,R3} - -SVC_Next - STR R2,[R3] ; os_tsk.run = os_tsk.new - - LDR R12,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack - LDMIA R12!,{R4-R11} ; Restore New Context - MSR PSP,R12 ; Write PSP - -SVC_Exit - MVN LR,#:NOT:0xFFFFFFFD ; set EXC_RETURN value - BX LR - - /*------------------- User SVC ------------------------------*/ - -SVC_User - PUSH {R4,LR} ; Save Registers - LDR R2,=SVC_Count - LDR R2,[R2] - CMP R1,R2 - BHI SVC_Done ; Overflow - - LDR R4,=SVC_Table-4 - LDR R4,[R4,R1,LSL #2] ; Load SVC Function Address - - LDM R0,{R0-R3,R12} ; Read R0-R3,R12 from stack - BLX R4 ; Call SVC Function - - MRS R12,PSP - STM R12,{R0-R3} ; Function return values -SVC_Done - POP {R4,PC} ; RETI - - ALIGN -} - - -/*-------------------------- PendSV_Handler ---------------------------------*/ - -__asm void PendSV_Handler (void) { - PRESERVE8 - - BL __cpp(rt_pop_req) - -Sys_Switch - LDR R3,=__cpp(&os_tsk) - LDM R3,{R1,R2} ; os_tsk.run, os_tsk.new - CMP R1,R2 - BEQ Sys_Exit - - MRS R12,PSP ; Read PSP - STMDB R12!,{R4-R11} ; Save Old context - STR R12,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack - - PUSH {R2,R3} - BL rt_stk_check ; Check for Stack overflow - POP {R2,R3} - - STR R2,[R3] ; os_tsk.run = os_tsk.new - - LDR R12,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack - LDMIA R12!,{R4-R11} ; Restore New Context - MSR PSP,R12 ; Write PSP - -Sys_Exit - MVN LR,#:NOT:0xFFFFFFFD ; set EXC_RETURN value - BX LR ; Return to Thread Mode - - ALIGN -} - - -/*-------------------------- SysTick_Handler --------------------------------*/ - -__asm void SysTick_Handler (void) { - PRESERVE8 - - BL __cpp(rt_systick) - B Sys_Switch - - ALIGN -} - - -/*-------------------------- OS_Tick_Handler --------------------------------*/ - -__asm void OS_Tick_Handler (void) { - PRESERVE8 - - BL __cpp(os_tick_irqack) - BL __cpp(rt_systick) - B Sys_Switch - - ALIGN -} - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/mbed-rtos/rtx/LPC1768/ARM/SVC_Table.s Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -;/*---------------------------------------------------------------------------- -; * RL-ARM - RTX -; *---------------------------------------------------------------------------- -; * Name: SVC_TABLE.S -; * Purpose: Pre-defined SVC Table for Cortex-M -; * Rev.: V4.50 -; *---------------------------------------------------------------------------- -; * -; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH -; * All rights reserved. -; * Redistribution and use in source and binary forms, with or without -; * modification, are permitted provided that the following conditions are met: -; * - Redistributions of source code must retain the above copyright -; * notice, this list of conditions and the following disclaimer. -; * - Redistributions in binary form must reproduce the above copyright -; * notice, this list of conditions and the following disclaimer in the -; * documentation and/or other materials provided with the distribution. -; * - Neither the name of ARM nor the names of its contributors may be used -; * to endorse or promote products derived from this software without -; * specific prior written permission. -; * -; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE -; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -; * POSSIBILITY OF SUCH DAMAGE. -; *---------------------------------------------------------------------------*/ - - - AREA SVC_TABLE, CODE, READONLY - - EXPORT SVC_Count - -SVC_Cnt EQU (SVC_End-SVC_Table)/4 -SVC_Count DCD SVC_Cnt - -; Import user SVC functions here. -; IMPORT __SVC_1 - - EXPORT SVC_Table -SVC_Table -; Insert user SVC functions here. SVC 0 used by RTL Kernel. -; DCD __SVC_1 ; user SVC function - -SVC_End - - END - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/mbed-rtos/rtx/LPC1768/GCC_ARM/HAL_CM3.s Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,323 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: HAL_CM3.S - * Purpose: Hardware Abstraction Layer for Cortex-M3 - * Rev.: V4.50 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - - .file "HAL_CM3.S" - .syntax unified - - .equ TCB_TSTACK, 36 - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - .thumb - - .section ".text" - .align 2 - - -/*--------------------------- rt_set_PSP ------------------------------------*/ - -# void rt_set_PSP (U32 stack); - - .thumb_func - .type rt_set_PSP, %function - .global rt_set_PSP -rt_set_PSP: - .fnstart - .cantunwind - - MSR PSP,R0 - BX LR - - .fnend - .size rt_set_PSP, .-rt_set_PSP - - -/*--------------------------- rt_get_PSP ------------------------------------*/ - -# U32 rt_get_PSP (void); - - .thumb_func - .type rt_get_PSP, %function - .global rt_get_PSP -rt_get_PSP: - .fnstart - .cantunwind - - MRS R0,PSP - BX LR - - .fnend - .size rt_get_PSP, .-rt_get_PSP - - -/*--------------------------- os_set_env ------------------------------------*/ - -# void os_set_env (void); - /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ - - .thumb_func - .type os_set_env, %function - .global os_set_env -os_set_env: - .fnstart - .cantunwind - - MOV R0,SP /* PSP = MSP */ - MSR PSP,R0 - LDR R0,=os_flags - LDRB R0,[R0] - LSLS R0,#31 - ITE NE - MOVNE R0,#0x02 /* Privileged Thread mode, use PSP */ - MOVEQ R0,#0x03 /* Unprivileged Thread mode, use PSP */ - MSR CONTROL,R0 - BX LR - - .fnend - .size os_set_env, .-os_set_env - - -/*--------------------------- _alloc_box ------------------------------------*/ - -# void *_alloc_box (void *box_mem); - /* Function wrapper for Unprivileged/Privileged mode. */ - - .thumb_func - .type _alloc_box, %function - .global _alloc_box -_alloc_box: - .fnstart - .cantunwind - - LDR R12,=rt_alloc_box - MRS R3,IPSR - LSLS R3,#24 - IT NE - BXNE R12 - MRS R3,CONTROL - LSLS R3,#31 - IT EQ - BXEQ R12 - SVC 0 - BX LR - - .fnend - .size _alloc_box, .-_alloc_box - - -/*--------------------------- _free_box -------------------------------------*/ - -# int _free_box (void *box_mem, void *box); - /* Function wrapper for Unprivileged/Privileged mode. */ - - .thumb_func - .type _free_box, %function - .global _free_box -_free_box: - .fnstart - .cantunwind - - LDR R12,=rt_free_box - MRS R3,IPSR - LSLS R3,#24 - IT NE - BXNE R12 - MRS R3,CONTROL - LSLS R3,#31 - IT EQ - BXEQ R12 - SVC 0 - BX LR - - .fnend - .size _free_box, .-_free_box - - -/*-------------------------- SVC_Handler ------------------------------------*/ - -# void SVC_Handler (void); - - .thumb_func - .type SVC_Handler, %function - .global SVC_Handler -SVC_Handler: - .fnstart - .cantunwind - - MRS R0,PSP /* Read PSP */ - LDR R1,[R0,#24] /* Read Saved PC from Stack */ - LDRB R1,[R1,#-2] /* Load SVC Number */ - CBNZ R1,SVC_User - - LDM R0,{R0-R3,R12} /* Read R0-R3,R12 from stack */ - BLX R12 /* Call SVC Function */ - - MRS R12,PSP /* Read PSP */ - STM R12,{R0-R2} /* Store return values */ - - LDR R3,=os_tsk - LDM R3,{R1,R2} /* os_tsk.run, os_tsk.new */ - CMP R1,R2 - BEQ SVC_Exit /* no task switch */ - - CBZ R1,SVC_Next /* Runtask deleted? */ - STMDB R12!,{R4-R11} /* Save Old context */ - STR R12,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ - - PUSH {R2,R3} - BL rt_stk_check /* Check for Stack overflow */ - POP {R2,R3} - -SVC_Next: - STR R2,[R3] /* os_tsk.run = os_tsk.new */ - - LDR R12,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ - LDMIA R12!,{R4-R11} /* Restore New Context */ - MSR PSP,R12 /* Write PSP */ - -SVC_Exit: - MVN LR,#~0xFFFFFFFD /* set EXC_RETURN value */ - BX LR - - /*------------------- User SVC ------------------------------*/ - -SVC_User: - PUSH {R4,LR} /* Save Registers */ - LDR R2,=SVC_Count - LDR R2,[R2] - CMP R1,R2 - BHI SVC_Done /* Overflow */ - - LDR R4,=SVC_Table-4 - LDR R4,[R4,R1,LSL #2] /* Load SVC Function Address */ - - LDM R0,{R0-R3,R12} /* Read R0-R3,R12 from stack */ - BLX R4 /* Call SVC Function */ - - MRS R12,PSP - STM R12,{R0-R3} /* Function return values */ -SVC_Done: - POP {R4,PC} /* RETI */ - - .fnend - .size SVC_Handler, .-SVC_Handler - - -/*-------------------------- PendSV_Handler ---------------------------------*/ - -# void PendSV_Handler (void); - - .thumb_func - .type PendSV_Handler, %function - .global PendSV_Handler - .global Sys_Switch -PendSV_Handler: - .fnstart - .cantunwind - - BL rt_pop_req - -Sys_Switch: - LDR R3,=os_tsk - LDM R3,{R1,R2} /* os_tsk.run, os_tsk.new */ - CMP R1,R2 - BEQ Sys_Exit - - MRS R12,PSP /* Read PSP */ - STMDB R12!,{R4-R11} /* Save Old context */ - STR R12,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ - - PUSH {R2,R3} - BL rt_stk_check /* Check for Stack overflow */ - POP {R2,R3} - - STR R2,[R3] /* os_tsk.run = os_tsk.new */ - - LDR R12,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ - LDMIA R12!,{R4-R11} /* Restore New Context */ - MSR PSP,R12 /* Write PSP */ - -Sys_Exit: - MVN LR,#~0xFFFFFFFD /* set EXC_RETURN value */ - BX LR /* Return to Thread Mode */ - - .fnend - .size PendSV_Handler, .-PendSV_Handler - - -/*-------------------------- SysTick_Handler --------------------------------*/ - -# void SysTick_Handler (void); - - .thumb_func - .type SysTick_Handler, %function - .global SysTick_Handler -SysTick_Handler: - .fnstart - .cantunwind - - BL rt_systick - B Sys_Switch - - .fnend - .size SysTick_Handler, .-SysTick_Handler - - -/*-------------------------- OS_Tick_Handler --------------------------------*/ - -# void OS_Tick_Handler (void); - - .thumb_func - .type OS_Tick_Handler, %function - .global OS_Tick_Handler -OS_Tick_Handler: - .fnstart - .cantunwind - - BL os_tick_irqack - BL rt_systick - B Sys_Switch - - .fnend - .size OS_Tick_Handler, .-OS_Tick_Handler - - - .end - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/mbed-rtos/rtx/LPC1768/GCC_ARM/SVC_Table.s Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -;/*---------------------------------------------------------------------------- -; * RL-ARM - RTX -; *---------------------------------------------------------------------------- -; * Name: SVC_TABLE.S -; * Purpose: Pre-defined SVC Table for Cortex-M -; * Rev.: V4.50 -; *---------------------------------------------------------------------------- -; * -; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH -; * All rights reserved. -; * Redistribution and use in source and binary forms, with or without -; * modification, are permitted provided that the following conditions are met: -; * - Redistributions of source code must retain the above copyright -; * notice, this list of conditions and the following disclaimer. -; * - Redistributions in binary form must reproduce the above copyright -; * notice, this list of conditions and the following disclaimer in the -; * documentation and/or other materials provided with the distribution. -; * - Neither the name of ARM nor the names of its contributors may be used -; * to endorse or promote products derived from this software without -; * specific prior written permission. -; * -; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE -; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -; * POSSIBILITY OF SUCH DAMAGE. -; *---------------------------------------------------------------------------*/ - - - .file "SVC_Table.S" - - - .section ".svc_table" - - .global SVC_Table -SVC_Table: -/* Insert user SVC functions here. SVC 0 used by RTL Kernel. */ -# .long __SVC_1 /* user SVC function */ -SVC_End: - - .global SVC_Count -SVC_Count: - .long (SVC_End-SVC_Table)/4 - - - .end - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/mbed-rtos/rtx/RTX_CM_lib.h Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,367 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RTX_CM_LIB.H - * Purpose: RTX Kernel System Configuration - * Rev.: V4.50 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#if defined (__CC_ARM) -#pragma O3 -#define __USED __attribute__((used)) -#elif defined (__GNUC__) -#pragma GCC optimize ("O3") -#define __USED __attribute__((used)) -#elif defined (__ICCARM__) -#define __USED __root -#endif - - -/*---------------------------------------------------------------------------- - * Definitions - *---------------------------------------------------------------------------*/ - -#define _declare_box(pool,size,cnt) uint32_t pool[(((size)+3)/4)*(cnt) + 3] -#define _declare_box8(pool,size,cnt) uint64_t pool[(((size)+7)/8)*(cnt) + 2] - -#define OS_TCB_SIZE 48 -#define OS_TMR_SIZE 8 - -#if defined (__CC_ARM) && !defined (__MICROLIB) - -typedef void *OS_ID; -typedef uint32_t OS_TID; -typedef uint32_t OS_MUT[3]; -typedef uint32_t OS_RESULT; - -#define runtask_id() rt_tsk_self() -#define mutex_init(m) rt_mut_init(m) -#define mutex_wait(m) os_mut_wait(m,0xFFFF) -#define mutex_rel(m) os_mut_release(m) - -extern OS_TID rt_tsk_self (void); -extern void rt_mut_init (OS_ID mutex); -extern OS_RESULT rt_mut_release (OS_ID mutex); -extern OS_RESULT rt_mut_wait (OS_ID mutex, uint16_t timeout); - -#define os_mut_wait(mutex,timeout) _os_mut_wait((uint32_t)rt_mut_wait,mutex,timeout) -#define os_mut_release(mutex) _os_mut_release((uint32_t)rt_mut_release,mutex) - -OS_RESULT _os_mut_release (uint32_t p, OS_ID mutex) __svc_indirect(0); -OS_RESULT _os_mut_wait (uint32_t p, OS_ID mutex, uint16_t timeout) __svc_indirect(0); - -#endif - - -/*---------------------------------------------------------------------------- - * Global Variables - *---------------------------------------------------------------------------*/ - -#if (OS_TIMERS != 0) -#define OS_TASK_CNT (OS_TASKCNT + 1) -#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. */ - for (;;); - } - *mutex = &std_libmutex[nr_mutex++]; - mutex_init (*mutex); - return (1); -} - - -/*--------------------------- _mutex_acquire --------------------------------*/ - -__attribute__((used)) void _mutex_acquire (OS_ID *mutex) { - /* Acquire a system mutex, lock stdlib resources. */ - if (runtask_id ()) { - /* RTX running, acquire a mutex. */ - mutex_wait (*mutex); - } -} - - -/*--------------------------- _mutex_release --------------------------------*/ - -__attribute__((used)) void _mutex_release (OS_ID *mutex) { - /* Release a system mutex, unlock stdlib resources. */ - if (runtask_id ()) { - /* RTX runnning, 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}; - -#if defined (__CC_ARM) - -// This define should be probably moved to the CMSIS layer -#ifdef TARGET_LPC1768 -#define INITIAL_SP (0x10008000UL) - -#elif TARGET_LPC11U24 -#define INITIAL_SP (0x10001000UL) - -#endif - -extern unsigned char Image$$RW_IRAM1$$ZI$$Limit[]; - -void set_main_stack(void) { - // Leave OS_SCHEDULERSTKSIZE words for the scheduler and interrupts - os_thread_def_main.stack_pointer = Image$$RW_IRAM1$$ZI$$Limit; - os_thread_def_main.stacksize = (INITIAL_SP - (unsigned int)Image$$RW_IRAM1$$ZI$$Limit) - (OS_SCHEDULERSTKSIZE * 4); -} - -#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(); - osThreadCreate(&os_thread_def_main, NULL); - osKernelStart(); - for (;;); -} - -#else - -__attribute__((naked)) void software_init_hook (void) { - __asm ( - ".syntax unified\n" - ".thumb\n" - "movs r0,#0\n" - "movs r1,#0\n" - "mov r4,r0\n" - "mov r5,r1\n" - "ldr r0,= __libc_fini_array\n" - "bl atexit\n" - "bl __libc_init_array\n" - "mov r0,r4\n" - "mov r1,r5\n" - "bl osKernelInitialize\n" - "ldr r0,=os_thread_def_main\n" - "movs r1,#0\n" - "bl osThreadCreate\n" - "bl osKernelStart\n" - "bl exit\n" - ); -} - -#endif - -#elif defined (__ICCARM__) - -extern int __low_level_init(void); -extern void __iar_data_init3(void); -extern void exit(int arg); - -__noreturn __stackless void __cmain(void) { - int a; - - if (__low_level_init() != 0) { - __iar_data_init3(); - } - osKernelInitialize(); - osThreadCreate(&os_thread_def_main, NULL); - a = osKernelStart(); - exit(a); -} - -#endif - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/mbed-rtos/rtx/RTX_Conf_CM.c Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,242 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RTX_Conf_CM.C - * Purpose: Configuration of CMSIS RTX Kernel for Cortex-M - * Rev.: V4.20 - *---------------------------------------------------------------------------- - * - * 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) -# define OS_TASKCNT 14 -# elif defined(TARGET_LPC11U24) -# define OS_TASKCNT 6 -# endif -#endif - -// <o>Scheduler (+ interrupts) stack size [bytes] <64-4096:8><#/4> -#ifndef OS_SCHEDULERSTKSIZE -# if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) -# define OS_SCHEDULERSTKSIZE 256 -# elif defined(TARGET_LPC11U24) -# define OS_SCHEDULERSTKSIZE 128 -# 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 - -// <q>Run in privileged mode -// ========================= -// <i> Runs all Threads in privileged mode. -// <i> Default: Unprivileged -#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_LPC11U24) -# define OS_CLOCK 48000000 -# 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 -// <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> Defines number of concurrent callbacks that will be queued. -// <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 iterrupt handler. -// <i> Default: 16 entries -#ifndef OS_FIFOSZ - #define OS_FIFOSZ 16 -#endif - -// </h> - -//------------- <<< end of configuration section >>> ----------------------- - -// Standard library system mutexes -// =============================== -// Define max. number system mutexes that are used to protect -// the arm standard runtime library. For microlib they are not used. -#ifndef OS_MUTEXCNT - #define OS_MUTEXCNT 8 -#endif - -/*---------------------------------------------------------------------------- - * RTX User configuration part END - *---------------------------------------------------------------------------*/ - -#define OS_TRV ((uint32_t)(((double)OS_CLOCK*(double)OS_TICK)/1E6)-1) - - -/*---------------------------------------------------------------------------- - * 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_Config.h). */ - mbed_die(); -} - -void sysThreadError(osStatus status) { - if (status != osOK) { - mbed_die(); - } -} - -/*---------------------------------------------------------------------------- - * RTX Configuration Functions - *---------------------------------------------------------------------------*/ - -#include "RTX_CM_lib.h" - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/mbed-rtos/rtx/RTX_Config.h Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RTX_CONFIG.H - * Purpose: Exported functions of RTX_Config.c - * Rev.: V4.50 - *---------------------------------------------------------------------------- - * - * 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 THREAD_STACK_DIAGNOSTIC 1 - -/* 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);
--- a/mbed-rtos/rtx/cmsis_os.h Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,774 +0,0 @@ -/* ---------------------------------------------------------------------- - * Copyright (C) 2012 ARM Limited. All rights reserved. - * - * $Date: 5. June 2012 - * $Revision: V1.01 - * - * Project: CMSIS-RTOS API - * Title: cmsis_os.h RTX header file - * - * Version 0.02 - * Initial Proposal Phase - * Version 0.03 - * osKernelStart added, optional feature: main started as thread - * osSemaphores have standard behaviour - * 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 troughtout 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 underlaying RTOS kernel and version number. -#define osCMSIS_RTX ((4<<16)|50) ///< 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.50" ///< RTOS identification string - - -#define CMSIS_OS_RTX - -// The stack space occupied is mainly dependent on the underling C standard library -#if defined(TOOLCHAIN_GCC_ARM) || defined(TOOLCHAIN_CS_ARM) || defined(TOOLCHAIN_CR_ARM) -# define WORDS_STACK_SIZE 512 -#elif defined(TOOLCHAIN_ARM) -# define WORDS_STACK_SIZE 512 -#elif defined(TOOLCHAIN_uARM) -# 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 8 ///< maximum count for \ref osSemaphoreCreate function -#define osFeature_Wait 0 ///< osWait function: 1=available, 0=not available - -#if defined (__CC_ARM) -#define os_InRegs __value_in_regs // Compiler specific: force struct in registers -#else -#define os_InRegs -#endif - -#include <stdint.h> -#include <stddef.h> - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include "os_tcb.h" - -// ==== Enumeration, structures, defines ==== - -/// Priority used for thread control. -/// \note MUST REMAIN UNCHANGED: \b osPriority shall be consistent in every CMSIS-RTOS. -typedef enum { - osPriorityIdle = -3, ///< priority: idle (lowest) - osPriorityLow = -2, ///< priority: low - osPriorityBelowNormal = -1, ///< priority: below normal - osPriorityNormal = 0, ///< priority: normal (default) - osPriorityAboveNormal = +1, ///< priority: above normal - osPriorityHigh = +2, ///< priority: high - osPriorityRealtime = +3, ///< priority: realtime (highest) - osPriorityError = 0x84 ///< system cannot determine priority or thread has illegal priority -} osPriority; - -/// Timeout value. -/// \note MUST REMAIN UNCHANGED: \b osWaitForever shall be consistent in every CMSIS-RTOS. -#define osWaitForever 0xFFFFFFFF ///< wait forever timeout value - -/// Status code values returned by CMSIS-RTOS functions. -/// \note MUST REMAIN UNCHANGED: \b osStatus shall be consistent in every CMSIS-RTOS. -typedef enum { - osOK = 0, ///< function completed; no event occurred. - osEventSignal = 0x08, ///< function completed; signal event occurred. - osEventMessage = 0x10, ///< function completed; message event occurred. - osEventMail = 0x20, ///< function completed; mail event occurred. - osEventTimeout = 0x40, ///< function completed; timeout occurred. - osErrorParameter = 0x80, ///< parameter error: a mandatory parameter was missing or specified an incorrect object. - osErrorResource = 0x81, ///< resource not available: a specified resource was not available. - osErrorTimeoutResource = 0xC1, ///< resource not available within given time: a specified resource was not available within the timeout period. - osErrorISR = 0x82, ///< not allowed in ISR context: the function cannot be called from interrupt service routines. - osErrorISRRecursive = 0x83, ///< function called multiple times from ISR with same object. - osErrorPriority = 0x84, ///< system cannot determine priority or thread has illegal priority. - osErrorNoMemory = 0x85, ///< system is out of memory: it was impossible to allocate or reserve memory for the operation. - osErrorValue = 0x86, ///< value of a parameter is out of range. - osErrorOS = 0xFF, ///< unspecified RTOS error: run-time error but no other error message fits. - os_status_reserved = 0x7FFFFFFF ///< prevent from enum down-size compiler optimization. -} osStatus; - - -/// Timer type value for the timer definition. -/// \note MUST REMAIN UNCHANGED: \b os_timer_type shall be consistent in every CMSIS-RTOS. -typedef enum { - osTimerOnce = 0, ///< one-shot timer - osTimerPeriodic = 1 ///< repeating timer -} os_timer_type; - -/// Entry point of a thread. -/// \note MUST REMAIN UNCHANGED: \b os_pthread shall be consistent in every CMSIS-RTOS. -typedef void (*os_pthread) (void const *argument); - -/// Entry point of a timer call back function. -/// \note MUST REMAIN UNCHANGED: \b os_ptimer shall be consistent in every CMSIS-RTOS. -typedef void (*os_ptimer) (void const *argument); - -// >>> the following data type definitions may shall adapted towards a specific RTOS - -/// Thread ID identifies the thread (pointer to a thread control block). -/// \note CAN BE CHANGED: \b os_thread_cb is implementation specific in every CMSIS-RTOS. -typedef struct os_thread_cb *osThreadId; - -/// Timer ID identifies the timer (pointer to a timer control block). -/// \note CAN BE CHANGED: \b os_timer_cb is implementation specific in every CMSIS-RTOS. -typedef struct os_timer_cb *osTimerId; - -/// Mutex ID identifies the mutex (pointer to a mutex control block). -/// \note CAN BE CHANGED: \b os_mutex_cb is implementation specific in every CMSIS-RTOS. -typedef struct os_mutex_cb *osMutexId; - -/// Semaphore ID identifies the semaphore (pointer to a semaphore control block). -/// \note CAN BE CHANGED: \b os_semaphore_cb is implementation specific in every CMSIS-RTOS. -typedef struct os_semaphore_cb *osSemaphoreId; - -/// Pool ID identifies the memory pool (pointer to a memory pool control block). -/// \note CAN BE CHANGED: \b os_pool_cb is implementation specific in every CMSIS-RTOS. -typedef struct os_pool_cb *osPoolId; - -/// Message ID identifies the message queue (pointer to a message queue control block). -/// \note CAN BE CHANGED: \b os_messageQ_cb is implementation specific in every CMSIS-RTOS. -typedef struct os_messageQ_cb *osMessageQId; - -/// Mail ID identifies the mail queue (pointer to a mail queue control block). -/// \note CAN BE CHANGED: \b os_mailQ_cb is implementation specific in every CMSIS-RTOS. -typedef struct os_mailQ_cb *osMailQId; - - -/// Thread Definition structure contains startup information of a thread. -/// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS. -typedef struct os_thread_def { - os_pthread pthread; ///< start address of thread function - osPriority tpriority; ///< initial thread priority - uint32_t stacksize; ///< stack size requirements in bytes - unsigned char *stack_pointer; ///< pointer to the stack memory block - struct OS_TCB tcb; -} osThreadDef_t; - -/// Timer Definition structure contains timer parameters. -/// \note CAN BE CHANGED: \b os_timer_def is implementation specific in every CMSIS-RTOS. -typedef struct os_timer_def { - os_ptimer ptimer; ///< start address of a timer function - void *timer; ///< pointer to internal data -} osTimerDef_t; - -/// Mutex Definition structure contains setup information for a mutex. -/// \note CAN BE CHANGED: \b os_mutex_def is implementation specific in every CMSIS-RTOS. -typedef struct os_mutex_def { - void *mutex; ///< pointer to internal data -} osMutexDef_t; - -/// Semaphore Definition structure contains setup information for a semaphore. -/// \note CAN BE CHANGED: \b os_semaphore_def is implementation specific in every CMSIS-RTOS. -typedef struct os_semaphore_def { - void *semaphore; ///< pointer to internal data -} osSemaphoreDef_t; - -/// Definition structure for memory block allocation. -/// \note CAN BE CHANGED: \b os_pool_def is implementation specific in every CMSIS-RTOS. -typedef struct os_pool_def { - uint32_t pool_sz; ///< number of items (elements) in the pool - uint32_t item_sz; ///< size of an item - void *pool; ///< pointer to memory for pool -} osPoolDef_t; - -/// Definition structure for message queue. -/// \note CAN BE CHANGED: \b os_messageQ_def is implementation specific in every CMSIS-RTOS. -typedef struct os_messageQ_def { - uint32_t queue_sz; ///< number of elements in the queue - void *pool; ///< memory array for messages -} osMessageQDef_t; - -/// Definition structure for mail queue. -/// \note CAN BE CHANGED: \b os_mailQ_def is implementation specific in every CMSIS-RTOS. -typedef struct os_mailQ_def { - uint32_t queue_sz; ///< number of elements in the queue - uint32_t item_sz; ///< size of an item - void *pool; ///< memory array for mail -} osMailQDef_t; - -/// Event structure contains detailed information about an event. -/// \note MUST REMAIN UNCHANGED: \b os_event shall be consistent in every CMSIS-RTOS. -/// However the struct may be extended at the end. -typedef struct { - osStatus status; ///< status code: event or error information - union { - uint32_t v; ///< message as 32-bit value - void *p; ///< message or mail as void pointer - int32_t signals; ///< signal flags - } value; ///< event value - union { - osMailQId mail_id; ///< mail id obtained by \ref osMailCreate - osMessageQId message_id; ///< message id obtained by \ref osMessageCreate - } def; ///< event definition -} osEvent; - - -// ==== Kernel Control Functions ==== - -/// Initialize the RTOS Kernel for creating objects. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osKernelInitialize shall be consistent in every CMSIS-RTOS. -osStatus osKernelInitialize (void); - -/// Start the RTOS Kernel. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osKernelStart shall be consistent in every CMSIS-RTOS. -osStatus osKernelStart (void); - -/// Check if the RTOS kernel is already started. -/// \note MUST REMAIN UNCHANGED: \b osKernelRunning shall be consistent in every CMSIS-RTOS. -/// \return 0 RTOS is not started, 1 RTOS is started. -int32_t osKernelRunning(void); - - -// ==== Thread Management ==== - -/// Create a Thread Definition with function, priority, and stack requirements. -/// \param name name of the thread function. -/// \param priority initial priority of the thread function. -/// \param stacksz stack size (in bytes) requirements for the thread function. -/// \note CAN BE CHANGED: The parameters to \b osThreadDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osThreadDef(name, priority, stacksz) \ -extern osThreadDef_t os_thread_def_##name -#else // define the object -#define osThreadDef(name, priority, stacksz) \ -unsigned char os_thread_def_stack_##name [stacksz]; \ -osThreadDef_t os_thread_def_##name = \ -{ (name), (priority), (stacksz), (os_thread_def_stack_##name)} -#endif - -/// Access a Thread defintion. -/// \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 signal); - -/// 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 signal); - -/// 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 defintion. -/// \param name name of the mutex object. -/// \note CAN BE CHANGED: The parameter to \b osMutex shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osMutex(name) \ -&os_mutex_def_##name - -/// Create and Initialize a Mutex object. -/// \param[in] mutex_def mutex definition referenced with \ref osMutex. -/// \return mutex ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osMutexCreate shall be consistent in every CMSIS-RTOS. -osMutexId osMutexCreate (osMutexDef_t *mutex_def); - -/// Wait until a Mutex becomes available. -/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. -/// \param[in] millisec timeout value or 0 in case of no time-out. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMutexWait shall be consistent in every CMSIS-RTOS. -osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec); - -/// Release a Mutex that was obtained by \ref osMutexWait. -/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMutexRelease shall be consistent in every CMSIS-RTOS. -osStatus osMutexRelease (osMutexId mutex_id); - -/// Delete a Mutex that was created by \ref osMutexCreate. -/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMutexDelete shall be consistent in every CMSIS-RTOS. -osStatus osMutexDelete (osMutexId mutex_id); - - -// ==== Semaphore Management Functions ==== - -#if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0)) // Semaphore available - -/// Define a Semaphore object. -/// \param name name of the semaphore object. -/// \note CAN BE CHANGED: The parameter to \b osSemaphoreDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osSemaphoreDef(name) \ -extern osSemaphoreDef_t os_semaphore_def_##name -#else // define the object -#define osSemaphoreDef(name) \ -uint32_t os_semaphore_cb_##name[2]; \ -osSemaphoreDef_t os_semaphore_def_##name = { (os_semaphore_cb_##name) } -#endif - -/// Access a Semaphore definition. -/// \param name name of the semaphore object. -/// \note CAN BE CHANGED: The parameter to \b osSemaphore shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osSemaphore(name) \ -&os_semaphore_def_##name - -/// Create and Initialize a Semaphore object used for managing resources. -/// \param[in] semaphore_def semaphore definition referenced with \ref osSemaphore. -/// \param[in] count number of available resources. -/// \return semaphore ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osSemaphoreCreate shall be consistent in every CMSIS-RTOS. -osSemaphoreId osSemaphoreCreate (osSemaphoreDef_t *semaphore_def, int32_t count); - -/// Wait until a Semaphore token becomes available. -/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. -/// \param[in] millisec timeout value or 0 in case of no time-out. -/// \return number of available tokens, or -1 in case of incorrect parameters. -/// \note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS. -int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec); - -/// Release a Semaphore token. -/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osSemaphoreRelease shall be consistent in every CMSIS-RTOS. -osStatus osSemaphoreRelease (osSemaphoreId semaphore_id); - -/// Delete a Semaphore that was created by \ref osSemaphoreCreate. -/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osSemaphoreDelete shall be consistent in every CMSIS-RTOS. -osStatus osSemaphoreDelete (osSemaphoreId semaphore_id); - -#endif // Semaphore available - - -// ==== Memory Pool Management Functions ==== - -#if (defined (osFeature_Pool) && (osFeature_Pool != 0)) // Memory Pool Management available - -/// \brief Define a Memory Pool. -/// \param name name of the memory pool. -/// \param no maximum number of blocks (objects) in the memory pool. -/// \param type data type of a single block (object). -/// \note CAN BE CHANGED: The parameter to \b osPoolDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osPoolDef(name, no, type) \ -extern osPoolDef_t os_pool_def_##name -#else // define the object -#define osPoolDef(name, no, type) \ -uint32_t os_pool_m_##name[3+((sizeof(type)+3)/4)*(no)]; \ -osPoolDef_t os_pool_def_##name = \ -{ (no), sizeof(type), (os_pool_m_##name) } -#endif - -/// \brief Access a Memory Pool definition. -/// \param name name of the memory pool -/// \note CAN BE CHANGED: The parameter to \b osPool shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osPool(name) \ -&os_pool_def_##name - -/// Create and Initialize a memory pool. -/// \param[in] pool_def memory pool definition referenced with \ref osPool. -/// \return memory pool ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osPoolCreate shall be consistent in every CMSIS-RTOS. -osPoolId osPoolCreate (osPoolDef_t *pool_def); - -/// Allocate a memory block from a memory pool. -/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. -/// \return address of the allocated memory block or NULL in case of no memory available. -/// \note MUST REMAIN UNCHANGED: \b osPoolAlloc shall be consistent in every CMSIS-RTOS. -void *osPoolAlloc (osPoolId pool_id); - -/// Allocate a memory block from a memory pool and set memory block to zero. -/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. -/// \return address of the allocated memory block or NULL in case of no memory available. -/// \note MUST REMAIN UNCHANGED: \b osPoolCAlloc shall be consistent in every CMSIS-RTOS. -void *osPoolCAlloc (osPoolId pool_id); - -/// Return an allocated memory block back to a specific memory pool. -/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. -/// \param[in] block address of the allocated memory block that is returned to the memory pool. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osPoolFree shall be consistent in every CMSIS-RTOS. -osStatus osPoolFree (osPoolId pool_id, void *block); - -#endif // Memory Pool Management available - - -// ==== Message Queue Management Functions ==== - -#if (defined (osFeature_MessageQ) && (osFeature_MessageQ != 0)) // Message Queues available - -/// \brief Create a Message Queue Definition. -/// \param name name of the queue. -/// \param queue_sz maximum number of messages in the queue. -/// \param type data type of a single message element (for debugger). -/// \note CAN BE CHANGED: The parameter to \b osMessageQDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osMessageQDef(name, queue_sz, type) \ -extern osMessageQDef_t os_messageQ_def_##name -#else // define the object -#define osMessageQDef(name, queue_sz, type) \ -uint32_t os_messageQ_q_##name[4+(queue_sz)]; \ -osMessageQDef_t os_messageQ_def_##name = \ -{ (queue_sz), (os_messageQ_q_##name) } -#endif - -/// \brief Access a Message Queue Definition. -/// \param name name of the queue -/// \note CAN BE CHANGED: The parameter to \b osMessageQ shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osMessageQ(name) \ -&os_messageQ_def_##name - -/// Create and Initialize a Message Queue. -/// \param[in] queue_def queue definition referenced with \ref osMessageQ. -/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. -/// \return message queue ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osMessageCreate shall be consistent in every CMSIS-RTOS. -osMessageQId osMessageCreate (osMessageQDef_t *queue_def, osThreadId thread_id); - -/// Put a Message to a Queue. -/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. -/// \param[in] info message information. -/// \param[in] millisec timeout value or 0 in case of no time-out. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMessagePut shall be consistent in every CMSIS-RTOS. -osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec); - -/// Get a Message or Wait for a Message from a Queue. -/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. -/// \param[in] millisec timeout value or 0 in case of no time-out. -/// \return event information that includes status code. -/// \note MUST REMAIN UNCHANGED: \b osMessageGet shall be consistent in every CMSIS-RTOS. -os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec); - -#endif // Message Queues available - - -// ==== Mail Queue Management Functions ==== - -#if (defined (osFeature_MailQ) && (osFeature_MailQ != 0)) // Mail Queues available - -/// \brief Create a Mail Queue Definition. -/// \param name name of the queue -/// \param queue_sz maximum number of messages in queue -/// \param type data type of a single message element -/// \note CAN BE CHANGED: The parameter to \b osMailQDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osMailQDef(name, queue_sz, type) \ -extern osMailQDef_t os_mailQ_def_##name -#else // define the object -#define osMailQDef(name, queue_sz, type) \ -uint32_t os_mailQ_q_##name[4+(queue_sz)]; \ -uint32_t os_mailQ_m_##name[3+((sizeof(type)+3)/4)*(queue_sz)]; \ -void * os_mailQ_p_##name[2] = { (os_mailQ_q_##name), os_mailQ_m_##name }; \ -osMailQDef_t os_mailQ_def_##name = \ -{ (queue_sz), sizeof(type), (os_mailQ_p_##name) } -#endif - -/// \brief Access a Mail Queue Definition. -/// \param name name of the queue -/// \note CAN BE CHANGED: The parameter to \b osMailQ shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osMailQ(name) \ -&os_mailQ_def_##name - -/// Create and Initialize mail queue. -/// \param[in] queue_def reference to the mail queue definition obtain with \ref osMailQ -/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. -/// \return mail queue ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osMailCreate shall be consistent in every CMSIS-RTOS. -osMailQId osMailCreate (osMailQDef_t *queue_def, osThreadId thread_id); - -/// Allocate a memory block from a mail. -/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. -/// \param[in] millisec timeout value or 0 in case of no time-out -/// \return pointer to memory block that can be filled with mail or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osMailAlloc shall be consistent in every CMSIS-RTOS. -void *osMailAlloc (osMailQId queue_id, uint32_t millisec); - -/// Allocate a memory block from a mail and set memory block to zero. -/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. -/// \param[in] millisec timeout value or 0 in case of no time-out -/// \return pointer to memory block that can be filled with mail or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osMailCAlloc shall be consistent in every CMSIS-RTOS. -void *osMailCAlloc (osMailQId queue_id, uint32_t millisec); - -/// Put a mail to a queue. -/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. -/// \param[in] mail memory block previously allocated with \ref osMailAlloc or \ref osMailCAlloc. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMailPut shall be consistent in every CMSIS-RTOS. -osStatus osMailPut (osMailQId queue_id, void *mail); - -/// Get a mail from a queue. -/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. -/// \param[in] millisec timeout value or 0 in case of no time-out -/// \return event that contains mail information or error code. -/// \note MUST REMAIN UNCHANGED: \b osMailGet shall be consistent in every CMSIS-RTOS. -os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec); - -/// Free a memory block from a mail. -/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. -/// \param[in] mail pointer to the memory block that was obtained with \ref osMailGet. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMailFree shall be consistent in every CMSIS-RTOS. -osStatus osMailFree (osMailQId queue_id, void *mail); - -#endif // Mail Queues available - - -#ifdef __cplusplus -} -#endif - -#endif // _CMSIS_OS_H
--- a/mbed-rtos/rtx/os_tcb.h Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -#ifndef OS_TCB_H -#define OS_TCB_H - -/* Types */ -typedef char S8; -typedef unsigned char U8; -typedef short S16; -typedef unsigned short U16; -typedef int S32; -typedef unsigned int U32; -typedef long long S64; -typedef unsigned long long U64; -typedef unsigned char BIT; -typedef unsigned int BOOL; -typedef void (*FUNCP)(void); - -typedef struct OS_TCB { - /* General part: identical for all implementations. */ - U8 cb_type; /* Control Block Type */ - U8 state; /* Task state */ - U8 prio; /* Execution priority */ - U8 task_id; /* Task ID value for optimized TCB access */ - struct OS_TCB *p_lnk; /* Link pointer for ready/sem. wait list */ - struct OS_TCB *p_rlnk; /* Link pointer for sem./mbx lst backwards */ - struct OS_TCB *p_dlnk; /* Link pointer for delay list */ - struct OS_TCB *p_blnk; /* Link pointer for delay list backwards */ - U16 delta_time; /* Time until time out */ - U16 interval_time; /* Time interval for periodic waits */ - U16 events; /* Event flags */ - U16 waits; /* Wait flags */ - void **msg; /* Direct message passing when task waits */ - - /* Hardware dependant part: specific for CM processor */ - U8 stack_frame; /* Stack frame: 0=Basic, 1=Extended */ - U8 reserved; - U16 priv_stack; /* Private stack size in bytes */ - U32 tsk_stack; /* Current task Stack pointer (R13) */ - U32 *stack; /* Pointer to Task Stack memory block */ - - /* Library dependant part */ -#if defined (__CC_ARM) && !defined (__MICROLIB) - /* A memory space for arm standard library. */ - U32 std_libspace[96/4]; -#endif - - /* Task entry point used for uVision debugger */ - FUNCP ptask; /* Task entry address */ -} *P_TCB; - -#endif
--- a/mbed-rtos/rtx/rt_CMSIS.c Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1913 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: rt_CMSIS.c - * Purpose: CMSIS RTOS API - * Rev.: V4.50 - *---------------------------------------------------------------------------- - * - * 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" -#else - #error "Missing __CORTEX_Mx definition" -#endif - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_System.h" -#include "rt_Task.h" -#include "rt_Event.h" -#include "rt_List.h" -#include "rt_Time.h" -#include "rt_Mutex.h" -#include "rt_Semaphore.h" -#include "rt_Mailbox.h" -#include "rt_MemBox.h" -#include "rt_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 != 8) -#error Invalid "osFeature_Semaphore" value! -#endif -#if (osFeature_Wait != 0) -#error osWait not supported! -#endif - - -// ==== Enumeration, structures, defines ==== - -// Service Calls defines - -#if defined (__CC_ARM) /* ARM Compiler */ - -#define __NO_RETURN __declspec(noreturn) - -#define osEvent_type osEvent -#define osEvent_ret_status ret -#define osEvent_ret_value ret -#define osEvent_ret_msg ret -#define osEvent_ret_mail ret - -#define osCallback_type osCallback -#define osCallback_ret ret - -#define SVC_0_1(f,t,...) \ -__svc_indirect(0) t _##f (t(*)()); \ - t f (void); \ -__attribute__((always_inline)) \ -static __inline t __##f (void) { \ - return _##f(f); \ -} - -#define SVC_1_1(f,t,t1,...) \ -__svc_indirect(0) t _##f (t(*)(t1),t1); \ - t f (t1 a1); \ -__attribute__((always_inline)) \ -static __inline t __##f (t1 a1) { \ - return _##f(f,a1); \ -} - -#define SVC_2_1(f,t,t1,t2,...) \ -__svc_indirect(0) t _##f (t(*)(t1,t2),t1,t2); \ - t f (t1 a1, t2 a2); \ -__attribute__((always_inline)) \ -static __inline t __##f (t1 a1, t2 a2) { \ - return _##f(f,a1,a2); \ -} - -#define SVC_3_1(f,t,t1,t2,t3,...) \ -__svc_indirect(0) t _##f (t(*)(t1,t2,t3),t1,t2,t3); \ - t f (t1 a1, t2 a2, t3 a3); \ -__attribute__((always_inline)) \ -static __inline t __##f (t1 a1, t2 a2, t3 a3) { \ - return _##f(f,a1,a2,a3); \ -} - -#define SVC_4_1(f,t,t1,t2,t3,t4,...) \ -__svc_indirect(0) t _##f (t(*)(t1,t2,t3,t4),t1,t2,t3,t4); \ - t f (t1 a1, t2 a2, t3 a3, t4 a4); \ -__attribute__((always_inline)) \ -static __inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ - return _##f(f,a1,a2,a3,a4); \ -} - -#define SVC_1_2 SVC_1_1 -#define SVC_1_3 SVC_1_1 -#define SVC_2_3 SVC_2_1 - -#elif defined (__GNUC__) /* GNU Compiler */ - -#define __NO_RETURN __attribute__((noreturn)) - -typedef uint32_t __attribute__((vector_size(8))) ret64; -typedef uint32_t __attribute__((vector_size(16))) ret128; - -#define RET_pointer __r0 -#define RET_int32_t __r0 -#define RET_osStatus __r0 -#define RET_osPriority __r0 -#define RET_osEvent {(osStatus)__r0, {(uint32_t)__r1}, {(void *)__r2}} -#define RET_osCallback {(void *)__r0, (void *)__r1} - -#define osEvent_type ret128 -#define osEvent_ret_status (ret128){ret.status} -#define osEvent_ret_value (ret128){ret.status, ret.value.v} -#define osEvent_ret_msg (ret128){ret.status, ret.value.v, (uint32_t)ret.def.message_id} -#define osEvent_ret_mail (ret128){ret.status, ret.value.v, (uint32_t)ret.def.mail_id} - -#define osCallback_type ret64 -#define osCallback_ret (ret64) {(uint32_t)ret.fp, (uint32_t)ret.arg} - -#define SVC_ArgN(n) \ - register int __r##n __asm("r"#n); - -#define SVC_ArgR(n,t,a) \ - register t __r##n __asm("r"#n) = a; - -#define SVC_Arg0() \ - SVC_ArgN(0) \ - SVC_ArgN(1) \ - SVC_ArgN(2) \ - SVC_ArgN(3) - -#define SVC_Arg1(t1) \ - SVC_ArgR(0,t1,a1) \ - SVC_ArgN(1) \ - SVC_ArgN(2) \ - SVC_ArgN(3) - -#define SVC_Arg2(t1,t2) \ - SVC_ArgR(0,t1,a1) \ - SVC_ArgR(1,t2,a2) \ - SVC_ArgN(2) \ - SVC_ArgN(3) - -#define SVC_Arg3(t1,t2,t3) \ - SVC_ArgR(0,t1,a1) \ - SVC_ArgR(1,t2,a2) \ - SVC_ArgR(2,t3,a3) \ - SVC_ArgN(3) - -#define SVC_Arg4(t1,t2,t3,t4) \ - SVC_ArgR(0,t1,a1) \ - SVC_ArgR(1,t2,a2) \ - SVC_ArgR(2,t3,a3) \ - SVC_ArgR(3,t4,a4) - -#if (defined (__CORTEX_M0)) -#define SVC_Call(f) \ - __asm volatile \ - ( \ - "ldr r7,="#f"\n\t" \ - "mov r12,r7\n\t" \ - "svc 0" \ - : "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3) \ - : "r" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) \ - : "r7", "r12", "lr", "cc" \ - ); -#else -#define SVC_Call(f) \ - __asm volatile \ - ( \ - "ldr r12,="#f"\n\t" \ - "svc 0" \ - : "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3) \ - : "r" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) \ - : "r12", "lr", "cc" \ - ); -#endif - -#define SVC_0_1(f,t,rv) \ -__attribute__((always_inline)) \ -static inline t __##f (void) { \ - SVC_Arg0(); \ - SVC_Call(f); \ - return (t) rv; \ -} - -#define SVC_1_1(f,t,t1,rv) \ -__attribute__((always_inline)) \ -static inline t __##f (t1 a1) { \ - SVC_Arg1(t1); \ - SVC_Call(f); \ - return (t) rv; \ -} - -#define SVC_2_1(f,t,t1,t2,rv) \ -__attribute__((always_inline)) \ -static inline t __##f (t1 a1, t2 a2) { \ - SVC_Arg2(t1,t2); \ - SVC_Call(f); \ - return (t) rv; \ -} - -#define SVC_3_1(f,t,t1,t2,t3,rv) \ -__attribute__((always_inline)) \ -static inline t __##f (t1 a1, t2 a2, t3 a3) { \ - SVC_Arg3(t1,t2,t3); \ - SVC_Call(f); \ - return (t) rv; \ -} - -#define SVC_4_1(f,t,t1,t2,t3,t4,rv) \ -__attribute__((always_inline)) \ -static inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ - SVC_Arg4(t1,t2,t3,t4); \ - SVC_Call(f); \ - return (t) rv; \ -} - -#define SVC_1_2 SVC_1_1 -#define SVC_1_3 SVC_1_1 -#define SVC_2_3 SVC_2_1 - -#elif defined (__ICCARM__) /* IAR Compiler */ - -#define __NO_RETURN __noreturn - -#define RET_osEvent "=r"(ret.status), "=r"(ret.value), "=r"(ret.def) -#define RET_osCallback "=r"(ret.fp), "=r"(ret.arg) - -#define osEvent_type osEvent -#define osEvent_ret_status ret -#define osEvent_ret_value ret -#define osEvent_ret_msg ret -#define osEvent_ret_mail ret - -#define osCallback_type uint64_t -#define osCallback_ret ((uint64_t)ret.fp | ((uint64_t)ret.arg)<<32) - -#define SVC_Setup(f) \ - __asm( \ - "mov r12,%0\n" \ - :: "r"(&f): "r12" \ - ); - -#define SVC_Ret3() \ - __asm( \ - "ldr r0,[sp,#0]\n" \ - "ldr r1,[sp,#4]\n" \ - "ldr r2,[sp,#8]\n" \ - ); - -#define SVC_0_1(f,t,...) \ -t f (void); \ -_Pragma("swi_number=0") __swi t _##f (void); \ -static inline t __##f (void) { \ - SVC_Setup(f); \ - return _##f(); \ -} - -#define SVC_1_1(f,t,t1,...) \ -t f (t1 a1); \ -_Pragma("swi_number=0") __swi t _##f (t1 a1); \ -static inline t __##f (t1 a1) { \ - SVC_Setup(f); \ - return _##f(a1); \ -} - -#define SVC_2_1(f,t,t1,t2,...) \ -t f (t1 a1, t2 a2); \ -_Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2); \ -static inline t __##f (t1 a1, t2 a2) { \ - SVC_Setup(f); \ - return _##f(a1,a2); \ -} - -#define SVC_3_1(f,t,t1,t2,t3,...) \ -t f (t1 a1, t2 a2, t3 a3); \ -_Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2, t3 a3); \ -static inline t __##f (t1 a1, t2 a2, t3 a3) { \ - SVC_Setup(f); \ - return _##f(a1,a2,a3); \ -} - -#define SVC_4_1(f,t,t1,t2,t3,t4,...) \ -t f (t1 a1, t2 a2, t3 a3, t4 a4); \ -_Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2, t3 a3, t4 a4); \ -static inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ - SVC_Setup(f); \ - return _##f(a1,a2,a3,a4); \ -} - -#define SVC_1_2(f,t,t1,rr) \ -uint64_t f (t1 a1); \ -_Pragma("swi_number=0") __swi uint64_t _##f (t1 a1); \ -static inline t __##f (t1 a1) { \ - t ret; \ - SVC_Setup(f); \ - _##f(a1); \ - __asm("" : rr : :); \ - return ret; \ -} - -#define SVC_1_3(f,t,t1,rr) \ -t f (t1 a1); \ -void f##_ (t1 a1) { \ - f(a1); \ - SVC_Ret3(); \ -} \ -_Pragma("swi_number=0") __swi void _##f (t1 a1); \ -static inline t __##f (t1 a1) { \ - t ret; \ - SVC_Setup(f##_); \ - _##f(a1); \ - __asm("" : rr : :); \ - return ret; \ -} - -#define SVC_2_3(f,t,t1,t2,rr) \ -t f (t1 a1, t2 a2); \ -void f##_ (t1 a1, t2 a2) { \ - f(a1,a2); \ - SVC_Ret3(); \ -} \ -_Pragma("swi_number=0") __swi void _##f (t1 a1, t2 a2); \ -static inline t __##f (t1 a1, t2 a2) { \ - t ret; \ - SVC_Setup(f##_); \ - _##f(a1,a2); \ - __asm("" : rr : :); \ - return ret; \ -} - -#endif - - -// Callback structure -typedef struct { - void *fp; // Function pointer - void *arg; // Function argument -} osCallback; - - -// OS Section definitions -#ifdef OS_SECTIONS_LINK_INFO -extern const uint32_t os_section_id$$Base; -extern const uint32_t os_section_id$$Limit; -#endif - -// OS Timers external resources -extern osThreadDef_t os_thread_def_osTimerThread; -extern osThreadId osThreadId_osTimerThread; -extern osMessageQDef_t os_messageQ_def_osTimerMessageQ; -extern osMessageQId osMessageQId_osTimerMessageQ; - - -// ==== Helper Functions ==== - -/// Convert timeout in millisec to system ticks -static uint32_t rt_ms2tick (uint32_t millisec) { - uint32_t tick; - - if (millisec == osWaitForever) return 0xFFFF; // Indefinite timeout - if (millisec > 4000000) return 0xFFFE; // Max ticks supported - - tick = ((1000 * millisec) + os_clockrate - 1) / os_clockrate; - if (tick > 0xFFFE) return 0xFFFE; - - return tick; -} - -/// Convert Thread ID to TCB pointer -static P_TCB rt_tid2ptcb (osThreadId thread_id) { - P_TCB ptcb; - - if (thread_id == NULL) return NULL; - - if ((uint32_t)thread_id & 3) return NULL; - -#ifdef OS_SECTIONS_LINK_INFO - if ((os_section_id$$Base != 0) && (os_section_id$$Limit != 0)) { - if (thread_id < (osThreadId)os_section_id$$Base) return NULL; - if (thread_id >= (osThreadId)os_section_id$$Limit) return NULL; - } -#endif - - ptcb = thread_id; - - if (ptcb->cb_type != TCB) return NULL; - - return ptcb; -} - -/// Convert ID pointer to Object pointer -static void *rt_id2obj (void *id) { - - if ((uint32_t)id & 3) return NULL; - -#ifdef OS_SECTIONS_LINK_INFO - if ((os_section_id$$Base != 0) && (os_section_id$$Limit != 0)) { - if (id < (void *)os_section_id$$Base) return NULL; - if (id >= (void *)os_section_id$$Limit) return NULL; - } -#endif - - return id; -} - - -// ==== Kernel Control ==== - -uint8_t os_initialized; // Kernel Initialized flag -uint8_t os_running; // Kernel Running flag - -// Kernel Control Service Calls declarations -SVC_0_1(svcKernelInitialize, osStatus, RET_osStatus) -SVC_0_1(svcKernelStart, osStatus, RET_osStatus) -SVC_0_1(svcKernelRunning, int32_t, RET_int32_t) - -extern void sysThreadError (osStatus status); -osThreadId svcThreadCreate (osThreadDef_t *thread_def, void *argument); -osMessageQId svcMessageCreate (osMessageQDef_t *queue_def, osThreadId thread_id); - -// Kernel Control Service Calls - -/// Initialize the RTOS Kernel for creating objects -osStatus svcKernelInitialize (void) { - if (os_initialized) return osOK; - - rt_sys_init(); // RTX System Initialization - os_tsk.run->prio = 255; // Highest priority - - sysThreadError(osOK); - - os_initialized = 1; - - return osOK; -} - -/// Start the RTOS Kernel -osStatus svcKernelStart (void) { - - if (os_running) return osOK; - - // Create OS Timers resources (Message Queue & Thread) - osMessageQId_osTimerMessageQ = svcMessageCreate (&os_messageQ_def_osTimerMessageQ, NULL); - osThreadId_osTimerThread = svcThreadCreate(&os_thread_def_osTimerThread, NULL); - - rt_tsk_prio(0, 0); // Lowest priority - __set_PSP(os_tsk.run->tsk_stack + 8*4); // New context - os_tsk.run = NULL; // Force context switch - - rt_sys_start(); - - os_running = 1; - - return osOK; -} - -/// Check if the RTOS kernel is already started -int32_t svcKernelRunning(void) { - return os_running; -} - -// Kernel Control Public API - -/// Initialize the RTOS Kernel for creating objects -osStatus osKernelInitialize (void) { - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR - if ((__get_CONTROL() & 1) == 0) { // Privileged mode - return svcKernelInitialize(); - } else { - return __svcKernelInitialize(); - } -} - -/// Start the RTOS Kernel -osStatus osKernelStart (void) { - uint32_t stack[8]; - - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR - switch (__get_CONTROL() & 0x03) { - case 0x00: // Privileged Thread mode & MSP - __set_PSP((uint32_t)(stack + 8)); // Initial PSP - if (os_flags & 1) { - __set_CONTROL(0x02); // Set Privileged Thread mode & PSP - } else { - __set_CONTROL(0x03); // Set Unprivileged Thread mode & PSP - } - __DSB(); - __ISB(); - break; - case 0x01: // Unprivileged Thread mode & MSP - return osErrorOS; - case 0x02: // Privileged Thread mode & PSP - if ((os_flags & 1) == 0) { // Unprivileged Thread mode requested - __set_CONTROL(0x03); // Set Unprivileged Thread mode & PSP - __DSB(); - __ISB(); - } - break; - case 0x03: // Unprivileged Thread mode & PSP - if (os_flags & 1) return osErrorOS; // Privileged Thread mode requested - break; - } - return __svcKernelStart(); -} - -/// Check if the RTOS kernel is already started -int32_t osKernelRunning(void) { - if ((__get_IPSR() != 0) || ((__get_CONTROL() & 1) == 0)) { - // in ISR or Privileged - return os_running; - } else { - return __svcKernelRunning(); - } -} - - -// ==== Thread Management ==== - -__NO_RETURN void osThreadExit (void); - -// Thread Service Calls declarations -SVC_2_1(svcThreadCreate, osThreadId, osThreadDef_t *, void *, RET_pointer) -SVC_0_1(svcThreadGetId, osThreadId, RET_pointer) -SVC_1_1(svcThreadTerminate, osStatus, osThreadId, RET_osStatus) -SVC_0_1(svcThreadYield, osStatus, RET_osStatus) -SVC_2_1(svcThreadSetPriority, osStatus, osThreadId, osPriority, RET_osStatus) -SVC_1_1(svcThreadGetPriority, osPriority, osThreadId, RET_osPriority) - -// Thread Service Calls -extern OS_TID rt_get_TID (void); -extern void rt_init_context (P_TCB p_TCB, U8 priority, FUNCP task_body); - -/// Create a thread and add it to Active Threads and set it to state READY -osThreadId svcThreadCreate (osThreadDef_t *thread_def, void *argument) { - P_TCB ptcb; - - if ((thread_def == NULL) || - (thread_def->pthread == NULL) || - (thread_def->tpriority <= osPriorityIdle) || - (thread_def->tpriority > osPriorityRealtime) || - (thread_def->stacksize == 0) || - (thread_def->stack_pointer == NULL) ) { - sysThreadError(osErrorParameter); - return NULL; - } - - U8 priority = thread_def->tpriority - osPriorityIdle + 1; - P_TCB task_context = &thread_def->tcb; - - /* If "size != 0" use a private user provided stack. */ - task_context->stack = (U32*)thread_def->stack_pointer; - task_context->priv_stack = thread_def->stacksize; - /* Pass parameter 'argv' to 'rt_init_context' */ - task_context->msg = argument; - /* For 'size == 0' system allocates the user stack from the memory pool. */ - rt_init_context (task_context, priority, (FUNCP)thread_def->pthread); - - /* Find a free entry in 'os_active_TCB' table. */ - OS_TID tsk = rt_get_TID (); - os_active_TCB[tsk-1] = task_context; - task_context->task_id = tsk; - DBG_TASK_NOTIFY(task_context, __TRUE); - rt_dispatch (task_context); - - ptcb = (P_TCB)os_active_TCB[tsk - 1]; // TCB pointer - - *((uint32_t *)ptcb->tsk_stack + 13) = (uint32_t)osThreadExit; - - return ptcb; -} - -/// Return the thread ID of the current running thread -osThreadId svcThreadGetId (void) { - OS_TID tsk; - - tsk = rt_tsk_self(); - if (tsk == 0) return NULL; - return (P_TCB)os_active_TCB[tsk - 1]; -} - -/// Terminate execution of a thread and remove it from ActiveThreads -osStatus svcThreadTerminate (osThreadId thread_id) { - OS_RESULT res; - P_TCB ptcb; - - ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) return osErrorParameter; - - res = rt_tsk_delete(ptcb->task_id); // Delete task - - if (res == OS_R_NOK) return osErrorResource; // Delete task failed - - return osOK; -} - -/// Pass control to next thread that is in state READY -osStatus svcThreadYield (void) { - rt_tsk_pass(); // Pass control to next task - return osOK; -} - -/// Change prority 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 prority 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 prority 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 prority 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 signal) { - P_TCB ptcb; - int32_t sig; - - ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) return 0x80000000; - - if (signal & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000; - - sig = ptcb->events; // Previous signal flags - - rt_evt_set(signal, 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 signal) { - P_TCB ptcb; - int32_t sig; - - ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) return 0x80000000; - - if (signal & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000; - - sig = ptcb->events; // Previous signal flags - - rt_evt_clr(signal, 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 signal) { - P_TCB ptcb; - int32_t sig; - - ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) return 0x80000000; - - if (signal & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000; - - sig = ptcb->events; // Previous signal flags - - isr_evt_set(signal, 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 signal) { - if (__get_IPSR() != 0) { // in ISR - return isrSignalSet(thread_id, signal); - } else { // in Thread - return __svcSignalSet(thread_id, signal); - } -} - -/// Clear the specified Signal Flags of an active thread -int32_t osSignalClear (osThreadId thread_id, int32_t signal) { - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR - return __svcSignalClear(thread_id, signal); -} - -/// 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; - - 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; - - 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; - return osMessagePut(*((void **)queue_id), (uint32_t)mail, 0); -} - -/// Get a mail from a queue -os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec) { - osEvent ret; - - if (queue_id == NULL) { - ret.status = osErrorParameter; - return ret; - } - - ret = osMessageGet(*((void **)queue_id), millisec); - if (ret.status == osEventMessage) ret.status = osEventMail; - - return ret; -}
--- a/mbed-rtos/rtx/rt_Event.c Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,182 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_EVENT.C - * Purpose: Implements waits and wake-ups for event flags - * Rev.: V4.50 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_System.h" -#include "rt_Event.h" -#include "rt_List.h" -#include "rt_Task.h" -#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; - rt_ret_val2(p_tcb, 0x08/*osEventSignal*/, p_tcb->waits); - 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; - rt_ret_val2(p_CB, 0x08/*osEventSignal*/, p_CB->waits); - rt_put_prio (&os_rdy, p_CB); - } - } -} - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/mbed-rtos/rtx/rt_Event.h Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_EVENT.H - * Purpose: Implements waits and wake-ups for event flags - * Rev.: V4.50 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Functions */ -extern OS_RESULT rt_evt_wait (U16 wait_flags, U16 timeout, BOOL and_wait); -extern void rt_evt_set (U16 event_flags, OS_TID task_id); -extern void rt_evt_clr (U16 clear_flags, OS_TID task_id); -extern void isr_evt_set (U16 event_flags, OS_TID task_id); -extern U16 rt_evt_get (void); -extern void rt_evt_psh (P_TCB p_CB, U16 set_flags); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/mbed-rtos/rtx/rt_HAL_CM.h Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,267 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_HAL_CM.H - * Purpose: Hardware Abstraction Layer for Cortex-M definitions - * Rev.: V4.50 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Definitions */ -#define INITIAL_xPSR 0x01000000 -#define DEMCR_TRCENA 0x01000000 -#define ITM_ITMENA 0x00000001 -#define MAGIC_WORD 0xE25A2EA5 - -#if defined (__CC_ARM) /* ARM Compiler */ - -#if ((__TARGET_ARCH_7_M || __TARGET_ARCH_7E_M) && !NO_EXCLUSIVE_ACCESS) - #define __USE_EXCLUSIVE_ACCESS -#else - #undef __USE_EXCLUSIVE_ACCESS -#endif - -#elif defined (__GNUC__) /* GNU Compiler */ - -#undef __USE_EXCLUSIVE_ACCESS - -#if defined (__CORTEX_M0) -#define __TARGET_ARCH_6S_M 1 -#else -#define __TARGET_ARCH_6S_M 0 -#endif - -#if defined (__VFP_FP__) && !defined(__SOFTFP__) -#define __TARGET_FPU_VFP 1 -#else -#define __TARGET_FPU_VFP 0 -#endif - -#define __inline inline -#define __weak __attribute__((weak)) - -#ifndef __CMSIS_GENERIC - -__attribute__((always_inline)) static inline void __enable_irq(void) -{ - __asm volatile ("cpsie i"); -} - -__attribute__((always_inline)) static inline U32 __disable_irq(void) -{ - U32 result; - - __asm volatile ("mrs %0, primask" : "=r" (result)); - __asm volatile ("cpsid i"); - return(result & 1); -} - -#endif - -__attribute__(( always_inline)) static inline U8 __clz(U32 value) -{ - U8 result; - - __asm volatile ("clz %0, %1" : "=r" (result) : "r" (value)); - return(result); -} - -#elif defined (__ICCARM__) /* IAR Compiler */ - -#undef __USE_EXCLUSIVE_ACCESS - -#if (__CORE__ == __ARM6M__) -#define __TARGET_ARCH_6S_M 1 -#else -#define __TARGET_ARCH_6S_M 0 -#endif - -#if defined __ARMVFP__ -#define __TARGET_FPU_VFP 1 -#else -#define __TARGET_FPU_VFP 0 -#endif - -#define __inline inline - -#ifndef __CMSIS_GENERIC - -static inline void __enable_irq(void) -{ - __asm volatile ("cpsie i"); -} - -static inline U32 __disable_irq(void) -{ - U32 result; - - __asm volatile ("mrs %0, primask" : "=r" (result)); - __asm volatile ("cpsid i"); - return(result & 1); -} - -#endif - -static inline U8 __clz(U32 value) -{ - U8 result; - - __asm volatile ("clz %0, %1" : "=r" (result) : "r" (value)); - return(result); -} - -#endif - -/* NVIC registers */ -#define NVIC_ST_CTRL (*((volatile U32 *)0xE000E010)) -#define NVIC_ST_RELOAD (*((volatile U32 *)0xE000E014)) -#define NVIC_ST_CURRENT (*((volatile U32 *)0xE000E018)) -#define NVIC_ISER ((volatile U32 *)0xE000E100) -#define NVIC_ICER ((volatile U32 *)0xE000E180) -#define NVIC_IP ((volatile U8 *)0xE000E400) -#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 -#define OS_X_INIT(n) NVIC_IP[n] = 0xFF; \ - NVIC_ISER[n>>5] = 1 << (n & 0x1F) -#define OS_X_LOCK(n) NVIC_ICER[n>>5] = 1 << (n & 0x1F) -#define OS_X_UNLOCK(n) NVIC_ISER[n>>5] = 1 << (n & 0x1F) - -/* Core Debug registers */ -#define DEMCR (*((volatile U32 *)0xE000EDFC)) - -/* ITM registers */ -#define ITM_CONTROL (*((volatile U32 *)0xE0000E80)) -#define ITM_ENABLE (*((volatile U32 *)0xE0000E00)) -#define ITM_PORT30_U32 (*((volatile U32 *)0xE0000078)) -#define ITM_PORT31_U32 (*((volatile U32 *)0xE000007C)) -#define ITM_PORT31_U16 (*((volatile U16 *)0xE000007C)) -#define ITM_PORT31_U8 (*((volatile U8 *)0xE000007C)) - -/* Variables */ -extern BIT dbg_msg; - -/* Functions */ -#ifdef __USE_EXCLUSIVE_ACCESS - #define rt_inc(p) while(__strex((__ldrex(p)+1),p)) - #define rt_dec(p) while(__strex((__ldrex(p)-1),p)) -#else - #define rt_inc(p) __disable_irq();(*p)++;__enable_irq(); - #define rt_dec(p) __disable_irq();(*p)--;__enable_irq(); -#endif - -__inline static U32 rt_inc_qi (U32 size, U8 *count, U8 *first) { - U32 cnt,c2; -#ifdef __USE_EXCLUSIVE_ACCESS - do { - if ((cnt = __ldrex(count)) == size) { - __clrex(); - return (cnt); } - } while (__strex(cnt+1, count)); - do { - c2 = (cnt = __ldrex(first)) + 1; - if (c2 == size) c2 = 0; - } while (__strex(c2, first)); -#else - __disable_irq(); - if ((cnt = *count) < size) { - *count = cnt+1; - c2 = (cnt = *first) + 1; - if (c2 == size) c2 = 0; - *first = c2; - } - __enable_irq (); -#endif - return (cnt); -} - -__inline static void rt_systick_init (void) { - NVIC_ST_RELOAD = os_trv; - NVIC_ST_CURRENT = 0; - NVIC_ST_CTRL = 0x0007; - NVIC_SYS_PRI3 |= 0xFF000000; -} - -__inline static void rt_svc_init (void) { -#if !(__TARGET_ARCH_6S_M) - int sh,prigroup; -#endif - NVIC_SYS_PRI3 |= 0x00FF0000; -#if (__TARGET_ARCH_6S_M) - NVIC_SYS_PRI2 |= (NVIC_SYS_PRI3<<(8+1)) & 0xFC000000; -#else - sh = 8 - __clz (~((NVIC_SYS_PRI3 << 8) & 0xFF000000)); - prigroup = ((NVIC_AIR_CTRL >> 8) & 0x07); - if (prigroup >= sh) { - sh = prigroup + 1; - } - NVIC_SYS_PRI2 = ((0xFEFFFFFF << sh) & 0xFF000000) | (NVIC_SYS_PRI2 & 0x00FFFFFF); -#endif -} - -extern void rt_set_PSP (U32 stack); -extern U32 rt_get_PSP (void); -extern void os_set_env (void); -extern void *_alloc_box (void *box_mem); -extern int _free_box (void *box_mem, void *box); - -extern void rt_init_stack (P_TCB p_TCB, FUNCP task_body); -extern void rt_ret_val (P_TCB p_TCB, U32 v0); -extern void rt_ret_val2 (P_TCB p_TCB, U32 v0, U32 v1); - -extern void dbg_init (void); -extern void dbg_task_notify (P_TCB p_tcb, BOOL create); -extern void dbg_task_switch (U32 task_id); - -#ifdef DBG_MSG -#define DBG_INIT() dbg_init() -#define DBG_TASK_NOTIFY(p_tcb,create) if (dbg_msg) dbg_task_notify(p_tcb,create) -#define DBG_TASK_SWITCH(task_id) if (dbg_msg && (os_tsk.new!=os_tsk.run)) \ - dbg_task_switch(task_id) -#else -#define DBG_INIT() -#define DBG_TASK_NOTIFY(p_tcb,create) -#define DBG_TASK_SWITCH(task_id) -#endif - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/mbed-rtos/rtx/rt_List.c Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,320 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_LIST.C - * Purpose: Functions for the management of different lists - * Rev.: V4.50 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_System.h" -#include "rt_List.h" -#include "rt_Task.h" -#include "rt_Time.h" -#include "rt_HAL_CM.h" - -/*---------------------------------------------------------------------------- - * Global Variables - *---------------------------------------------------------------------------*/ - -/* List head of chained ready tasks */ -struct OS_XCB os_rdy; -/* List head of chained delay tasks */ -struct OS_XCB os_dly; - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_put_prio -----------------------------------*/ - -void rt_put_prio (P_XCB p_CB, P_TCB p_task) { - /* Put task identified with "p_task" into list ordered by priority. */ - /* "p_CB" points to head of list; list has always an element at end with */ - /* a priority less than "p_task->prio". */ - P_TCB p_CB2; - U32 prio; - BOOL sem_mbx = __FALSE; - - if (p_CB->cb_type == SCB || p_CB->cb_type == MCB || p_CB->cb_type == MUCB) { - sem_mbx = __TRUE; - } - prio = p_task->prio; - p_CB2 = p_CB->p_lnk; - /* Search for an entry in the list */ - while (p_CB2 != NULL && prio <= p_CB2->prio) { - p_CB = (P_XCB)p_CB2; - p_CB2 = p_CB2->p_lnk; - } - /* Entry found, insert the task into the list */ - p_task->p_lnk = p_CB2; - p_CB->p_lnk = p_task; - if (sem_mbx) { - if (p_CB2 != NULL) { - p_CB2->p_rlnk = p_task; - } - p_task->p_rlnk = (P_TCB)p_CB; - } - else { - p_task->p_rlnk = NULL; - } -} - - -/*--------------------------- rt_get_first ----------------------------------*/ - -P_TCB rt_get_first (P_XCB p_CB) { - /* Get task at head of list: it is the task with highest priority. */ - /* "p_CB" points to head of list. */ - P_TCB p_first; - - p_first = p_CB->p_lnk; - p_CB->p_lnk = p_first->p_lnk; - if (p_CB->cb_type == SCB || p_CB->cb_type == MCB || p_CB->cb_type == MUCB) { - if (p_first->p_lnk != NULL) { - p_first->p_lnk->p_rlnk = (P_TCB)p_CB; - p_first->p_lnk = NULL; - } - p_first->p_rlnk = NULL; - } - else { - p_first->p_lnk = NULL; - } - return (p_first); -} - - -/*--------------------------- rt_put_rdy_first ------------------------------*/ - -void rt_put_rdy_first (P_TCB p_task) { - /* Put task identified with "p_task" at the head of the ready list. The */ - /* task must have at least a priority equal to highest priority in list. */ - p_task->p_lnk = os_rdy.p_lnk; - p_task->p_rlnk = NULL; - os_rdy.p_lnk = p_task; -} - - -/*--------------------------- rt_get_same_rdy_prio --------------------------*/ - -P_TCB rt_get_same_rdy_prio (void) { - /* Remove a task of same priority from ready list if any exists. Other- */ - /* wise return NULL. */ - P_TCB p_first; - - p_first = os_rdy.p_lnk; - if (p_first->prio == os_tsk.run->prio) { - os_rdy.p_lnk = os_rdy.p_lnk->p_lnk; - return (p_first); - } - return (NULL); -} - - -/*--------------------------- rt_resort_prio --------------------------------*/ - -void rt_resort_prio (P_TCB p_task) { - /* Re-sort ordered lists after the priority of 'p_task' has changed. */ - P_TCB p_CB; - - if (p_task->p_rlnk == NULL) { - if (p_task->state == READY) { - /* Task is chained into READY list. */ - p_CB = (P_TCB)&os_rdy; - goto res; - } - } - else { - p_CB = p_task->p_rlnk; - while (p_CB->cb_type == TCB) { - /* Find a header of this task chain list. */ - p_CB = p_CB->p_rlnk; - } -res:rt_rmv_list (p_task); - rt_put_prio ((P_XCB)p_CB, p_task); - } -} - - -/*--------------------------- rt_put_dly ------------------------------------*/ - -void rt_put_dly (P_TCB p_task, U16 delay) { - /* Put a task identified with "p_task" into chained delay wait list using */ - /* a delay value of "delay". */ - P_TCB p; - U32 delta,idelay = delay; - - p = (P_TCB)&os_dly; - if (p->p_dlnk == NULL) { - /* Delay list empty */ - delta = 0; - goto last; - } - delta = os_dly.delta_time; - while (delta < idelay) { - if (p->p_dlnk == NULL) { - /* End of list found */ -last: p_task->p_dlnk = NULL; - p->p_dlnk = p_task; - p_task->p_blnk = p; - p->delta_time = (U16)(idelay - delta); - p_task->delta_time = 0; - return; - } - p = p->p_dlnk; - delta += p->delta_time; - } - /* Right place found */ - p_task->p_dlnk = p->p_dlnk; - p->p_dlnk = p_task; - p_task->p_blnk = p; - if (p_task->p_dlnk != NULL) { - p_task->p_dlnk->p_blnk = p_task; - } - p_task->delta_time = (U16)(delta - idelay); - p->delta_time -= p_task->delta_time; -} - - -/*--------------------------- rt_dec_dly ------------------------------------*/ - -void rt_dec_dly (void) { - /* Decrement delta time of list head: remove tasks having a value of zero.*/ - P_TCB p_rdy; - - if (os_dly.p_dlnk == NULL) { - return; - } - os_dly.delta_time--; - while ((os_dly.delta_time == 0) && (os_dly.p_dlnk != NULL)) { - p_rdy = os_dly.p_dlnk; - if (p_rdy->p_rlnk != NULL) { - /* Task is really enqueued, remove task from semaphore/mailbox */ - /* timeout waiting list. */ - p_rdy->p_rlnk->p_lnk = p_rdy->p_lnk; - if (p_rdy->p_lnk != NULL) { - p_rdy->p_lnk->p_rlnk = p_rdy->p_rlnk; - p_rdy->p_lnk = NULL; - } - p_rdy->p_rlnk = NULL; - } - rt_put_prio (&os_rdy, p_rdy); - os_dly.delta_time = p_rdy->delta_time; - if (p_rdy->state == WAIT_ITV) { - /* Calculate the next time for interval wait. */ - p_rdy->delta_time = p_rdy->interval_time + (U16)os_time; - } - p_rdy->state = READY; - os_dly.p_dlnk = p_rdy->p_dlnk; - if (p_rdy->p_dlnk != NULL) { - p_rdy->p_dlnk->p_blnk = (P_TCB)&os_dly; - p_rdy->p_dlnk = NULL; - } - p_rdy->p_blnk = NULL; - } -} - - -/*--------------------------- rt_rmv_list -----------------------------------*/ - -void rt_rmv_list (P_TCB p_task) { - /* Remove task identified with "p_task" from ready, semaphore or mailbox */ - /* waiting list if enqueued. */ - P_TCB p_b; - - if (p_task->p_rlnk != NULL) { - /* A task is enqueued in semaphore / mailbox waiting list. */ - p_task->p_rlnk->p_lnk = p_task->p_lnk; - if (p_task->p_lnk != NULL) { - p_task->p_lnk->p_rlnk = p_task->p_rlnk; - } - return; - } - - p_b = (P_TCB)&os_rdy; - while (p_b != NULL) { - /* Search the ready list for task "p_task" */ - if (p_b->p_lnk == p_task) { - p_b->p_lnk = p_task->p_lnk; - return; - } - p_b = p_b->p_lnk; - } -} - - -/*--------------------------- rt_rmv_dly ------------------------------------*/ - -void rt_rmv_dly (P_TCB p_task) { - /* Remove task identified with "p_task" from delay list if enqueued. */ - P_TCB p_b; - - p_b = p_task->p_blnk; - if (p_b != NULL) { - /* Task is really enqueued */ - p_b->p_dlnk = p_task->p_dlnk; - if (p_task->p_dlnk != NULL) { - /* 'p_task' is in the middle of list */ - p_b->delta_time += p_task->delta_time; - p_task->p_dlnk->p_blnk = p_b; - p_task->p_dlnk = NULL; - } - else { - /* 'p_task' is at the end of list */ - p_b->delta_time = 0; - } - p_task->p_blnk = NULL; - } -} - - -/*--------------------------- rt_psq_enq ------------------------------------*/ - -void rt_psq_enq (OS_ID entry, U32 arg) { - /* Insert post service request "entry" into ps-queue. */ - U32 idx; - - idx = rt_inc_qi (os_psq->size, &os_psq->count, &os_psq->first); - if (idx < os_psq->size) { - os_psq->q[idx].id = entry; - os_psq->q[idx].arg = arg; - } - else { - os_error (OS_ERR_FIFO_OVF); - } -} - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/mbed-rtos/rtx/rt_List.h Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_LIST.H - * Purpose: Functions for the management of different lists - * Rev.: V4.50 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Definitions */ - -/* Values for 'cb_type' */ -#define TCB 0 -#define MCB 1 -#define SCB 2 -#define MUCB 3 -#define HCB 4 - -/* Variables */ -extern struct OS_XCB os_rdy; -extern struct OS_XCB os_dly; - -/* Functions */ -extern void rt_put_prio (P_XCB p_CB, P_TCB p_task); -extern P_TCB rt_get_first (P_XCB p_CB); -extern void rt_put_rdy_first (P_TCB p_task); -extern P_TCB rt_get_same_rdy_prio (void); -extern void rt_resort_prio (P_TCB p_task); -extern void rt_put_dly (P_TCB p_task, U16 delay); -extern void rt_dec_dly (void); -extern void rt_rmv_list (P_TCB p_task); -extern void rt_rmv_dly (P_TCB p_task); -extern void rt_psq_enq (OS_ID entry, U32 arg); - -/* This is a fast macro generating in-line code */ -#define rt_rdy_prio(void) (os_rdy.p_lnk->prio) - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/mbed-rtos/rtx/rt_Mailbox.c Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,285 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_MAILBOX.C - * Purpose: Implements waits and wake-ups for mailbox messages - * Rev.: V4.50 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_System.h" -#include "rt_List.h" -#include "rt_Mailbox.h" -#include "rt_MemBox.h" -#include "rt_Task.h" -#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->state == 1) { - /* A task is waiting for message */ - p_TCB = rt_get_first ((P_XCB)p_MCB); - if (p_MCB->p_lnk == NULL) { - p_MCB->state = 0; - } - rt_ret_val2(p_TCB, 0x10/*osEventMessage*/, (U32)p_msg); - 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->state == 2) { - /* A task is waiting to send message */ - p_TCB = rt_get_first ((P_XCB)p_MCB); - if (p_MCB->p_lnk == NULL) { - p_MCB->state = 0; - } - rt_ret_val(p_TCB, 0/*osOK*/); - 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); - 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; - - switch (p_CB->state) { - 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); - if (p_CB->p_lnk == NULL) { - p_CB->state = 0; - } - rt_ret_val(p_TCB, (U32)mem); - p_TCB->state = READY; - rt_rmv_dly (p_TCB); - rt_put_prio (&os_rdy, p_TCB); - break; - case 2: - /* Task is waiting to send a message, remove it from the waiting list */ - p_TCB = rt_get_first ((P_XCB)p_CB); - if (p_CB->p_lnk == NULL) { - p_CB->state = 0; - } - rt_ret_val(p_TCB, 0/*osOK*/); - 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); - if (p_CB->p_lnk == NULL) { - p_CB->state = 0; - } - rt_ret_val2(p_TCB, 0x10/*osEventMessage*/, (U32)p_msg); - p_TCB->state = READY; - rt_rmv_dly (p_TCB); - rt_put_prio (&os_rdy, p_TCB); - break; - default: - /* 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); - } - break; - } -} - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/mbed-rtos/rtx/rt_Mailbox.h Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_MAILBOX.H - * Purpose: Implements waits and wake-ups for mailbox messages - * Rev.: V4.50 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Functions */ -extern void rt_mbx_init (OS_ID mailbox, U16 mbx_size); -extern OS_RESULT rt_mbx_send (OS_ID mailbox, void *p_msg, U16 timeout); -extern OS_RESULT rt_mbx_wait (OS_ID mailbox, void **message, U16 timeout); -extern OS_RESULT rt_mbx_check (OS_ID mailbox); -extern void isr_mbx_send (OS_ID mailbox, void *p_msg); -extern OS_RESULT isr_mbx_receive (OS_ID mailbox, void **message); -extern void rt_mbx_psh (P_MCB p_CB, void *p_msg); - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/mbed-rtos/rtx/rt_MemBox.c Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,166 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_MEMBOX.C - * Purpose: Interface functions for fixed memory block management system - * Rev.: V4.50 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_System.h" -#include "rt_MemBox.h" -#include "rt_HAL_CM.h" - -/*---------------------------------------------------------------------------- - * Global Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- _init_box -------------------------------------*/ - -int _init_box (void *box_mem, U32 box_size, U32 blk_size) { - /* Initialize memory block system, returns 0 if OK, 1 if fails. */ - void *end; - void *blk; - void *next; - U32 sizeof_bm; - - /* Create memory structure. */ - if (blk_size & BOX_ALIGN_8) { - /* Memory blocks 8-byte aligned. */ - blk_size = ((blk_size & ~BOX_ALIGN_8) + 7) & ~7; - sizeof_bm = (sizeof (struct OS_BM) + 7) & ~7; - } - else { - /* Memory blocks 4-byte aligned. */ - blk_size = (blk_size + 3) & ~3; - sizeof_bm = sizeof (struct OS_BM); - } - if (blk_size == 0) { - return (1); - } - if ((blk_size + sizeof_bm) > box_size) { - return (1); - } - /* Create a Memory structure. */ - blk = ((U8 *) box_mem) + sizeof_bm; - ((P_BM) box_mem)->free = blk; - end = ((U8 *) box_mem) + box_size; - ((P_BM) box_mem)->end = end; - ((P_BM) box_mem)->blk_size = blk_size; - - /* Link all free blocks using offsets. */ - end = ((U8 *) end) - blk_size; - while (1) { - next = ((U8 *) blk) + blk_size; - if (next > end) break; - *((void **)blk) = next; - blk = next; - } - /* end marker */ - *((void **)blk) = 0; - return (0); -} - -/*--------------------------- rt_alloc_box ----------------------------------*/ - -void *rt_alloc_box (void *box_mem) { - /* Allocate a memory block and return start address. */ - void **free; -#ifndef __USE_EXCLUSIVE_ACCESS - int irq_dis; - - irq_dis = __disable_irq (); - free = ((P_BM) box_mem)->free; - if (free) { - ((P_BM) box_mem)->free = *free; - } - if (!irq_dis) __enable_irq (); -#else - do { - if ((free = (void **)__ldrex(&((P_BM) box_mem)->free)) == 0) { - __clrex(); - break; - } - } while (__strex((U32)*free, &((P_BM) box_mem)->free)); -#endif - return (free); -} - - -/*--------------------------- _calloc_box -----------------------------------*/ - -void *_calloc_box (void *box_mem) { - /* Allocate a 0-initialized memory block and return start address. */ - void *free; - U32 *p; - U32 i; - - free = _alloc_box (box_mem); - if (free) { - p = free; - for (i = ((P_BM) box_mem)->blk_size; i; i -= 4) { - *p = 0; - p++; - } - } - return (free); -} - - -/*--------------------------- rt_free_box -----------------------------------*/ - -int rt_free_box (void *box_mem, void *box) { - /* Free a memory block, returns 0 if OK, 1 if box does not belong to box_mem */ -#ifndef __USE_EXCLUSIVE_ACCESS - int irq_dis; -#endif - - if (box < box_mem || box >= ((P_BM) box_mem)->end) { - return (1); - } - -#ifndef __USE_EXCLUSIVE_ACCESS - irq_dis = __disable_irq (); - *((void **)box) = ((P_BM) box_mem)->free; - ((P_BM) box_mem)->free = box; - if (!irq_dis) __enable_irq (); -#else - do { - *((void **)box) = (void *)__ldrex(&((P_BM) box_mem)->free); - } while (__strex ((U32)box, &((P_BM) box_mem)->free)); -#endif - return (0); -} - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/mbed-rtos/rtx/rt_MemBox.h Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_MEMBOX.H - * Purpose: Interface functions for fixed memory block management system - * Rev.: V4.50 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Functions */ -#define rt_init_box _init_box -#define rt_calloc_box _calloc_box -extern int _init_box (void *box_mem, U32 box_size, U32 blk_size); -extern void *rt_alloc_box (void *box_mem); -extern void * _calloc_box (void *box_mem); -extern int rt_free_box (void *box_mem, void *box); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/mbed-rtos/rtx/rt_Mutex.c Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,189 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_MUTEX.C - * Purpose: Implements mutex synchronization objects - * Rev.: V4.50 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_List.h" -#include "rt_Task.h" -#include "rt_Mutex.h" -#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 ---------------------------------*/ -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); -} - -/*--------------------------- 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); - rt_ret_val(p_TCB, 0/*osOK*/); - rt_rmv_dly (p_TCB); - /* A waiting task becomes the owner of this mutex. */ - p_MCB->level = 1; - p_MCB->owner = p_TCB; - p_MCB->prio = p_TCB->prio; - /* Priority inversion, check which task continues. */ - if (os_tsk.run->prio >= rt_rdy_prio()) { - rt_dispatch (p_TCB); - } - else { - /* Ready task has higher priority than running task. */ - rt_put_prio (&os_rdy, os_tsk.run); - rt_put_prio (&os_rdy, p_TCB); - os_tsk.run->state = READY; - p_TCB->state = READY; - rt_dispatch (NULL); - } - } - else { - /* Check if own priority raised by priority inversion. */ - if (rt_rdy_prio() > os_tsk.run->prio) { - rt_put_prio (&os_rdy, os_tsk.run); - os_tsk.run->state = READY; - rt_dispatch (NULL); - } - } - return (OS_R_OK); -} - - -/*--------------------------- rt_mut_wait -----------------------------------*/ - -OS_RESULT rt_mut_wait (OS_ID mutex, U16 timeout) { - /* Wait for a mutex, continue when mutex is free. */ - P_MUCB p_MCB = mutex; - - if (p_MCB->level == 0) { - p_MCB->owner = os_tsk.run; - p_MCB->prio = os_tsk.run->prio; - goto inc; - } - if (p_MCB->owner == os_tsk.run) { - /* OK, running task is the owner of this mutex. */ -inc:p_MCB->level++; - return (OS_R_OK); - } - /* Mutex owned by another task, wait until released. */ - if (timeout == 0) { - return (OS_R_TMO); - } - /* Raise the owner task priority if lower than current priority. */ - /* This priority inversion is called priority inheritance. */ - if (p_MCB->prio < os_tsk.run->prio) { - p_MCB->owner->prio = os_tsk.run->prio; - rt_resort_prio (p_MCB->owner); - } - if (p_MCB->p_lnk != NULL) { - rt_put_prio ((P_XCB)p_MCB, os_tsk.run); - } - else { - p_MCB->p_lnk = os_tsk.run; - os_tsk.run->p_lnk = NULL; - os_tsk.run->p_rlnk = (P_TCB)p_MCB; - } - rt_block(timeout, WAIT_MUT); - return (OS_R_TMO); -} - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/mbed-rtos/rtx/rt_Mutex.h Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_MUTEX.H - * Purpose: Implements mutex synchronization objects - * Rev.: V4.50 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Functions */ -extern void rt_mut_init (OS_ID mutex); -extern OS_RESULT rt_mut_delete (OS_ID mutex); -extern OS_RESULT rt_mut_release (OS_ID mutex); -extern OS_RESULT rt_mut_wait (OS_ID mutex, U16 timeout); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/mbed-rtos/rtx/rt_Robin.c Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,84 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_ROBIN.C - * Purpose: Round Robin Task switching - * Rev.: V4.50 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_List.h" -#include "rt_Task.h" -#include "rt_Time.h" -#include "rt_Robin.h" -#include "rt_HAL_CM.h" - -/*---------------------------------------------------------------------------- - * Global Variables - *---------------------------------------------------------------------------*/ - -struct OS_ROBIN os_robin; - - -/*---------------------------------------------------------------------------- - * Global Functions - *---------------------------------------------------------------------------*/ - -/*--------------------------- rt_init_robin ---------------------------------*/ - -__weak void rt_init_robin (void) { - /* Initialize Round Robin variables. */ - os_robin.task = NULL; - os_robin.tout = (U16)os_rrobin; -} - -/*--------------------------- rt_chk_robin ----------------------------------*/ - -__weak void rt_chk_robin (void) { - /* Check if Round Robin timeout expired and switch to the next ready task.*/ - P_TCB p_new; - - if (os_robin.task != os_rdy.p_lnk) { - /* New task was suspended, reset Round Robin timeout. */ - os_robin.task = os_rdy.p_lnk; - os_robin.time = (U16)os_time + os_robin.tout - 1; - } - if (os_robin.time == (U16)os_time) { - /* Round Robin timeout has expired, swap Robin tasks. */ - os_robin.task = NULL; - p_new = rt_get_first (&os_rdy); - rt_put_prio ((P_XCB)&os_rdy, p_new); - } -} - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/mbed-rtos/rtx/rt_Robin.h Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_ROBIN.H - * Purpose: Round Robin Task switching definitions - * Rev.: V4.50 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Variables */ -extern struct OS_ROBIN os_robin; - -/* Functions */ -extern void rt_init_robin (void); -extern void rt_chk_robin (void); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/mbed-rtos/rtx/rt_Semaphore.c Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,171 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_SEMAPHORE.C - * Purpose: Implements binary and counting semaphores - * Rev.: V4.50 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_System.h" -#include "rt_List.h" -#include "rt_Task.h" -#include "rt_Semaphore.h" -#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 ---------------------------------*/ -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); -} - -/*--------------------------- 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); - rt_ret_val(p_TCB, 1); - 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; - rt_ret_val(p_TCB, 1); - rt_put_prio (&os_rdy, p_TCB); - } - else { - /* Store token */ - p_CB->tokens++; - } -} - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/mbed-rtos/rtx/rt_Semaphore.h Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_SEMAPHORE.H - * Purpose: Implements binary and counting semaphores - * Rev.: V4.50 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Functions */ -extern void rt_sem_init (OS_ID semaphore, U16 token_count); -extern OS_RESULT rt_sem_delete(OS_ID semaphore); -extern OS_RESULT rt_sem_send (OS_ID semaphore); -extern OS_RESULT rt_sem_wait (OS_ID semaphore, U16 timeout); -extern void isr_sem_send (OS_ID semaphore); -extern void rt_sem_psh (P_SCB p_CB); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/mbed-rtos/rtx/rt_System.c Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,288 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_SYSTEM.C - * Purpose: System Task Manager - * Rev.: V4.50 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_Task.h" -#include "rt_System.h" -#include "rt_Event.h" -#include "rt_List.h" -#include "rt_Mailbox.h" -#include "rt_Semaphore.h" -#include "rt_Time.h" -#include "rt_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; - } - - 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; - } - - /* 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. */ - sysTimerTick(); - - /* Switch back to highest ready task */ - next = rt_get_first (&os_rdy); - rt_switch_req (next); -} - -/*--------------------------- rt_stk_check ----------------------------------*/ -#ifdef THREAD_STACK_DIAGNOSTIC -typedef struct stack_boundaries_s { - unsigned int top; - unsigned int min; -} stack_boundaries_t; -stack_boundaries_t stack_boundaries[256]; -#endif - -__weak void rt_stk_check (void) { -#ifdef THREAD_STACK_DIAGNOSTIC - stack_boundaries_t* sb = &stack_boundaries[os_tsk.run->task_id]; - if (sb->top == 0) { - sb->top = (unsigned int)os_tsk.run->stack + os_tsk.run->priv_stack; - } - if ((sb->min == 0) || (sb->min < os_tsk.run->tsk_stack)) - sb->min = os_tsk.run->tsk_stack; -#endif - /* Check for stack overflow */ - if (os_tsk.run->task_id == 0x01) { - // TODO: For the main thread the check should be done against the heap pointer - } else { - if ((os_tsk.run->tsk_stack < (U32)os_tsk.run->stack) || - (os_tsk.run->stack[0] != MAGIC_WORD)) { - os_error (OS_ERR_STK_OVF); - } - } -} - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/mbed-rtos/rtx/rt_System.h Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_SYSTEM.H - * Purpose: System Task Manager definitions - * Rev.: V4.50 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Variables */ -#define os_psq ((P_PSQ)&os_fifo) -extern int os_tick_irqn; - -/* Functions */ -extern U32 rt_suspend (void); -extern void rt_resume (U32 sleep_time); -extern void rt_tsk_lock (void); -extern void rt_tsk_unlock (void); -extern void rt_psh_req (void); -extern void rt_pop_req (void); -extern void rt_systick (void); -extern void rt_stk_check (void); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/mbed-rtos/rtx/rt_Task.c Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,317 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_TASK.C - * Purpose: Task functions and system start up. - * Rev.: V4.50 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_System.h" -#include "rt_Task.h" -#include "rt_List.h" -#include "rt_MemBox.h" -#include "rt_Robin.h" -#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 = 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 -----------------------------------*/ -void rt_sys_init (void) { - /* 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 */ - 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 (); -} - - -/*--------------------------- rt_sys_start ----------------------------------*/ -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); - } -} - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/
--- a/mbed-rtos/rtx/rt_Task.h Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_TASK.H - * Purpose: Task functions and system start up. - * Rev.: V4.50 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Definitions */ - -/* Values for 'state' */ -#define INACTIVE 0 -#define READY 1 -#define RUNNING 2 -#define WAIT_DLY 3 -#define WAIT_ITV 4 -#define WAIT_OR 5 -#define WAIT_AND 6 -#define WAIT_SEM 7 -#define WAIT_MBX 8 -#define WAIT_MUT 9 - -/* Return codes */ -#define OS_R_TMO 0x01 -#define OS_R_EVT 0x02 -#define OS_R_SEM 0x03 -#define OS_R_MBX 0x04 -#define OS_R_MUT 0x05 - -#define OS_R_OK 0x00 -#define OS_R_NOK 0xff - -/* Variables */ -extern struct OS_TSK os_tsk; -extern struct OS_TCB os_idle_TCB; - -/* Functions */ -extern void rt_switch_req (P_TCB p_new); -extern void rt_dispatch (P_TCB next_TCB); -extern void rt_block (U16 timeout, U8 block_state); -extern void rt_tsk_pass (void); -extern OS_TID rt_tsk_self (void); -extern OS_RESULT rt_tsk_prio (OS_TID task_id, U8 new_prio); -extern OS_RESULT rt_tsk_delete (OS_TID task_id); -extern void rt_sys_init (void); -extern void rt_sys_start (void);
--- a/mbed-rtos/rtx/rt_Time.c Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,94 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_TIME.C - * Purpose: Delay and interval wait functions - * Rev.: V4.50 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_Task.h" -#include "rt_Time.h" - -/*---------------------------------------------------------------------------- - * Global Variables - *---------------------------------------------------------------------------*/ - -/* Free running system tick counter */ -U32 os_time; - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_time_get -----------------------------------*/ - -U32 rt_time_get (void) { - /* Get system time tick */ - return (os_time); -} - - -/*--------------------------- rt_dly_wait -----------------------------------*/ - -void rt_dly_wait (U16 delay_time) { - /* Delay task by "delay_time" */ - rt_block (delay_time, WAIT_DLY); -} - - -/*--------------------------- rt_itv_set ------------------------------------*/ - -void rt_itv_set (U16 interval_time) { - /* Set interval length and define start of first interval */ - os_tsk.run->interval_time = interval_time; - os_tsk.run->delta_time = interval_time + (U16)os_time; -} - - -/*--------------------------- rt_itv_wait -----------------------------------*/ - -void rt_itv_wait (void) { - /* Wait for interval end and define start of next one */ - U16 delta; - - delta = os_tsk.run->delta_time - (U16)os_time; - os_tsk.run->delta_time += os_tsk.run->interval_time; - if ((delta & 0x8000) == 0) { - rt_block (delta, WAIT_ITV); - } -} - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/mbed-rtos/rtx/rt_Time.h Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_TIME.H - * Purpose: Delay and interval wait functions definitions - * Rev.: V4.50 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Variables */ -extern U32 os_time; - -/* Functions */ -extern U32 rt_time_get (void); -extern void rt_dly_wait (U16 delay_time); -extern void rt_itv_set (U16 interval_time); -extern void rt_itv_wait (void); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -
--- a/mbed-rtos/rtx/rt_TypeDef.h Fri Mar 22 01:33:24 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,128 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_TYPEDEF.H - * Purpose: Type Definitions - * Rev.: V4.50 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ -#ifndef RT_TYPE_DEF_H -#define RT_TYPE_DEF_H - -#include "os_tcb.h" - -typedef U32 OS_TID; -typedef void *OS_ID; -typedef U32 OS_RESULT; - -#define TCB_STACKF 32 /* 'stack_frame' offset */ -#define TCB_TSTACK 36 /* 'tsk_stack' offset */ - -typedef struct OS_PSFE { /* Post Service Fifo Entry */ - void *id; /* Object Identification */ - U32 arg; /* Object Argument */ -} *P_PSFE; - -typedef struct OS_PSQ { /* Post Service Queue */ - U8 first; /* FIFO Head Index */ - U8 last; /* FIFO Tail Index */ - U8 count; /* Number of stored items in FIFO */ - U8 size; /* FIFO Size */ - struct OS_PSFE q[1]; /* FIFO Content */ -} *P_PSQ; - -typedef struct OS_TSK { - P_TCB run; /* Current running task */ - P_TCB new; /* 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