Update revision to use TI's mqtt and Freertos.

Dependencies:   mbed client server

Fork of cc3100_Test_mqtt_CM3 by David Fletcher

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cc3100_spawn.cpp Source File

cc3100_spawn.cpp

00001 /*
00002  * spawn.c - CC31xx/CC32xx Host Driver Implementation
00003  *
00004  * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
00005  *
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *    Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  *
00014  *    Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the
00017  *    distribution.
00018  *
00019  *    Neither the name of Texas Instruments Incorporated nor the names of
00020  *    its contributors may be used to endorse or promote products derived
00021  *    from this software without specific prior written permission.
00022  *
00023  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00024  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00025  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00026  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00027  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00028  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00029  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00030  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00031  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00032  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00033  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034  *
00035 */
00036 
00037 
00038 
00039 /*****************************************************************************/
00040 /* Include files                                                             */
00041 /*****************************************************************************/
00042 #include "cc3100_simplelink.h"
00043 
00044 #include "cc3100_spawn.h"
00045 
00046 #if (defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))
00047 
00048 namespace mbed_cc3100 {
00049 
00050 #define _SL_MAX_INTERNAL_SPAWN_ENTRIES      10
00051 
00052 
00053 typedef struct _SlInternalSpawnEntry_t {
00054     _SlSpawnEntryFunc_t                 pEntry;
00055     void*                               pValue;
00056     struct _SlInternalSpawnEntry_t*     pNext;
00057 } _SlInternalSpawnEntry_t;
00058 
00059 typedef struct {
00060     _SlInternalSpawnEntry_t     SpawnEntries[_SL_MAX_INTERNAL_SPAWN_ENTRIES];
00061     _SlInternalSpawnEntry_t*    pFree;
00062     _SlInternalSpawnEntry_t*    pWaitForExe;
00063     _SlInternalSpawnEntry_t*    pLastInWaitList;
00064     _SlSyncObj_t                SyncObj;
00065     _SlLockObj_t                LockObj;
00066 } _SlInternalSpawnCB_t;
00067 
00068 _SlInternalSpawnCB_t g_SlInternalSpawnCB;
00069 
00070 cc3100_spawn::cc3100_spawn()
00071 {
00072 
00073 }
00074 
00075 cc3100_spawn::~cc3100_spawn()
00076 {
00077 
00078 }
00079 
00080 
00081 void cc3100_spawn::_SlInternalSpawnTaskEntry()
00082 {
00083     int16_t                     i;
00084     _SlInternalSpawnEntry_t*    pEntry;
00085     uint8_t                     LastEntry;
00086 
00087     /* create and lock the locking object. lock in order to avoid race condition
00088         on the first creation */
00089     sl_LockObjCreate(&g_SlInternalSpawnCB.LockObj,"SlSpawnProtect");
00090     sl_LockObjLock(&g_SlInternalSpawnCB.LockObj,SL_OS_NO_WAIT);
00091 
00092     /* create and clear the sync object */
00093     sl_SyncObjCreate(&g_SlInternalSpawnCB.SyncObj,"SlSpawnSync");
00094     sl_SyncObjWait(&g_SlInternalSpawnCB.SyncObj,SL_OS_NO_WAIT);
00095 
00096     g_SlInternalSpawnCB.pFree = &g_SlInternalSpawnCB.SpawnEntries[0];
00097     g_SlInternalSpawnCB.pWaitForExe = NULL;
00098     g_SlInternalSpawnCB.pLastInWaitList = NULL;
00099 
00100     /* create the link list between the entries */
00101     for (i=0 ; i<_SL_MAX_INTERNAL_SPAWN_ENTRIES - 1 ; i++) {
00102         g_SlInternalSpawnCB.SpawnEntries[i].pNext = &g_SlInternalSpawnCB.SpawnEntries[i+1];
00103         g_SlInternalSpawnCB.SpawnEntries[i].pEntry = NULL;
00104     }
00105     g_SlInternalSpawnCB.SpawnEntries[i].pNext = NULL;
00106 
00107     _SlDrvObjUnLock(&g_SlInternalSpawnCB.LockObj);
00108 
00109 
00110     /* here we ready to execute entries */
00111 
00112     while (TRUE) {
00113         sl_SyncObjWait(&g_SlInternalSpawnCB.SyncObj,SL_OS_WAIT_FOREVER);
00114         /* go over all entries that already waiting for execution */
00115         LastEntry = FALSE;
00116         do {
00117             /* get entry to execute */
00118             _SlDrvObjLockWaitForever(&g_SlInternalSpawnCB.LockObj);
00119 
00120             pEntry = g_SlInternalSpawnCB.pWaitForExe;
00121             if ( NULL == pEntry ) {
00122                 _SlDrvObjUnLock(&g_SlInternalSpawnCB.LockObj);
00123                 break;
00124             }
00125             g_SlInternalSpawnCB.pWaitForExe = pEntry->pNext;
00126             if (pEntry == g_SlInternalSpawnCB.pLastInWaitList) {
00127                 g_SlInternalSpawnCB.pLastInWaitList = NULL;
00128                 LastEntry = TRUE;
00129             }
00130 
00131             _SlDrvObjUnLock(&g_SlInternalSpawnCB.LockObj);
00132 
00133 
00134             /* pEntry could be null in case that the sync was already set by some
00135                of the entries during execution of earlier entry */
00136             if (NULL != pEntry) {
00137                 pEntry->pEntry(pEntry->pValue);
00138                 /* free the entry */
00139                 _SlDrvObjLockWaitForever(&g_SlInternalSpawnCB.LockObj);
00140 
00141                 pEntry->pNext = g_SlInternalSpawnCB.pFree;
00142                 g_SlInternalSpawnCB.pFree = pEntry;
00143 
00144 
00145                 if (NULL != g_SlInternalSpawnCB.pWaitForExe) {
00146                     /* new entry received meanwhile */
00147                     LastEntry = FALSE;
00148                 }
00149 
00150                 _SlDrvObjUnLock(&g_SlInternalSpawnCB.LockObj);
00151 
00152             }
00153 
00154         } while (!LastEntry);
00155     }
00156 }
00157 
00158 
00159 int16_t cc3100_spawn::_SlInternalSpawn(_SlSpawnEntryFunc_t pEntry , void* pValue , uint32_t flags)
00160 {
00161     int16_t                         Res = 0;
00162     _SlInternalSpawnEntry_t*    pSpawnEntry;
00163 
00164     if (NULL == pEntry) {
00165         Res = -1;
00166     } else {
00167          _SlDrvObjLockWaitForever(&g_SlInternalSpawnCB.LockObj);
00168 
00169         pSpawnEntry = g_SlInternalSpawnCB.pFree;
00170         g_SlInternalSpawnCB.pFree = pSpawnEntry->pNext;
00171 
00172         pSpawnEntry->pEntry = pEntry;
00173         pSpawnEntry->pValue = pValue;
00174         pSpawnEntry->pNext = NULL;
00175 
00176         if (NULL == g_SlInternalSpawnCB.pWaitForExe) {
00177             g_SlInternalSpawnCB.pWaitForExe = pSpawnEntry;
00178             g_SlInternalSpawnCB.pLastInWaitList = pSpawnEntry;
00179         } else {
00180             g_SlInternalSpawnCB.pLastInWaitList->pNext = pSpawnEntry;
00181             g_SlInternalSpawnCB.pLastInWaitList = pSpawnEntry;
00182         }
00183 
00184         _SlDrvObjUnLock(&g_SlInternalSpawnCB.LockObj);
00185         
00186         /* this sync is called after releasing the lock object to avoid unnecessary context switches */
00187         _SlDrvSyncObjSignal(&g_SlInternalSpawnCB.SyncObj);
00188     }
00189 
00190     return Res;
00191 }
00192 
00193 }//namespace mbed_cc3100
00194 
00195 #endif//SL_PLATFORM_MULTI_THREADED
00196