1 //*****************************************************************************
2 // osi_freertos.c
3 //
4 // Interface APIs for free-rtos function calls
5 //
6 // Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
7 //
8 //
9 //  Redistribution and use in source and binary forms, with or without
10 //  modification, are permitted provided that the following conditions
11 //  are met:
12 //
13 //    Redistributions of source code must retain the above copyright
14 //    notice, this list of conditions and the following disclaimer.
15 //
16 //    Redistributions in binary form must reproduce the above copyright
17 //    notice, this list of conditions and the following disclaimer in the
18 //    documentation and/or other materials provided with the
19 //    distribution.
20 //
21 //    Neither the name of Texas Instruments Incorporated nor the names of
22 //    its contributors may be used to endorse or promote products derived
23 //    from this software without specific prior written permission.
24 //
25 //  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 //  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 //  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 //  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 //  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 //  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 //  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 //  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 //  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 //  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 //  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 //*****************************************************************************
38 
39 
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include "FreeRTOS.h"
44 #include "task.h"
45 #include "semphr.h"
46 #include "portmacro.h"
47 #include "osi.h"
48 #include "rom_map.h"
49 #include "inc/hw_types.h"
50 #include "interrupt.h"
51 #include "pybwdt.h"
52 #include "debug.h"
53 
54 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
55 //Local function definition
56 static void vSimpleLinkSpawnTask( void *pvParameters );
57 //Queue Handler
58 QueueHandle_t xSimpleLinkSpawnQueue = NULL;
59 TaskHandle_t xSimpleLinkSpawnTaskHndl = NULL;
60 // Queue size
61 #define slQUEUE_SIZE				( 3 )
62 #define SL_SPAWN_MAX_WAIT_MS        ( 200 )
63 
64 // This is the static memory (TCB and stack) for the SL spawn task
65 static StaticTask_t spawnTaskTCB __attribute__ ((section (".rtos_heap")));
66 static portSTACK_TYPE spawnTaskStack[896 / sizeof(portSTACK_TYPE)] __attribute__ ((section (".rtos_heap"))) __attribute__((aligned (8)));
67 
68 /*!
69 	\brief 	This function registers an interrupt in NVIC table
70 
71 	The sync object is used for synchronization between different thread or ISR and
72 	a thread.
73 
74 	\param	iIntrNum	-	Interrupt number to register
75 	\param	pEntry	    -	Pointer to the interrupt handler
76 	\param	ucPriority	-	priority of the interrupt
77 
78 	\return upon successful creation the function should return 0
79 			Otherwise, a negative value indicating the error code shall be returned
80 	\note
81 	\warning
82 */
osi_InterruptRegister(int iIntrNum,P_OSI_INTR_ENTRY pEntry,unsigned char ucPriority)83 OsiReturnVal_e osi_InterruptRegister(int iIntrNum,P_OSI_INTR_ENTRY pEntry,unsigned char ucPriority)
84 {
85 	MAP_IntRegister(iIntrNum,(void(*)(void))pEntry);
86 	MAP_IntPrioritySet(iIntrNum, ucPriority);
87 	MAP_IntEnable(iIntrNum);
88 	return OSI_OK;
89 }
90 
91 /*!
92 	\brief 	This function De registers an interrupt in NVIC table
93 
94 
95 	\param	iIntrNum	-	Interrupt number to De register
96 
97 	\return 	none
98 	\note
99 	\warning
100 */
101 
osi_InterruptDeRegister(int iIntrNum)102 void osi_InterruptDeRegister(int iIntrNum)
103 {
104 	MAP_IntDisable(iIntrNum);
105 	MAP_IntUnregister(iIntrNum);
106 }
107 
108 /*!
109 	\brief 	This function creates a sync object
110 
111 	The sync object is used for synchronization between different thread or ISR and
112 	a thread.
113 
114 	\param	pSyncObj	-	pointer to the sync object control block
115 
116 	\return upon successful creation the function should return 0
117 			Otherwise, a negative value indicating the error code shall be returned
118 	\note
119 	\warning
120 */
osi_SyncObjCreate(OsiSyncObj_t * pSyncObj)121 OsiReturnVal_e osi_SyncObjCreate(OsiSyncObj_t* pSyncObj)
122 {
123     SemaphoreHandle_t *pl_SyncObj = (SemaphoreHandle_t *)pSyncObj;
124 
125     *pl_SyncObj = xSemaphoreCreateBinary();
126 
127     ASSERT (*pSyncObj != NULL);
128 
129     return OSI_OK;
130 }
131 
132 /*!
133 	\brief 	This function deletes a sync object
134 
135 	\param	pSyncObj	-	pointer to the sync object control block
136 
137 	\return upon successful deletion the function should return 0
138 			Otherwise, a negative value indicating the error code shall be returned
139 	\note
140 	\warning
141 */
osi_SyncObjDelete(OsiSyncObj_t * pSyncObj)142 OsiReturnVal_e osi_SyncObjDelete(OsiSyncObj_t* pSyncObj)
143 {
144     vSemaphoreDelete(*pSyncObj );
145     return OSI_OK;
146 }
147 
148 /*!
149 	\brief 		This function generates a sync signal for the object.
150 
151 	All suspended threads waiting on this sync object are resumed
152 
153 	\param		pSyncObj	-	pointer to the sync object control block
154 
155 	\return 	upon successful signaling the function should return 0
156 				Otherwise, a negative value indicating the error code shall be returned
157 	\note		the function could be called from ISR context
158 	\warning
159 */
osi_SyncObjSignal(OsiSyncObj_t * pSyncObj)160 OsiReturnVal_e osi_SyncObjSignal(OsiSyncObj_t* pSyncObj)
161 {
162     xSemaphoreGive( *pSyncObj );
163     return OSI_OK;
164 }
165 /*!
166 	\brief 		This function generates a sync signal for the object
167 				from ISR context.
168 
169 	All suspended threads waiting on this sync object are resumed
170 
171 	\param		pSyncObj	-	pointer to the sync object control block
172 
173 	\return 	upon successful signalling the function should return 0
174 				Otherwise, a negative value indicating the error code shall be returned
175 	\note		the function is called from ISR context
176 	\warning
177 */
osi_SyncObjSignalFromISR(OsiSyncObj_t * pSyncObj)178 OsiReturnVal_e osi_SyncObjSignalFromISR(OsiSyncObj_t* pSyncObj)
179 {
180 	xHigherPriorityTaskWoken = pdFALSE;
181 	if(pdTRUE == xSemaphoreGiveFromISR( *pSyncObj, &xHigherPriorityTaskWoken ))
182 	{
183 		if( xHigherPriorityTaskWoken )
184 		{
185 			taskYIELD ();
186 		}
187 	}
188 	return OSI_OK;
189 }
190 
191 /*!
192 	\brief 	This function waits for a sync signal of the specific sync object
193 
194 	\param	pSyncObj	-	pointer to the sync object control block
195 	\param	Timeout		-	numeric value specifies the maximum number of mSec to
196 							stay suspended while waiting for the sync signal
197 							Currently, the simple link driver uses only two values:
198 								- OSI_WAIT_FOREVER
199 								- OSI_NO_WAIT
200 
201 	\return upon successful reception of the signal within the timeout window return 0
202 			Otherwise, a negative value indicating the error code shall be returned
203 	\note
204 	\warning
205 */
osi_SyncObjWait(OsiSyncObj_t * pSyncObj,OsiTime_t Timeout)206 OsiReturnVal_e osi_SyncObjWait(OsiSyncObj_t* pSyncObj , OsiTime_t Timeout)
207 {
208     if(pdTRUE == xSemaphoreTake( (SemaphoreHandle_t)*pSyncObj, ( TickType_t )Timeout))
209     {
210         return OSI_OK;
211     }
212     else
213     {
214         return OSI_OPERATION_FAILED;
215     }
216 }
217 
218 /*!
219 	\brief 	This function clears a sync object
220 
221 	\param	pSyncObj	-	pointer to the sync object control block
222 
223 	\return upon successful clearing the function should return 0
224 			Otherwise, a negative value indicating the error code shall be returned
225 	\note
226 	\warning
227 */
osi_SyncObjClear(OsiSyncObj_t * pSyncObj)228 OsiReturnVal_e osi_SyncObjClear(OsiSyncObj_t* pSyncObj)
229 {
230     if (OSI_OK == osi_SyncObjWait(pSyncObj,0) )
231     {
232         return OSI_OK;
233     }
234     else
235     {
236         return OSI_OPERATION_FAILED;
237     }
238 }
239 
240 /*!
241 	\brief 	This function creates a locking object.
242 
243 	The locking object is used for protecting a shared resources between different
244 	threads.
245 
246 	\param	pLockObj	-	pointer to the locking object control block
247 
248 	\return upon successful creation the function should return 0
249 			Otherwise, a negative value indicating the error code shall be returned
250 	\note
251 	\warning
252 */
osi_LockObjCreate(OsiLockObj_t * pLockObj)253 OsiReturnVal_e osi_LockObjCreate(OsiLockObj_t* pLockObj)
254 {
255     SemaphoreHandle_t *pl_LockObj = (SemaphoreHandle_t *)pLockObj;
256 
257     vSemaphoreCreateBinary(*pl_LockObj);
258 
259     ASSERT (*pLockObj != NULL);
260 
261     return OSI_OK;
262 }
263 
264 /*!
265 	\brief 	This function creates a Task.
266 
267 	Creates a new Task and add it to the last of tasks that are ready to run
268 
269 	\param	pEntry	-	pointer to the Task Function
270 	\param	pcName	-	Task Name String
271 	\param	usStackDepth	-	Stack Size in bytes
272 	\param	pvParameters	-	pointer to structure to be passed to the Task Function
273 	\param	uxPriority	-	Task Priority
274 
275 	\return upon successful creation the function should return 0
276 			Otherwise, a negative value indicating the error code shall be returned
277 	\note
278 	\warning
279 */
osi_TaskCreate(P_OSI_TASK_ENTRY pEntry,const signed char * const pcName,unsigned short usStackDepth,void * pvParameters,unsigned long uxPriority,OsiTaskHandle * pTaskHandle)280 OsiReturnVal_e osi_TaskCreate(P_OSI_TASK_ENTRY pEntry,const signed char * const pcName,
281                               unsigned short usStackDepth, void *pvParameters,
282                               unsigned long uxPriority,OsiTaskHandle* pTaskHandle)
283 {
284 	ASSERT (pdPASS == xTaskCreate( pEntry, (char const*)pcName,
285                                 (usStackDepth/(sizeof( portSTACK_TYPE ))),
286                                 pvParameters,(unsigned portBASE_TYPE)uxPriority,
287                                 (TaskHandle_t*)pTaskHandle ));
288 	return OSI_OK;
289 }
290 
291 
292 /*!
293 	\brief 	This function Deletes a Task.
294 
295 	Deletes a  Task and remove it from list of running task
296 
297 	\param	pTaskHandle	-	Task Handle
298 
299 	\note
300 	\warning
301 */
osi_TaskDelete(OsiTaskHandle * pTaskHandle)302 void osi_TaskDelete(OsiTaskHandle* pTaskHandle)
303 {
304 	vTaskDelete((TaskHandle_t)*pTaskHandle);
305 }
306 
307 
308 
309 /*!
310 	\brief 	This function deletes a locking object.
311 
312 	\param	pLockObj	-	pointer to the locking object control block
313 
314 	\return upon successful deletion the function should return 0
315 			Otherwise, a negative value indicating the error code shall be returned
316 	\note
317 	\warning
318 */
_osi_LockObjDelete(OsiLockObj_t * pLockObj)319 OsiReturnVal_e _osi_LockObjDelete(OsiLockObj_t* pLockObj)
320 {
321     vSemaphoreDelete((SemaphoreHandle_t)*pLockObj );
322     return OSI_OK;
323 }
324 
325 /*!
326 	\brief 	This function locks a locking object.
327 
328 	All other threads that call this function before this thread calls
329 	the osi_LockObjUnlock would be suspended
330 
331 	\param	pLockObj	-	pointer to the locking object control block
332 	\param	Timeout		-	numeric value specifies the maximum number of mSec to
333 							stay suspended while waiting for the locking object
334 							Currently, the simple link driver uses only two values:
335 								- OSI_WAIT_FOREVER
336 								- OSI_NO_WAIT
337 
338 
339 	\return upon successful reception of the locking object the function should return 0
340 			Otherwise, a negative value indicating the error code shall be returned
341 	\note
342 	\warning
343 */
_osi_LockObjLock(OsiLockObj_t * pLockObj,OsiTime_t Timeout)344 OsiReturnVal_e _osi_LockObjLock(OsiLockObj_t* pLockObj , OsiTime_t Timeout)
345 {
346     //Take Semaphore
347     if(pdTRUE == xSemaphoreTake( *pLockObj, ( TickType_t ) Timeout ))
348     {
349         return OSI_OK;
350     }
351     else
352     {
353         return OSI_OPERATION_FAILED;
354     }
355 }
356 
357 /*!
358 	\brief 	This function unlock a locking object.
359 
360 	\param	pLockObj	-	pointer to the locking object control block
361 
362 	\return upon successful unlocking the function should return 0
363 			Otherwise, a negative value indicating the error code shall be returned
364 	\note
365 	\warning
366 */
_osi_LockObjUnlock(OsiLockObj_t * pLockObj)367 OsiReturnVal_e _osi_LockObjUnlock(OsiLockObj_t* pLockObj)
368 {
369 	//Release Semaphore
370     if(pdTRUE == xSemaphoreGive( *pLockObj ))
371     {
372     	return OSI_OK;
373     }
374     else
375     {
376     	return OSI_OPERATION_FAILED;
377     }
378 }
379 
380 
381 /*!
382 	\brief 	This function call the pEntry callback from a different context
383 
384 	\param	pEntry		-	pointer to the entry callback function
385 
386 	\param	pValue		- 	pointer to any type of memory structure that would be
387 							passed to pEntry callback from the execution thread.
388 
389 	\param	flags		- 	execution flags - reserved for future usage
390 
391 	\return upon successful registration of the spawn the function should return 0
392 			(the function is not blocked till the end of the execution of the function
393 			and could be returned before the execution is actually completed)
394 			Otherwise, a negative value indicating the error code shall be returned
395 	\note
396 	\warning
397 */
398 
osi_Spawn(P_OSI_SPAWN_ENTRY pEntry,void * pValue,unsigned long flags)399 OsiReturnVal_e osi_Spawn(P_OSI_SPAWN_ENTRY pEntry , void* pValue , unsigned long flags)
400 {
401 
402 	tSimpleLinkSpawnMsg Msg;
403 	Msg.pEntry = pEntry;
404 	Msg.pValue = pValue;
405 	xHigherPriorityTaskWoken = pdFALSE;
406 
407 	if(pdTRUE == xQueueSendFromISR( xSimpleLinkSpawnQueue, &Msg, &xHigherPriorityTaskWoken ))
408 	{
409 		if( xHigherPriorityTaskWoken )
410 		{
411 			taskYIELD ();
412 		}
413 		return OSI_OK;
414 	}
415 	return OSI_OPERATION_FAILED;
416 }
417 
418 
419 /*!
420 	\brief 	This is the simplelink spawn task to call SL callback from a different context
421 
422 	\param	pvParameters		-	pointer to the task parameter
423 
424 	\return void
425 	\note
426 	\warning
427 */
vSimpleLinkSpawnTask(void * pvParameters)428 void vSimpleLinkSpawnTask(void *pvParameters)
429 {
430 	tSimpleLinkSpawnMsg Msg;
431 	portBASE_TYPE ret;
432 
433 	for(;;)
434 	{
435 		ret = xQueueReceive( xSimpleLinkSpawnQueue, &Msg, SL_SPAWN_MAX_WAIT_MS);
436 		if(ret == pdPASS)
437 		{
438 				Msg.pEntry(Msg.pValue);
439 		}
440         // set the alive flag for the wdt
441         pybwdt_sl_alive();
442 	}
443 }
444 
445 /*!
446 	\brief 	This is the API to create SL spawn task and create the SL queue
447 
448 	\param	uxPriority		-	task priority
449 
450 	\return void
451 	\note
452 	\warning
453 */
454 __attribute__ ((section (".boot")))
VStartSimpleLinkSpawnTask(unsigned portBASE_TYPE uxPriority)455 OsiReturnVal_e VStartSimpleLinkSpawnTask(unsigned portBASE_TYPE uxPriority)
456 {
457     xSimpleLinkSpawnQueue = xQueueCreate( slQUEUE_SIZE, sizeof( tSimpleLinkSpawnMsg ) );
458     ASSERT (xSimpleLinkSpawnQueue != NULL);
459 
460     /*
461     // This is the original code to create a task dynamically
462     ASSERT (pdPASS == xTaskCreate( vSimpleLinkSpawnTask, ( portCHAR * ) "SLSPAWN",\
463                                    896 / sizeof(portSTACK_TYPE), NULL, uxPriority, &xSimpleLinkSpawnTaskHndl ));
464     */
465 
466     // This code creates the task using static memory for the TCB and stack
467     xSimpleLinkSpawnTaskHndl = xTaskCreateStatic(
468         vSimpleLinkSpawnTask, ( portCHAR * ) "SLSPAWN",
469         896 / sizeof(portSTACK_TYPE), NULL, uxPriority,
470         spawnTaskStack, &spawnTaskTCB);
471 
472     ASSERT(xSimpleLinkSpawnTaskHndl != NULL);
473 
474     return OSI_OK;
475 }
476 
477 /*!
478 	\brief 	This is the API to delete SL spawn task and delete the SL queue
479 
480 	\param	none
481 
482 	\return void
483 	\note
484 	\warning
485 */
VDeleteSimpleLinkSpawnTask(void)486 void VDeleteSimpleLinkSpawnTask( void )
487 {
488 	if(xSimpleLinkSpawnTaskHndl)
489 	{
490 		vTaskDelete( xSimpleLinkSpawnTaskHndl );
491 		xSimpleLinkSpawnTaskHndl = 0;
492 	}
493 
494 	if(xSimpleLinkSpawnQueue)
495 	{
496 		vQueueDelete( xSimpleLinkSpawnQueue );
497 		xSimpleLinkSpawnQueue = 0;
498 	}
499 }
500 
501 /*!
502 	\brief 	This function is used to create the MsgQ
503 
504 	\param	pMsgQ	-	pointer to the message queue
505 	\param	pMsgQName	-	msg queue name
506 	\param	MsgSize	-	size of message on the queue
507 	\param	MaxMsgs	-	max. number of msgs that the queue can hold
508 
509 	\return - OsiReturnVal_e
510 	\note
511 	\warning
512 */
osi_MsgQCreate(OsiMsgQ_t * pMsgQ,char * pMsgQName,unsigned long MsgSize,unsigned long MaxMsgs)513 OsiReturnVal_e osi_MsgQCreate(OsiMsgQ_t* 		pMsgQ ,
514 			      char*			pMsgQName,
515 			      unsigned long 		MsgSize,
516 			      unsigned long		MaxMsgs)
517 {
518 	QueueHandle_t handle;
519 
520 	//Create Queue
521 	handle = xQueueCreate( MaxMsgs, MsgSize );
522 	ASSERT (handle != NULL);
523 
524 	*pMsgQ = (OsiMsgQ_t)handle;
525 	return OSI_OK;
526 }
527 /*!
528 	\brief 	This function is used to delete the MsgQ
529 
530 	\param	pMsgQ	-	pointer to the message queue
531 
532 	\return - OsiReturnVal_e
533 	\note
534 	\warning
535 */
osi_MsgQDelete(OsiMsgQ_t * pMsgQ)536 OsiReturnVal_e osi_MsgQDelete(OsiMsgQ_t* pMsgQ)
537 {
538 	vQueueDelete((QueueHandle_t) *pMsgQ );
539     return OSI_OK;
540 }
541 /*!
542 	\brief 	This function is used to write data to the MsgQ
543 
544 	\param	pMsgQ	-	pointer to the message queue
545 	\param	pMsg	-	pointer to the Msg strut to read into
546 	\param	Timeout	-	timeout to wait for the Msg to be available
547 
548 	\return - OsiReturnVal_e
549 	\note
550 	\warning
551 */
552 
osi_MsgQWrite(OsiMsgQ_t * pMsgQ,void * pMsg,OsiTime_t Timeout)553 OsiReturnVal_e osi_MsgQWrite(OsiMsgQ_t* pMsgQ, void* pMsg , OsiTime_t Timeout)
554 {
555 	xHigherPriorityTaskWoken = pdFALSE;
556     if(pdPASS == xQueueSendFromISR((QueueHandle_t) *pMsgQ, pMsg, &xHigherPriorityTaskWoken ))
557     {
558 		taskYIELD ();
559 		return OSI_OK;
560     }
561 	else
562 	{
563 		return OSI_OPERATION_FAILED;
564 	}
565 }
566 /*!
567 	\brief 	This function is used to read data from the MsgQ
568 
569 	\param	pMsgQ	-	pointer to the message queue
570 	\param	pMsg	-	pointer to the Msg strut to read into
571 	\param	Timeout	-	timeout to wait for the Msg to be available
572 
573 	\return - OsiReturnVal_e
574 	\note
575 	\warning
576 */
577 
osi_MsgQRead(OsiMsgQ_t * pMsgQ,void * pMsg,OsiTime_t Timeout)578 OsiReturnVal_e osi_MsgQRead(OsiMsgQ_t* pMsgQ, void* pMsg , OsiTime_t Timeout)
579 {
580 	//Receive Item from Queue
581 	if( pdTRUE  == xQueueReceive((QueueHandle_t)*pMsgQ,pMsg,Timeout) )
582 	{
583 		return OSI_OK;
584 	}
585 	else
586 	{
587 		return OSI_OPERATION_FAILED;
588 	}
589 }
590 
591 /*!
592 	\brief 	This function to call the memory de-allocation function of the FREERTOS
593 
594 	\param	Size	-	size of memory to alloc in bytes
595 
596 	\return - void *
597 	\note
598 	\warning
599 */
600 
mem_Malloc(unsigned long Size)601 void * mem_Malloc(unsigned long Size)
602 {
603     return ( void * ) pvPortMalloc( (size_t)Size );
604 }
605 
606 /*!
607 	\brief 	This function to call the memory de-allocation function of the FREERTOS
608 
609 	\param	pMem		-	pointer to the memory which needs to be freed
610 
611 	\return - void
612 	\note
613 	\warning
614 */
mem_Free(void * pMem)615 void mem_Free(void *pMem)
616 {
617     vPortFree( pMem );
618 }
619 
620 /*!
621 	\brief 	This function call the memset function
622 	\param	pBuf	     -	 pointer to the memory to be fill
623         \param  Val          -   Value to be fill
624         \param  Size         -   Size of the memory which needs to be fill
625 	\return - void
626 	\note
627 	\warning
628 */
629 
mem_set(void * pBuf,int Val,size_t Size)630 void  mem_set(void *pBuf,int Val,size_t Size)
631 {
632     memset( pBuf,Val,Size);
633 }
634 
635 /*!
636       \brief 	This function call the memcopy function
637       \param	pDst	-	pointer to the destination
638       \param pSrc     -   pointer to the source
639       \param Size     -   Size of the memory which needs to be copy
640 
641       \return - void
642       \note
643       \warning
644 */
mem_copy(void * pDst,void * pSrc,size_t Size)645 void  mem_copy(void *pDst, void *pSrc,size_t Size)
646 {
647     memcpy(pDst,pSrc,Size);
648 }
649 
650 
651 /*!
652 	\brief 	This function use to entering into critical section
653 	\param	void
654 	\return - void
655 	\note
656 	\warning
657 */
658 
osi_EnterCritical(void)659 void osi_EnterCritical(void)
660 {
661     vPortEnterCritical();
662 }
663 
664 /*!
665 	\brief 	This function use to exit critical section
666 	\param	void
667 	\return - void
668 	\note
669 	\warning
670 */
671 
osi_ExitCritical(void)672 void osi_ExitCritical(void)
673 {
674     vPortExitCritical();
675 }
676 /*!
677 	\brief 	This function used to start the scheduler
678 	\param	void
679 	\return - void
680 	\note
681 	\warning
682 */
683 __attribute__ ((section (".boot")))
osi_start()684 void osi_start()
685 {
686     vTaskStartScheduler();
687 }
688 /*!
689 	\brief 	This function used to suspend the task for the specified number of milli secs
690 	\param	MilliSecs	-	Time in millisecs to suspend the task
691 	\return - void
692 	\note
693 	\warning
694 */
osi_Sleep(unsigned int MilliSecs)695 void osi_Sleep(unsigned int MilliSecs)
696 {
697 	vTaskDelay(MilliSecs);
698 }
699 
700 
701 /*!
702 	\brief 	This function used to disable the tasks
703 	\param	- void
704 	\return - Key with the suspended tasks
705 	\note
706 	\warning
707 */
osi_TaskDisable(void)708 void osi_TaskDisable(void)
709 {
710    vTaskSuspendAll();
711 }
712 
713 
714 /*!
715 	\brief 	This function used to resume all the tasks
716 	\param	key	-	returned from suspend tasks
717 	\return - void
718 	\note
719 	\warning
720 */
osi_TaskEnable(void)721 void osi_TaskEnable(void)
722 {
723    xTaskResumeAll();
724 }
725 
726 /*!
727 	\brief 	This function used to save the OS context before sleep
728 	\param	void
729 	\return - void
730 	\note
731 	\warning
732 */
osi_ContextSave()733 void osi_ContextSave()
734 {
735 
736 }
737 /*!
738 	\brief 	This function used to restore the OS context after sleep
739 	\param	void
740 	\return - void
741 	\note
742 	\warning
743 */
osi_ContextRestore()744 void osi_ContextRestore()
745 {
746 
747 }
748