Simple LED control project using CC3100 as Access Point and socket
Fork of cc3100_Test_Demo by
Diff: simplelink/cc3100_spawn.cpp
- Revision:
- 0:e89ba455dbcf
diff -r 000000000000 -r e89ba455dbcf simplelink/cc3100_spawn.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/simplelink/cc3100_spawn.cpp Tue Feb 10 12:09:29 2015 +0000 @@ -0,0 +1,194 @@ +/* + * spawn.c - CC31xx/CC32xx Host Driver Implementation + * + * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * 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 Texas Instruments Incorporated 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 THE COPYRIGHT + * OWNER OR 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 files */ +/*****************************************************************************/ +#include "cc3100_simplelink.h" + +#include "cc3100_spawn.h" + +namespace mbed_cc3100 { + +#if (defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN)) + +#define _SL_MAX_INTERNAL_SPAWN_ENTRIES 10 + + +typedef struct _SlInternalSpawnEntry_t { + _SlSpawnEntryFunc_t pEntry; + void* pValue; + struct _SlInternalSpawnEntry_t* pNext; +} _SlInternalSpawnEntry_t; + +typedef struct { + _SlInternalSpawnEntry_t SpawnEntries[_SL_MAX_INTERNAL_SPAWN_ENTRIES]; + _SlInternalSpawnEntry_t* pFree; + _SlInternalSpawnEntry_t* pWaitForExe; + _SlInternalSpawnEntry_t* pLastInWaitList; + _SlSyncObj_t SyncObj; + _SlLockObj_t LockObj; +} _SlInternalSpawnCB_t; + +_SlInternalSpawnCB_t g_SlInternalSpawnCB; + +cc3100_spawn::cc3100_spawn() +{ + +} + +cc3100_spawn::~cc3100_spawn() +{ + +} + + +void cc3100_spawn::_SlInternalSpawnTaskEntry() +{ + int16_t i; + _SlInternalSpawnEntry_t* pEntry; + uint8_t LastEntry; + + /* create and lock the locking object. lock in order to avoid race condition + on the first creation */ + sl_LockObjCreate(&g_SlInternalSpawnCB.LockObj,"SlSpawnProtect"); + sl_LockObjLock(&g_SlInternalSpawnCB.LockObj,SL_OS_NO_WAIT); + + /* create and clear the sync object */ + sl_SyncObjCreate(&g_SlInternalSpawnCB.SyncObj,"SlSpawnSync"); + sl_SyncObjWait(&g_SlInternalSpawnCB.SyncObj,SL_OS_NO_WAIT); + + g_SlInternalSpawnCB.pFree = &g_SlInternalSpawnCB.SpawnEntries[0]; + g_SlInternalSpawnCB.pWaitForExe = NULL; + g_SlInternalSpawnCB.pLastInWaitList = NULL; + + /* create the link list between the entries */ + for (i=0 ; i<_SL_MAX_INTERNAL_SPAWN_ENTRIES - 1 ; i++) { + g_SlInternalSpawnCB.SpawnEntries[i].pNext = &g_SlInternalSpawnCB.SpawnEntries[i+1]; + g_SlInternalSpawnCB.SpawnEntries[i].pEntry = NULL; + } + g_SlInternalSpawnCB.SpawnEntries[i].pNext = NULL; + + sl_LockObjUnlock(&g_SlInternalSpawnCB.LockObj); + + + /* here we ready to execute entries */ + + while (TRUE) { + sl_SyncObjWait(&g_SlInternalSpawnCB.SyncObj,SL_OS_WAIT_FOREVER); + /* go over all entries that already waiting for execution */ + LastEntry = FALSE; + do { + /* get entry to execute */ + sl_LockObjLock(&g_SlInternalSpawnCB.LockObj,SL_OS_WAIT_FOREVER); + + pEntry = g_SlInternalSpawnCB.pWaitForExe; + if ( NULL == pEntry ) { + sl_LockObjUnlock(&g_SlInternalSpawnCB.LockObj); + break; + } + g_SlInternalSpawnCB.pWaitForExe = pEntry->pNext; + if (pEntry == g_SlInternalSpawnCB.pLastInWaitList) { + g_SlInternalSpawnCB.pLastInWaitList = NULL; + LastEntry = TRUE; + } + + sl_LockObjUnlock(&g_SlInternalSpawnCB.LockObj); + + + /* pEntry could be null in case that the sync was already set by some + of the entries during execution of earlier entry */ + if (NULL != pEntry) { + pEntry->pEntry(pEntry->pValue); + /* free the entry */ + sl_LockObjLock(&g_SlInternalSpawnCB.LockObj,SL_OS_WAIT_FOREVER); + + pEntry->pNext = g_SlInternalSpawnCB.pFree; + g_SlInternalSpawnCB.pFree = pEntry; + + + if (NULL != g_SlInternalSpawnCB.pWaitForExe) { + /* new entry received meanwhile */ + LastEntry = FALSE; + } + + sl_LockObjUnlock(&g_SlInternalSpawnCB.LockObj); + + } + + } while (!LastEntry); + } +} + + +int16_t cc3100_spawn::_SlInternalSpawn(_SlSpawnEntryFunc_t pEntry , void* pValue , uint32_t flags) +{ + int16_t Res = 0; + _SlInternalSpawnEntry_t* pSpawnEntry; + + if (NULL == pEntry) { + Res = -1; + } else { + sl_LockObjLock(&g_SlInternalSpawnCB.LockObj,SL_OS_WAIT_FOREVER); + + pSpawnEntry = g_SlInternalSpawnCB.pFree; + g_SlInternalSpawnCB.pFree = pSpawnEntry->pNext; + + pSpawnEntry->pEntry = pEntry; + pSpawnEntry->pValue = pValue; + pSpawnEntry->pNext = NULL; + + if (NULL == g_SlInternalSpawnCB.pWaitForExe) { + g_SlInternalSpawnCB.pWaitForExe = pSpawnEntry; + g_SlInternalSpawnCB.pLastInWaitList = pSpawnEntry; + } else { + g_SlInternalSpawnCB.pLastInWaitList->pNext = pSpawnEntry; + g_SlInternalSpawnCB.pLastInWaitList = pSpawnEntry; + } + + sl_LockObjUnlock(&g_SlInternalSpawnCB.LockObj); + /* this sync is called after releasing the lock object to avoid unnecessary context switches */ + sl_SyncObjSignal(&g_SlInternalSpawnCB.SyncObj); + } + + return Res; +} + +#endif + +}//namespace mbed_cc3100