mirror of https://github.com/ARMmbed/mbed-os.git
commit
d89c3c18f9
|
@ -21,6 +21,7 @@
|
|||
#if DEVICE_ANALOGIN
|
||||
|
||||
#include "analogin_api.h"
|
||||
#include "SingletonPtr.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
|
@ -110,15 +111,15 @@ public:
|
|||
protected:
|
||||
|
||||
virtual void lock() {
|
||||
_mutex.lock();
|
||||
_mutex->lock();
|
||||
}
|
||||
|
||||
virtual void unlock() {
|
||||
_mutex.unlock();
|
||||
_mutex->unlock();
|
||||
}
|
||||
|
||||
analogin_t _adc;
|
||||
static PlatformMutex _mutex;
|
||||
static SingletonPtr<PlatformMutex> _mutex;
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
|
|
@ -41,6 +41,7 @@ typedef long off_t;
|
|||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
#include "SingletonPtr.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
|
@ -65,7 +66,7 @@ public:
|
|||
/* disallow copy constructor and assignment operators */
|
||||
private:
|
||||
static FileBase *_head;
|
||||
static PlatformMutex _mutex;
|
||||
static SingletonPtr<PlatformMutex> _mutex;
|
||||
|
||||
FileBase *_next;
|
||||
const char * const _name;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#if DEVICE_I2C
|
||||
|
||||
#include "i2c_api.h"
|
||||
#include "SingletonPtr.h"
|
||||
|
||||
#if DEVICE_I2C_ASYNCH
|
||||
#include "CThunk.h"
|
||||
|
@ -181,7 +182,7 @@ protected:
|
|||
i2c_t _i2c;
|
||||
static I2C *_owner;
|
||||
int _hz;
|
||||
static PlatformMutex _mutex;
|
||||
static SingletonPtr<PlatformMutex> _mutex;
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef SINGLETONPTR_H
|
||||
#define SINGLETONPTR_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <new>
|
||||
#include "mbed_assert.h"
|
||||
#ifdef MBED_CONF_RTOS_PRESENT
|
||||
#include "cmsis_os.h"
|
||||
#endif
|
||||
|
||||
#ifdef MBED_CONF_RTOS_PRESENT
|
||||
extern osMutexId singleton_mutex_id;
|
||||
#endif
|
||||
|
||||
/** Lock the singleton mutex
|
||||
*
|
||||
* This function is typically used to provide
|
||||
* exclusive access when initializing a
|
||||
* global object.
|
||||
*/
|
||||
inline static void singleton_lock(void)
|
||||
{
|
||||
#ifdef MBED_CONF_RTOS_PRESENT
|
||||
osMutexWait(singleton_mutex_id, osWaitForever);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Unlock the singleton mutex
|
||||
*
|
||||
* This function is typically used to provide
|
||||
* exclusive access when initializing a
|
||||
* global object.
|
||||
*/
|
||||
inline static void singleton_unlock(void)
|
||||
{
|
||||
#ifdef MBED_CONF_RTOS_PRESENT
|
||||
osMutexRelease (singleton_mutex_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Utility class for creating an using a singleton
|
||||
*
|
||||
* @Note Synchronization level: Thread safe
|
||||
*
|
||||
* @Note: This class must only be used in a static context -
|
||||
* this class must never be allocated or created on the
|
||||
* stack.
|
||||
*
|
||||
* @Note: This class is lazily initialized on first use.
|
||||
* This class is a POD type so if it is not used it will
|
||||
* be garbage collected.
|
||||
*/
|
||||
template <class T>
|
||||
struct SingletonPtr {
|
||||
|
||||
/** Get a pointer to the underlying singleton
|
||||
*
|
||||
* @returns
|
||||
* A pointer to the singleton
|
||||
*/
|
||||
T* get() {
|
||||
if (NULL == _ptr) {
|
||||
singleton_lock();
|
||||
_ptr = new (_data) T;
|
||||
singleton_unlock();
|
||||
}
|
||||
// _ptr was not zero initialized or was
|
||||
// corrupted if this assert is hit
|
||||
MBED_ASSERT(_ptr == (T *)&_data);
|
||||
return _ptr;
|
||||
}
|
||||
|
||||
/** Get a pointer to the underlying singleton
|
||||
*
|
||||
* @returns
|
||||
* A pointer to the singleton
|
||||
*/
|
||||
T* operator->() {
|
||||
return get();
|
||||
}
|
||||
|
||||
// This is zero initialized when in global scope
|
||||
T *_ptr;
|
||||
// Force data to be 4 byte aligned
|
||||
uint32_t _data[(sizeof(T) + sizeof(uint32_t) - 1) / sizeof(uint32_t)];
|
||||
};
|
||||
|
||||
#endif
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
namespace mbed {
|
||||
|
||||
PlatformMutex AnalogIn::_mutex;
|
||||
SingletonPtr<PlatformMutex> AnalogIn::_mutex;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
namespace mbed {
|
||||
|
||||
FileBase *FileBase::_head = NULL;
|
||||
PlatformMutex FileBase::_mutex;
|
||||
SingletonPtr<PlatformMutex> FileBase::_mutex;
|
||||
|
||||
FileBase::FileBase(const char *name, PathType t) : _next(NULL),
|
||||
_name(name),
|
||||
_path_type(t) {
|
||||
_mutex.lock();
|
||||
_mutex->lock();
|
||||
if (name != NULL) {
|
||||
// put this object at head of the list
|
||||
_next = _head;
|
||||
|
@ -31,11 +31,11 @@ FileBase::FileBase(const char *name, PathType t) : _next(NULL),
|
|||
} else {
|
||||
_next = NULL;
|
||||
}
|
||||
_mutex.unlock();
|
||||
_mutex->unlock();
|
||||
}
|
||||
|
||||
FileBase::~FileBase() {
|
||||
_mutex.lock();
|
||||
_mutex->lock();
|
||||
if (_name != NULL) {
|
||||
// remove this object from the list
|
||||
if (_head == this) { // first in the list, so just drop me
|
||||
|
@ -48,38 +48,38 @@ FileBase::~FileBase() {
|
|||
p->_next = _next;
|
||||
}
|
||||
}
|
||||
_mutex.unlock();
|
||||
_mutex->unlock();
|
||||
}
|
||||
|
||||
FileBase *FileBase::lookup(const char *name, unsigned int len) {
|
||||
_mutex.lock();
|
||||
_mutex->lock();
|
||||
FileBase *p = _head;
|
||||
while (p != NULL) {
|
||||
/* Check that p->_name matches name and is the correct length */
|
||||
if (p->_name != NULL && std::strncmp(p->_name, name, len) == 0 && std::strlen(p->_name) == len) {
|
||||
_mutex.unlock();
|
||||
_mutex->unlock();
|
||||
return p;
|
||||
}
|
||||
p = p->_next;
|
||||
}
|
||||
_mutex.unlock();
|
||||
_mutex->unlock();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FileBase *FileBase::get(int n) {
|
||||
_mutex.lock();
|
||||
_mutex->lock();
|
||||
FileBase *p = _head;
|
||||
int m = 0;
|
||||
while (p != NULL) {
|
||||
if (m == n) {
|
||||
_mutex.unlock();
|
||||
_mutex->unlock();
|
||||
return p;
|
||||
}
|
||||
|
||||
m++;
|
||||
p = p->_next;
|
||||
}
|
||||
_mutex.unlock();
|
||||
_mutex->unlock();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
namespace mbed {
|
||||
|
||||
I2C *I2C::_owner = NULL;
|
||||
PlatformMutex I2C::_mutex;
|
||||
SingletonPtr<PlatformMutex> I2C::_mutex;
|
||||
|
||||
I2C::I2C(PinName sda, PinName scl) :
|
||||
#if DEVICE_I2C_ASYNCH
|
||||
|
@ -113,11 +113,11 @@ void I2C::stop(void) {
|
|||
}
|
||||
|
||||
void I2C::lock() {
|
||||
_mutex.lock();
|
||||
_mutex->lock();
|
||||
}
|
||||
|
||||
void I2C::unlock() {
|
||||
_mutex.unlock();
|
||||
_mutex->unlock();
|
||||
}
|
||||
|
||||
#if DEVICE_I2C_ASYNCH
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "toolchain.h"
|
||||
#include "semihost_api.h"
|
||||
#include "mbed_interface.h"
|
||||
#include "SingletonPtr.h"
|
||||
#if DEVICE_STDIO_MESSAGES
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
@ -72,17 +73,17 @@ extern const char __stderr_name[] = "/stderr";
|
|||
* (or rather index+3, as filehandles 0-2 are stdin/out/err).
|
||||
*/
|
||||
static FileHandle *filehandles[OPEN_MAX];
|
||||
static PlatformMutex filehandle_mutex;
|
||||
static SingletonPtr<PlatformMutex> filehandle_mutex;
|
||||
|
||||
FileHandle::~FileHandle() {
|
||||
filehandle_mutex.lock();
|
||||
filehandle_mutex->lock();
|
||||
/* Remove all open filehandles for this */
|
||||
for (unsigned int fh_i = 0; fh_i < sizeof(filehandles)/sizeof(*filehandles); fh_i++) {
|
||||
if (filehandles[fh_i] == this) {
|
||||
filehandles[fh_i] = NULL;
|
||||
}
|
||||
}
|
||||
filehandle_mutex.unlock();
|
||||
filehandle_mutex->unlock();
|
||||
}
|
||||
|
||||
#if DEVICE_SERIAL
|
||||
|
@ -162,17 +163,17 @@ extern "C" FILEHANDLE PREFIX(_open)(const char* name, int openmode) {
|
|||
#endif
|
||||
|
||||
// find the first empty slot in filehandles
|
||||
filehandle_mutex.lock();
|
||||
filehandle_mutex->lock();
|
||||
unsigned int fh_i;
|
||||
for (fh_i = 0; fh_i < sizeof(filehandles)/sizeof(*filehandles); fh_i++) {
|
||||
if (filehandles[fh_i] == NULL) break;
|
||||
}
|
||||
if (fh_i >= sizeof(filehandles)/sizeof(*filehandles)) {
|
||||
filehandle_mutex.unlock();
|
||||
filehandle_mutex->unlock();
|
||||
return -1;
|
||||
}
|
||||
filehandles[fh_i] = (FileHandle*)FILE_HANDLE_RESERVED;
|
||||
filehandle_mutex.unlock();
|
||||
filehandle_mutex->unlock();
|
||||
|
||||
FileHandle *res;
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#if defined (__CC_ARM)
|
||||
#include <rt_misc.h>
|
||||
#pragma O3
|
||||
#define __USED __attribute__((used))
|
||||
#elif defined (__GNUC__)
|
||||
|
@ -224,6 +225,10 @@ uint32_t os_tmr = 0;
|
|||
uint32_t const *m_tmr = NULL;
|
||||
uint16_t const mp_tmr_size = 0;
|
||||
|
||||
/* singleton mutex */
|
||||
osMutexId singleton_mutex_id;
|
||||
osMutexDef(singleton_mutex);
|
||||
|
||||
#if defined (__CC_ARM) && !defined (__MICROLIB)
|
||||
/* A memory space for arm standard library. */
|
||||
static uint32_t std_libspace[OS_TASK_CNT][96/4];
|
||||
|
@ -433,6 +438,7 @@ void $Sub$$__cpp_initialize__aeabi_(void)
|
|||
|
||||
void pre_main()
|
||||
{
|
||||
singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex));
|
||||
$Super$$__cpp_initialize__aeabi_();
|
||||
main();
|
||||
}
|
||||
|
@ -442,25 +448,13 @@ void pre_main()
|
|||
void * armcc_heap_base;
|
||||
void * armcc_heap_top;
|
||||
|
||||
__asm void pre_main (void)
|
||||
{
|
||||
IMPORT __rt_lib_init
|
||||
IMPORT main
|
||||
IMPORT armcc_heap_base
|
||||
IMPORT armcc_heap_top
|
||||
int main(void);
|
||||
|
||||
LDR R0,=armcc_heap_base
|
||||
LDR R1,=armcc_heap_top
|
||||
LDR R0,[R0]
|
||||
LDR R1,[R1]
|
||||
/* Save link register (keep 8 byte alignment with dummy R4) */
|
||||
PUSH {R4, LR}
|
||||
BL __rt_lib_init
|
||||
BL main
|
||||
/* Return to the thread destroy function.
|
||||
*/
|
||||
POP {R4, PC}
|
||||
ALIGN
|
||||
void pre_main (void)
|
||||
{
|
||||
singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex));
|
||||
__rt_lib_init((unsigned)armcc_heap_base, (unsigned)armcc_heap_top);
|
||||
main();
|
||||
}
|
||||
|
||||
__asm void __rt_entry (void) {
|
||||
|
@ -496,6 +490,7 @@ extern void __libc_init_array (void);
|
|||
extern int main(int argc, char **argv);
|
||||
|
||||
void pre_main(void) {
|
||||
singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex));
|
||||
atexit(__libc_fini_array);
|
||||
__libc_init_array();
|
||||
main(0, NULL);
|
||||
|
@ -528,6 +523,7 @@ extern int main(void);
|
|||
static uint8_t low_level_init_needed;
|
||||
|
||||
void pre_main(void) {
|
||||
singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex));
|
||||
if (low_level_init_needed) {
|
||||
__iar_dynamic_initialization();
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "mbed_error.h"
|
||||
|
||||
#if defined (__CC_ARM)
|
||||
#include <rt_misc.h>
|
||||
#pragma O3
|
||||
#define __USED __attribute__((used))
|
||||
#elif defined (__GNUC__)
|
||||
|
@ -186,6 +187,10 @@ uint32_t os_tmr = 0U;
|
|||
uint32_t const *m_tmr = NULL;
|
||||
uint16_t const mp_tmr_size = 0U;
|
||||
|
||||
/* singleton mutex */
|
||||
osMutexId singleton_mutex_id;
|
||||
osMutexDef(singleton_mutex);
|
||||
|
||||
#if defined (__CC_ARM) && !defined (__MICROLIB)
|
||||
/* A memory space for arm standard library. */
|
||||
static uint32_t std_libspace[OS_TASK_CNT][96/4];
|
||||
|
@ -584,6 +589,7 @@ void $Sub$$__cpp_initialize__aeabi_(void)
|
|||
|
||||
void pre_main()
|
||||
{
|
||||
singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex));
|
||||
$Super$$__cpp_initialize__aeabi_();
|
||||
main();
|
||||
}
|
||||
|
@ -593,25 +599,13 @@ void pre_main()
|
|||
void * armcc_heap_base;
|
||||
void * armcc_heap_top;
|
||||
|
||||
__asm void pre_main (void)
|
||||
{
|
||||
IMPORT __rt_lib_init
|
||||
IMPORT main
|
||||
IMPORT armcc_heap_base
|
||||
IMPORT armcc_heap_top
|
||||
int main(void);
|
||||
|
||||
LDR R0,=armcc_heap_base
|
||||
LDR R1,=armcc_heap_top
|
||||
LDR R0,[R0]
|
||||
LDR R1,[R1]
|
||||
/* Save link register (keep 8 byte alignment with dummy R4) */
|
||||
PUSH {R4, LR}
|
||||
BL __rt_lib_init
|
||||
BL main
|
||||
/* Return to the thread destroy function.
|
||||
*/
|
||||
POP {R4, PC}
|
||||
ALIGN
|
||||
void pre_main (void)
|
||||
{
|
||||
singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex));
|
||||
__rt_lib_init((unsigned)armcc_heap_base, (unsigned)armcc_heap_top);
|
||||
main();
|
||||
}
|
||||
|
||||
/* The single memory model is checking for stack collision at run time, verifing
|
||||
|
@ -676,6 +670,7 @@ extern void __libc_init_array (void);
|
|||
extern int main(int argc, char **argv);
|
||||
|
||||
void pre_main(void) {
|
||||
singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex));
|
||||
malloc_mutex_id = osMutexCreate(osMutex(malloc_mutex));
|
||||
env_mutex_id = osMutexCreate(osMutex(env_mutex));
|
||||
atexit(__libc_fini_array);
|
||||
|
@ -737,6 +732,7 @@ extern void exit(int arg);
|
|||
static uint8_t low_level_init_needed;
|
||||
|
||||
void pre_main(void) {
|
||||
singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex));
|
||||
if (low_level_init_needed) {
|
||||
__iar_dynamic_initialization();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue