first commit

This commit is contained in:
jeffrey 2015-11-17 10:30:14 +08:00
parent 48de61fed7
commit 28cd8da44d
1181 changed files with 784669 additions and 0 deletions

View file

@ -0,0 +1,127 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
*
******************************************************************************/
#ifndef __MAILBOX_H_
#define __MAILBOX_H_
#include "hal_api.h"
#include "osdep_api.h"
#include "hal_util.h"
#ifdef CONFIG_FREERTOS
#include "queue.h"
#endif
#define MBOX_WAIT_NO_TIMEOUT 0xffffffff // waiting for send/receive message with no timeout
#define MBOX_WAIT_NONE 0 // No wait for send/receive message
typedef enum _MAILBOX_ID_ {
MBOX_ID_WLAN = 0,
MBOX_ID_UART = 1,
MBOX_ID_I2C = 2,
MBOX_ID_I2S = 3,
MBOX_ID_SPI = 4,
MBOX_ID_SDIO = 5,
MBOX_ID_SDIO_MP = 6,
MBOX_ID_MAX = 0xff
} MAILBOX_ID;
#if defined(CONFIG_SDIO_DEVICE_EN) && defined(CONFIG_SDIO_DEVICE_NORMAL)
typedef enum _MSG_TYPE_SDIO {
MSG_SDIO_RX_PKT=1, // request to send a SDIO RX packet to the host side
MSG_SDIO_C2H=2, // request to send a C2H message
MSG_SDIO_RPWM=3, // request to set the RPWM
MSG_SDIO_MP_LOOP_TXPKT=4, // request to loopback this TX packet
MSG_SDIO_MAX=0xff
} MSG_TYPE_SDIO;
#endif // end of "#ifdef CONFIG_SDIO_DEVICE_EN"
/* the data structure of a MailBox to deliver message blocks */
typedef struct _RTL_MAILBOX_ {
void *mbox_hdl; // the mailbox handle which return from OS create queue API
_Sema *pWakeSema; // the semaphore to wakeup the message receiving task
_LIST mbox_list; // the link list to chain all created mailbox
u8 mbox_id; /* the ID of this Mailbox, this ID is
used to locate the MBox for send/get message */
} RTL_MAILBOX, *PRTL_MAILBOX;
/* the data structure of a message block */
typedef struct _RTL_MSG_BLK {
u8 MsgType; // the message type
u8 Reserved; // reserved
u16 DateLen; // the vaild data length of the pBuf
u32 Para; // the optional parameters associated with this message type
u8 *pBuf; // point to a data buffer associated with this message type
} MSG_BLK, *PMSG_BLK;
/* the data structure for system level message block management */
typedef struct _RTL_MBOX_ROOT_ {
_LIST mbox_list; // the link list of all created mailbox
_Mutex Mutex; // the Mutex to protect the mailbox create/delete procedure
u8 isInitialed; // is this Mailbox link-list initialed
} RTL_MBOX_ROOT, *PRTL_MBOX_ROOT;
// Export Funcction API
extern PRTL_MAILBOX RtlMailboxCreate(
IN u8 MboxID,
IN u32 MboxSize,
IN _Sema *pWakeSema
);
extern VOID RtlMailboxDel(
IN PRTL_MAILBOX MboxHdl
);
extern u8 RtlMailboxSendToBack(
IN u8 MboxID,
IN MSG_BLK *pMsg,
IN u32 MSToWait,
IN u8 IsFromISR
);
extern u8 RtlMailboxSendToFront(
IN u8 MboxID,
IN MSG_BLK *pMsg,
IN u32 MSToWait,
IN u8 IsFromISR
);
extern u8 RtlMailboxReceive(
IN u8 MboxID,
OUT MSG_BLK *pMsg,
IN u32 MSToWait,
IN u8 IsFromISR
);
extern u8 RtlMailboxPeek(
IN u8 MboxID,
OUT MSG_BLK *pMsg,
IN u32 MSToWait,
IN u8 IsFromISR
);
extern u32 RtlMailboxMsgWaiting(
IN u8 MboxID,
IN u8 IsFromISR
);
#endif // #ifndef __MAILBOX_H_

View file

@ -0,0 +1,344 @@
/******************************************************************************
*
* Name: sys-support.h - System type support for Linux
* $Revision: 1.1.1.1 $
*
*****************************************************************************/
#ifndef __OS_SUPPORT_H__
#define __OS_SUPPORT_H__
#include <FreeRTOS.h>
#include <basic_types.h>
#include "os_support.h"
//#include "diag.h"
#if 0
#define __init
#define __exit
#define __devinit
#define __devexit
#endif
#define RTL_HZ 100
#define SemaInit(sem, value) vSemaphoreCreateBinary(sem)
#define SemaPost(sem) xSemaphoreGive(sem)
#define SemaWait(sem, block_time) xSemaphoreTake(sem, block_time)
//#define printk DiagPrintf
#define SpinLockInit(lock) do { } while (0)
#define SpinLock(x) do { } while (0)
#define SpinUnlock(x) do { } while (0)
#define SpinLockBh(x) do { } while (0)
#define SpinUnlockBh(x) do { } while (0)
#ifdef PLATFORM_FREERTOS
#define RestoreFlags() portEXIT_CRITICAL()
#define SaveAndCli() portENTER_CRITICAL()
#define SpinLockIrqSave(lock, flags) SaveAndCli()
#define SpinUnlockIrqRestore(l, f) RestoreFlags()
#else
#define RestoreFlags(x) portENABLE_INTERRUPTS()
#define SaveAndCli(x) portDISABLE_INTERRUPTS()
#define SpinLockIrqSave(lock, flags) SaveAndCli(flags)
#define SpinUnlockIrqRestore(l, f) RestoreFlags(f)
#endif
//#define RtlKmalloc(size, flag) pvPortMallocAligned(size, 0)
#define RtlKmalloc(size, flag) pvPortMalloc(size)
#define RtlKfree(pv) vPortFreeAligned(pv)
#ifdef CONFIG_TIMER_MODULE
extern _LONG_CALL_ u32 HalDelayUs(u32 us);
#define __Delay(t) HalDelayUs(t)
#else
static __inline__ u32 __Delay(u32 us)
{
DBG_8195A("No Delay: please enable hardware Timer\n");
}
#endif
#define Mdelay(t) __Delay(t*1000)
#define Udelay(t) __Delay(t)
#define ASSERT(_bool_) do { } while (0)
//#define panic_printk DiagPrintf
//#define sprintf DiagPrintf
//#define diag_sprintf DiagPrintf
//1TODO: Need check again; the below just for compile ok ; chris
/*
* ATOMIC_READ - read atomic variable
* @v: pointer of type atomic_t
*
* Atomically reads the value of @v. Note that the guaranteed
* useful range of an atomic_t is only 24 bits.
*/
//#define AtomicRead(v) ((*v))
extern __inline__ u32
AtomicRead(
IN atomic_t * v
)
{
#ifdef PLATFORM_FREERTOS
u32 Temp;
SaveAndCli();
Temp = v->counter;
RestoreFlags();
return Temp;
#else
u32 Temp, Flags;
SaveAndCli(Flags);
Temp = v->counter;
RestoreFlags(Flags);
return Temp;
#endif
}
/*
* ATOMIC_SET - set atomic variable
* @v: pointer of type atomic_t
* @i: required value
*
* Atomically sets the value of @v to @i. Note that the guaranteed
* useful range of an atomic_t is only 24 bits.
*/
//#define AtomicSet(v,i) ((v)->counter = (i))
extern __inline__ VOID
AtomicSet(
IN u32 i,
IN atomic_t * v
)
{
#ifdef PLATFORM_FREERTOS
SaveAndCli();
v->counter = i;
RestoreFlags();
#else
u32 Flags;
SaveAndCli(Flags);
v->counter = i;
RestoreFlags(Flags);
#endif
}
/*
* The MIPS I implementation is only atomic with respect to
* interrupts. R3000 based multiprocessor machines are rare anyway ...
*
* AtomicAdd - add integer to atomic variable
* @i: integer value to add
* @v: pointer of type atomic_t
*
* Atomically adds @i to @v. Note that the guaranteed useful range
* of an atomic_t is only 24 bits.
*/
extern __inline__ VOID
AtomicAdd(
IN u32 i,
IN atomic_t * v
)
{
#ifdef PLATFORM_FREERTOS
SaveAndCli();
v->counter += i;
RestoreFlags();
#else
u32 Flags;
SaveAndCli(Flags);
v->counter += i;
RestoreFlags(Flags);
#endif
}
/*
* AtomicSub - subtract the atomic variable
* @i: integer value to subtract
* @v: pointer of type atomic_t
*
* Atomically subtracts @i from @v. Note that the guaranteed
* useful range of an atomic_t is only 24 bits.
*/
extern __inline__ void
AtomicSub(
IN u32 i,
IN atomic_t * v
)
{
#ifdef PLATFORM_FREERTOS
SaveAndCli();
v->counter -= i;
RestoreFlags();
#else
u32 Flags;
SaveAndCli(Flags);
v->counter -= i;
RestoreFlags(Flags);
#endif
}
extern __inline__ u32
AtomicAddReturn(
IN u32 i,
IN atomic_t * v
)
{
#ifdef PLATFORM_FREERTOS
u32 Temp;
SaveAndCli();
Temp = v->counter;
Temp += i;
v->counter = Temp;
RestoreFlags();
return Temp;
#else
u32 Temp, Flags;
SaveAndCli(Flags);
Temp = v->counter;
Temp += i;
v->counter = Temp;
RestoreFlags(Flags);
return Temp;
#endif
}
extern __inline__ u32
AtomicSubReturn(
IN u32 i,
IN atomic_t * v
)
{
#ifdef PLATFORM_FREERTOS
u32 Temp;
SaveAndCli();
Temp = v->counter;
Temp -= i;
v->counter = Temp;
RestoreFlags();
return Temp;
#else
u32 Temp, Flags;
SaveAndCli(Flags);
Temp = v->counter;
Temp -= i;
v->counter = Temp;
RestoreFlags(Flags);
return Temp;
#endif
}
/*
* ATOMIC_INC - increment atomic variable
* @v: pointer of type atomic_t
*
* Atomically increments @v by 1. Note that the guaranteed
* useful range of an atomic_t is only 24 bits.
*/
#define AtomicInc(v) AtomicAdd(1,(v))
#define AtomicIncReturn(v) AtomicAddReturn(1,(v))
/*
* ATOMIC_DEC - decrement and test
* @v: pointer of type atomic_t
*
* Atomically decrements @v by 1. Note that the guaranteed
* useful range of an atomic_t is only 24 bits.
*/
#define AtomicDec(v) AtomicSub(1,(v))
#define AtomicDecReturn(v) AtomicSubReturn(1,(v))
/*
* ATOMIC_DEC_AND_TEST - decrement by 1 and test
* @v: pointer of type atomic_t
*
* Atomically decrements @v by 1 and
* returns true if the result is 0, or false for all other
* cases. Note that the guaranteed
* useful range of an atomic_t is only 24 bits.
*/
#define AtomicDecAndTest(v) (AtomicSubReturn(1, (v)) == 0)
/* Not needed on 64bit architectures */
static __inline__ u32
__Div64_32(
IN __uint64_t *n,
IN u32 base
)
{
__uint64_t rem = *n;
__uint64_t b = base;
__uint64_t res, d = 1;
u32 high = rem >> 32;
/* Reduce the thing a bit first */
res = 0;
if (high >= base) {
high /= base;
res = (__uint64_t) high << 32;
rem -= (__uint64_t) (high*base) << 32;
}
while ((__int64_t)b > 0 && b < rem) {
b = b+b;
d = d+d;
}
do {
if (rem >= b) {
rem -= b;
res += d;
}
b >>= 1;
d >>= 1;
} while (d);
*n = res;
return rem;
}
#define DO_DIV(n,base) ({ \
unsigned int __base = (base); \
unsigned int __rem; \
(void)(((typeof((n)) *)0) == ((__uint64_t *)0)); \
if (((n) >> 32) == 0) { \
__rem = (unsigned int)(n) % __base; \
(n) = (unsigned int)(n) / __base; \
} else \
__rem = __Div64_32(&(n), __base); \
__rem; \
})
#endif /* __SYS_SUPPORT_H__ */

View file

@ -0,0 +1,215 @@
/******************************************************************************
*
* Name: sys-support.h - System type support for Linux
* $Revision: 1.1.1.1 $
*
*****************************************************************************/
#ifndef __OS_TIMER_H__
#define __OS_TIMER_H__
#include "diag.h"
#include "os_support.h"
#include "timers.h"
#define JIFFIES xTaskGetTickCount()
enum {
TIMER_NO_INIT = 0,
TIMER_INIT = 1,
TIMER_START = 2,
TIMER_DISABLE = 3
};
struct TIMER_LIST {
xTimerHandle TimeHdl;
u32 Flag;
unsigned long Data;
VOID (*Function)(void *);
u32 TimerID;
};
static inline VOID
InitTimer(
IN struct TIMER_LIST *Timer
)
{
#ifdef RTK_MODE_TIMER
u32 data = Timer->Data;
#endif
#ifndef PLATFORM_FREERTOS
u32 Flags;
#endif
u32 TimerID = Timer->TimerID;
VOID (*Function)(VOID *) = Timer->Function;
// xTimerHandle timer_handle;
#ifdef PLATFORM_FREERTOS
SaveAndCli();
#else
SaveAndCli(Flags);
#endif
if (Timer->Flag != TIMER_DISABLE) {
if (Timer->Flag == TIMER_NO_INIT) {
Timer->TimeHdl = xTimerCreate( (const char *)"Timer", // Just a test name, not used by the kernel.
( 100 ), // The timer period in ticks.
pdFALSE, // The timers will auto-reload themselves when they expire.
( void * ) TimerID, // Assign each timer a unique id equal to its array index.
Function
#ifdef RTK_MODE_TIMER
,data // Each timer calls the same callback when it expires.
#endif
);
if (NULL == Timer->TimeHdl) {
DBG_ERROR_LOG("\rInitial Timer fail !!!!!!!!!\n");
}
else {
TimerID++;
}
Timer->Flag = TIMER_INIT;
}
else if (Timer->Flag == TIMER_START) {
xTimerStop(Timer->TimeHdl,0);
Timer->Flag = TIMER_DISABLE;
}
}
#ifdef PLATFORM_FREERTOS
RestoreFlags();
#else
RestoreFlags(Flags);
#endif
}
static inline void
ModTimer(
IN struct TIMER_LIST *Timer,
IN u32 TimeoutTicks
)
{
#ifndef PLATFORM_FREERTOS
u32 Flags;
#endif
void (*Function)(void *) = Timer->Function;
#ifdef PLATFORM_FREERTOS
SaveAndCli();
#else
SaveAndCli(Flags);
#endif
if (Timer->Flag == TIMER_NO_INIT) {
if (Timer->Function) {
Timer->TimeHdl = xTimerCreate((const char *)"Timer", // Just a text name, not used by the kernel.
( 100 ), // The timer period in ticks.
pdFALSE, // The timers will auto-reload themselves when they expire.
( void * ) Timer->TimerID, // Assign each timer a unique id equal to its array index.
Function
#ifdef RTK_MODE_TIMER
,Timer->Data // Each timer calls the same callback when it expires.
#endif
);
if (NULL == Timer->TimeHdl) {
DBG_ERROR_LOG("\rInitial Timer fail !!!!!!!!!\n");
}
else {
Timer->TimerID++;
}
Timer->Flag = TIMER_INIT;
}
else {
//printf("###mod_timer() not initilized, timer->flag=%d timer->function=%p timeout_ticks=%llu###\n", timer->flag, timer->function, timeout_ticks);
#ifdef PLATFORM_FREERTOS
RestoreFlags();
#else
RestoreFlags(Flags);
#endif
return;
}
}
else if (Timer->Flag == TIMER_START) {
xTimerStop(Timer->TimeHdl,0);
Timer->Flag = TIMER_DISABLE;
}
TimeoutTicks -= xTaskGetTickCount();
if (TimeoutTicks <= 0)
TimeoutTicks = 2;
if (xTimerStart(Timer->TimeHdl, TimeoutTicks ))
Timer->Flag = TIMER_START;
else
DBG_ERROR_LOG("\r###mod_timer() - no slots available###\n");
#ifdef PLATFORM_FREERTOS
RestoreFlags();
#else
RestoreFlags(Flags);
#endif
}
static inline int
TimerPending (
IN const struct TIMER_LIST *Timer
)
{
if (Timer->TimeHdl && Timer->Flag != TIMER_NO_INIT)
return 1;
else
return 0;
}
static inline void
DelTimerSync(
IN struct TIMER_LIST *Timer
)
{
#ifdef PLATFORM_FREERTOS
SaveAndCli();
#else
u32 Flags;
SaveAndCli(Flags);
#endif
if (Timer->TimeHdl && Timer->Flag != TIMER_INIT) {
if (Timer->Flag == TIMER_START)
xTimerStop(Timer->TimeHdl, 0);
xTimerDelete(Timer->TimeHdl, 0);
Timer->Flag = TIMER_NO_INIT;
}
#ifdef PLATFORM_FREERTOS
RestoreFlags();
#else
RestoreFlags(Flags);
#endif
}
/*
* These inlines deal with timer wrapping correctly. You are
* strongly encouraged to use them
* 1. Because people otherwise forget
* 2. Because if the timer wrap changes in future you wont have to
* alter your driver code.
*
* time_after(a,b) returns true if the time a is after time b.
*
* Do this with "<0" and ">=0" to only test the sign of the result. A
* good compiler would generate better code (and a really good compiler
* wouldn't care). Gcc is currently neither.
*/
#define TIME_AFTER(a,b) ((long)(b) - (long)(a) < 0)
#define TIMER_BEFORE(a,b) TIME_AFTER(b,a)
#define TIME_AFTER_EQ(a,b) ((long)(a) - (long)(b) >= 0)
#define TIMER_BEFORE_EQ(a,b) TIME_AFTER_EQ(b,a)
#endif //__OS_TIMER_H__

View file

@ -0,0 +1,561 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
*
******************************************************************************/
#ifndef __OSDEP_API_H_
#define __OSDEP_API_H_
#include "os_timer.h"
#include "os_support.h"
#include "semphr.h"
#if 0
/* Structure used to pass parameters to each task. */
typedef struct SEMAPHORE_PARAMETERS
{
xSemaphoreHandle xSemaphore;
// volatile unsigned long *pulSharedVariable;
portTickType xBlockTime;
} xSemaphoreParameters;
#endif
//#define RTW_STATUS_TIMEDOUT -110
#define MAX_SEMA_COUNT 32 /* the maximum count of a semaphore */
typedef xSemaphoreHandle _Sema;
typedef xSemaphoreHandle _Mutex;
typedef u32 _Lock;
typedef struct TIMER_LIST _Timer;
//typedef unsigned char _buffer;
typedef unsigned long _IRQL;
//typedef struct net_device * _nic_hdl;
typedef xTaskHandle _THREAD_HDL_;
typedef VOID THREAD_RETURN;
typedef VOID* THREAD_CONTEXT;
#ifndef mdelay
#define mdelay(t) ((t/portTICK_RATE_MS)>0)?(vTaskDelay(t/portTICK_RATE_MS)):(vTaskDelay(1))
#endif
#ifndef udelay
#define udelay(t) ((t/(portTICK_RATE_MS*1000))>0)?vTaskDelay(t/(portTICK_RATE_MS*1000)):(vTaskDelay(1))
#endif
/* to delete/start/stop a timer it will send a message to the timer task through a message queue,
so we define the max wait time for message sending */
#define RTL_TIMER_API_MAX_BLOCK_TIME 1000 // unit is ms
#define RTL_TIMER_API_MAX_BLOCK_TICKS (RTL_TIMER_API_MAX_BLOCK_TIME/portTICK_RATE_MS)
typedef VOID
(*RTL_TIMER_CALL_BACK)(
void *pContext
);
typedef struct _RTL_TIMER{
#ifdef PLATFORM_FREERTOS
xTimerHandle TimerHandle; // the timer handle of created FreeRTOS soft-timer
#endif
RTL_TIMER_CALL_BACK CallBackFunc; // Callback function of this timer
u32 msPeriod; // The period of this timer
void *Context; // Timer specific context.
u8 isPeriodical; // is a periodical timer
u8 TimerName[35]; // the Name of timer
}RTL_TIMER, *PRTL_TIMER;
__inline static VOID
RtlEnterCritical(VOID)
{
portENTER_CRITICAL();
}
__inline static VOID
RtlExitCritical(VOID)
{
portEXIT_CRITICAL();
}
__inline static VOID
RtlEnterCriticalBh(
IN _Lock *plock,
IN _IRQL *pirqL
)
{
SpinLockBh(plock);
}
__inline static VOID
RtlExitCriticalBh(
IN _Lock *plock,
IN _IRQL *pirqL
)
{
SpinUnlockBh(plock);
}
__inline static u32
RtlEnterCriticalMutex(
IN _Mutex *pmutex,
IN _IRQL *pirqL
)
{
u32 ret = 0;
xSemaphoreTake(*pmutex, portMAX_DELAY);
return ret;
}
__inline static VOID
RtlExitCriticalMutex(
IN _Mutex *pmutex,
IN _IRQL *pirqL
)
{
xSemaphoreGive(*pmutex);
}
__inline static VOID
RtlInitTimer(
IN _Timer *ptimer,
IN VOID *Data,
IN VOID (*pfunc)(VOID *),
IN VOID* cntx
)
{
ptimer->Function = pfunc;
ptimer->Data = (unsigned long)cntx;
InitTimer(ptimer);
}
__inline static VOID
RtlSetTimer(
IN _Timer *ptimer,
IN u32 delay_time
)
{
ModTimer(ptimer , (JIFFIES+(delay_time*RTL_HZ/1000)));
}
__inline static VOID
RtlCancelTimer(
IN _Timer *ptimer,
IN u8 *bcancelled
)
{
DelTimerSync(ptimer);
*bcancelled= _TRUE;//TRUE ==1; FALSE==0
}
__inline static u32
RtlSystime2Ms(
IN u32 systime
)
{
return systime * 1000 / RTL_HZ;
}
__inline static u32
RtlMs2Systime(
IN u32 ms
)
{
return ms * RTL_HZ / 1000;
}
extern u8* RtlZmalloc(u32 sz);
extern u8* RtlMalloc(u32 sz);
extern VOID RtlMfree(u8 *pbuf, u32 sz);
extern VOID* RtlMalloc2d(u32 h, u32 w, u32 size);
extern VOID RtlMfree2d(VOID *pbuf, u32 h, u32 w, u32 size);
extern VOID RtlInitSema(_Sema *sema, u32 init_val);
extern VOID RtlFreeSema(_Sema *sema);
extern VOID RtlUpSema(_Sema *sema);
extern VOID RtlUpSemaFromISR(_Sema *sema);
extern u32 RtlDownSema(_Sema *sema);
extern u32 RtlDownSemaWithTimeout(_Sema *sema, u32 ms);
extern VOID RtlMutexInit(_Mutex *pmutex);
extern VOID RtlMutexFree(_Mutex *pmutex);
extern VOID RtlSpinlockInit(_Lock *plock);
extern VOID RtlSpinlockFree(_Lock *plock);
extern VOID RtlSpinlock(_Lock *plock);
extern VOID RtlSpinunlock(_Lock *plock);
extern VOID RtlSpinlockEx(_Lock *plock);
extern VOID RtlSpinunlockEx(_Lock *plock);
extern VOID RtlSleepSchedulable(u32 ms);
extern VOID RtlMsleepOS(u32 ms);
extern VOID RtlUsleepOS(u32 us);
extern VOID RtlMdelayOS(u32 ms);
extern VOID RtlUdelayOS(u32 us);
//extern VOID rtw_mdelay_os(u32 ms);
//extern VOID rtw_udelay_os(u32 us);
//1TODO: Need Check if we need add this api
extern VOID RtlYieldOS(VOID);
#define RtlUpMutex(mutex) RtlUpSema(mutex)
#define RtlDownMutex(mutex) RtlDownSema(mutex)
__inline static u8
RtlCancelTimerEx(
IN _Timer *ptimer
)
{
DelTimerSync(ptimer);
return 0;
}
static __inline VOID
ThreadEnter(
IN char *name
)
{
DBG_8195A("\rRTKTHREAD_enter %s\n", name);
}
#define ThreadExit() do{DBG_8195A("\rRTKTHREAD_exit %s\n", __FUNCTION__);}while(0)
__inline static VOID
FlushSignalsThread(VOID)
{
#ifdef PLATFORM_LINUX
if (signal_pending (current))
{
flush_signals(current);
}
#endif
}
#define RTL_RND(sz, r) ((((sz)+((r)-1))/(r))*(r))
#define RTL_RND4(x) (((x >> 2) + (((x & 3) == 0) ? 0: 1)) << 2)
__inline static u32
RtlRnd4(
IN u32 sz
)
{
u32 val;
val = ((sz >> 2) + ((sz & 3) ? 1: 0)) << 2;
return val;
}
__inline static u32
RtlRnd8(
IN u32 sz
)
{
u32 val;
val = ((sz >> 3) + ((sz & 7) ? 1: 0)) << 3;
return val;
}
__inline static u32
RtlRnd128(
IN u32 sz
)
{
u32 val;
val = ((sz >> 7) + ((sz & 127) ? 1: 0)) << 7;
return val;
}
__inline
static u32 RtlRnd256(
IN u32 sz
)
{
u32 val;
val = ((sz >> 8) + ((sz & 255) ? 1: 0)) << 8;
return val;
}
__inline static u32
RtlRnd512(
IN u32 sz
)
{
u32 val;
val = ((sz >> 9) + ((sz & 511) ? 1: 0)) << 9;
return val;
}
__inline static u32
BitShift(
IN u32 BitMask
)
{
u32 i;
for (i = 0; i <= 31; i++)
if (((BitMask>>i) & 0x1) == 1) break;
return i;
}
//#ifdef __GNUC__
#ifdef PLATFORM_LINUX
#define STRUCT_PACKED __attribute__ ((packed))
#else
#define STRUCT_PACKED
#endif
//Atomic integer operations
#define RTL_ATOMIC_T atomic_t
extern inline VOID
RTL_ATOMIC_SET(
IN RTL_ATOMIC_T *v,
IN u32 i
)
{
AtomicSet(i,v);
}
extern inline uint32_t
RTL_ATOMIC_READ(
IN RTL_ATOMIC_T *v
)
{
return AtomicRead(v);
}
extern inline VOID
RTL_ATOMIC_ADD(
IN RTL_ATOMIC_T *v,
IN u32 i
)
{
AtomicAdd(i,v);
}
extern inline VOID
RTL_ATOMIC_SUB(
IN RTL_ATOMIC_T *v,
IN u32 i
)
{
AtomicSub(i,v);
}
extern inline VOID
RTL_ATOMIC_INC(
IN RTL_ATOMIC_T *v
)
{
AtomicInc(v);
}
extern inline VOID
RTL_ATOMIC_DEC(
IN RTL_ATOMIC_T *v
)
{
AtomicDec(v);
}
extern inline u32
RTL_ATOMIC_ADD_RETURN(
IN RTL_ATOMIC_T *v,
IN u32 i
)
{
return AtomicAddReturn(i,v);
}
extern inline u32
RTL_ATOMIC_SUB_RETURN(
IN RTL_ATOMIC_T *v,
IN u32 i
)
{
return AtomicSubReturn(i,v);
}
extern inline u32
RTL_ATOMIC_INC_RETURN(
IN RTL_ATOMIC_T *v
)
{
return AtomicIncReturn(v);
}
extern inline u32
RTL_ATOMIC_DEC_RETURN(
IN RTL_ATOMIC_T *v
)
{
return AtomicDecReturn(v);
}
extern u64 RtlModular64(u64 x, u64 y);
/* Macros for handling unaligned memory accesses */
#if 0
#define RTW_GET_BE16(a) ((u16) (((a)[0] << 8) | (a)[1]))
#define RTW_PUT_BE16(a, val) \
do { \
(a)[0] = ((u16) (val)) >> 8; \
(a)[1] = ((u16) (val)) & 0xff; \
} while (0)
#define RTW_GET_LE16(a) ((u16) (((a)[1] << 8) | (a)[0]))
#define RTW_PUT_LE16(a, val) \
do { \
(a)[1] = ((u16) (val)) >> 8; \
(a)[0] = ((u16) (val)) & 0xff; \
} while (0)
#define RTW_GET_BE24(a) ((((u32) (a)[0]) << 16) | (((u32) (a)[1]) << 8) | \
((u32) (a)[2]))
#define RTW_PUT_BE24(a, val) \
do { \
(a)[0] = (u8) ((((u32) (val)) >> 16) & 0xff); \
(a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff); \
(a)[2] = (u8) (((u32) (val)) & 0xff); \
} while (0)
#define RTW_GET_BE32(a) ((((u32) (a)[0]) << 24) | (((u32) (a)[1]) << 16) | \
(((u32) (a)[2]) << 8) | ((u32) (a)[3]))
#define RTW_PUT_BE32(a, val) \
do { \
(a)[0] = (u8) ((((u32) (val)) >> 24) & 0xff); \
(a)[1] = (u8) ((((u32) (val)) >> 16) & 0xff); \
(a)[2] = (u8) ((((u32) (val)) >> 8) & 0xff); \
(a)[3] = (u8) (((u32) (val)) & 0xff); \
} while (0)
#define RTW_GET_LE32(a) ((((u32) (a)[3]) << 24) | (((u32) (a)[2]) << 16) | \
(((u32) (a)[1]) << 8) | ((u32) (a)[0]))
#define RTW_PUT_LE32(a, val) \
do { \
(a)[3] = (u8) ((((u32) (val)) >> 24) & 0xff); \
(a)[2] = (u8) ((((u32) (val)) >> 16) & 0xff); \
(a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff); \
(a)[0] = (u8) (((u32) (val)) & 0xff); \
} while (0)
#define RTW_GET_BE64(a) ((((u64) (a)[0]) << 56) | (((u64) (a)[1]) << 48) | \
(((u64) (a)[2]) << 40) | (((u64) (a)[3]) << 32) | \
(((u64) (a)[4]) << 24) | (((u64) (a)[5]) << 16) | \
(((u64) (a)[6]) << 8) | ((u64) (a)[7]))
#define RTW_PUT_BE64(a, val) \
do { \
(a)[0] = (u8) (((u64) (val)) >> 56); \
(a)[1] = (u8) (((u64) (val)) >> 48); \
(a)[2] = (u8) (((u64) (val)) >> 40); \
(a)[3] = (u8) (((u64) (val)) >> 32); \
(a)[4] = (u8) (((u64) (val)) >> 24); \
(a)[5] = (u8) (((u64) (val)) >> 16); \
(a)[6] = (u8) (((u64) (val)) >> 8); \
(a)[7] = (u8) (((u64) (val)) & 0xff); \
} while (0)
#define RTW_GET_LE64(a) ((((u64) (a)[7]) << 56) | (((u64) (a)[6]) << 48) | \
(((u64) (a)[5]) << 40) | (((u64) (a)[4]) << 32) | \
(((u64) (a)[3]) << 24) | (((u64) (a)[2]) << 16) | \
(((u64) (a)[1]) << 8) | ((u64) (a)[0]))
#endif
extern PRTL_TIMER
RtlTimerCreate(
IN char *pTimerName,
IN u32 TimerPeriodMS,
IN RTL_TIMER_CALL_BACK CallbckFunc,
IN void *pContext,
IN u8 isPeriodical
);
extern VOID
RtlTimerDelete(
IN PRTL_TIMER pTimerHdl
);
extern u8
RtlTimerStart(
IN PRTL_TIMER pTimerHdl,
IN u8 isFromISR
);
extern u8
RtlTimerStop(
IN PRTL_TIMER pTimerHdl,
IN u8 isFromISR
);
extern u8
RtlTimerReset(
IN PRTL_TIMER pTimerHdl,
IN u8 isFromISR
);
extern u8
RtlTimerChangePeriod(
IN PRTL_TIMER pTimerHdl,
IN u32 NewPeriodMS,
IN u8 isFromISR
);
#endif //#ifndef __OSDEP_API_H_

View file

@ -0,0 +1,574 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
*
******************************************************************************/
#define _MAILBOX_C_
#include "mailbox.h"
/******************************************************************************
* Function Prototype Declaration
******************************************************************************/
static PRTL_MAILBOX RtlMBoxIdToHdl(
IN u8 MBoxId
);
PRTL_MAILBOX RtlMailboxCreate(
IN u8 MboxID,
IN u32 MboxSize,
IN _Sema *pWakeSema
);
VOID RtlMailboxDel(
IN PRTL_MAILBOX MboxHdl
);
u8 RtlMailboxSendToBack(
IN u8 MboxID,
IN MSG_BLK *pMsg,
IN u32 MSToWait,
IN u8 IsFromISR
);
u8 RtlMailboxSendToFront(
IN u8 MboxID,
IN MSG_BLK *pMsg,
IN u32 MSToWait,
IN u8 IsFromISR
);
u8 RtlMailboxReceive(
IN u8 MboxID,
OUT MSG_BLK *pMsg,
IN u32 MSToWait,
IN u8 IsFromISR
);
u8 RtlMailboxPeek(
IN u8 MboxID,
OUT MSG_BLK *pMsg,
IN u32 MSToWait,
IN u8 IsFromISR
);
u32 RtlMailboxMsgWaiting(
IN u8 MboxID,
IN u8 IsFromISR
);
/******************************************************************************
* Global Variable Declaration
******************************************************************************/
static RTL_MBOX_ROOT MBox_Entry={0};
/******************************************************************************
* External Function & Variable Declaration
******************************************************************************/
/******************************************************************************
* Function: RtlMBoxIdToHdl
* Desc: Map a mailbox ID to the mailbox pointer.
* Para:
* MBoxId: The Mailbox ID
* Return: The pointer of the mailbox. If didn't found match mailbox,
* return NULL.
*
******************************************************************************/
static PRTL_MAILBOX RtlMBoxIdToHdl(
IN u8 MBoxId
)
{
RTL_MAILBOX *pMbox=NULL;
RTL_MAILBOX *pTmpMbox;
_LIST *pHead;
_LIST *pList;
// if the Mailbox root entry initialed ? if not, initial it
if (!MBox_Entry.isInitialed) {
RtlMutexInit(&MBox_Entry.Mutex); // Init the Mutex for the mailbox add/delete procedure protection
RtlInitListhead(&MBox_Entry.mbox_list); // Init the link list head to chain all created mailbox
MBox_Entry.isInitialed = 1;
MSG_MBOX_INFO("MBox Entry Initial...\n");
}
pHead = &MBox_Entry.mbox_list;
RtlDownMutex(&MBox_Entry.Mutex);
pList = RtlListGetNext(&MBox_Entry.mbox_list);
while (pList != pHead) {
pTmpMbox = CONTAINER_OF(pList, RTL_MAILBOX, mbox_list);
if (MBoxId == pTmpMbox->mbox_id) {
pMbox = pTmpMbox;
break;
}
pList = RtlListGetNext(pList);
}
RtlUpMutex(&MBox_Entry.Mutex);
return pMbox;
}
/******************************************************************************
* Function: RtlMailboxCreate
* Desc: To create a mailbox with a given mailbox ID and size
* Para:
* MboxID: A number to identify this created mailbox. A message block can
* be send to a mailbox by a given MboxID. The MboxID must be unique
* in the whole system. If this MboxID is conflict with a created
* mailbox, the mailbox creation will fail and return NULL.
* MboxSize: The size of this mailbox to be created. It means maximum number
* of message blocks can be stored in this mailbox.
* pWakeSema: The semaphore to wake up the receiving task to receive the new
* message. If the receiving task doesn't need a semaphore to wakeup
* it, then just let this pointer is NULL.
* Return: The created mailbox pointer. If it failed, return NULL.
******************************************************************************/
PRTL_MAILBOX RtlMailboxCreate(
IN u8 MboxID,
IN u32 MboxSize,
IN _Sema *pWakeSema
)
{
PRTL_MAILBOX pMBox=NULL;
// if the Mailbox root entry initialed ? if not, initial it
if (!MBox_Entry.isInitialed) {
RtlMutexInit(&MBox_Entry.Mutex); // Init the Mutex for the mailbox add/delete procedure protection
RtlInitListhead(&MBox_Entry.mbox_list); // Init the link list head to chain all created mailbox
MBox_Entry.isInitialed = 1;
MSG_MBOX_INFO("MBox Entry Initial...\n");
}
// check if this mailbox ID is ocupied ?
pMBox = RtlMBoxIdToHdl(MboxID);
if (NULL != pMBox) {
MSG_MBOX_ERR("RtlMailboxCreate: The Mailbox ID %d is used by someone!!\n", MboxID);
return NULL;
}
pMBox = (RTL_MAILBOX *)RtlZmalloc(sizeof(RTL_MAILBOX));
if (NULL==pMBox) {
MSG_MBOX_ERR("RtlMailboxCreate: MAlloc Failed\n");
return NULL;
}
RtlInitListhead(&pMBox->mbox_list); // Init the link list to be chained into the created mailbox list
pMBox->mbox_id = MboxID;
pMBox->pWakeSema = pWakeSema;
#ifdef PLATFORM_FREERTOS
pMBox->mbox_hdl = xQueueCreate(MboxSize, sizeof(MSG_BLK));
if (NULL == pMBox->mbox_hdl) {
MSG_MBOX_ERR("RtlMailboxCreate: xQueueCreate Failed\n");
RtlMfree((void *)pMBox, sizeof(RTL_MAILBOX));
return NULL;
}
#endif
#ifdef PLATFORM_ECOS
// TODO: Create mailbox
#endif
// Add this mailbox to the link list of created mailbox
RtlDownMutex(&MBox_Entry.Mutex);
RtlListInsertTail(&pMBox->mbox_list, &MBox_Entry.mbox_list);
RtlUpMutex(&MBox_Entry.Mutex);
MSG_MBOX_INFO("A Mailbox Created: Size=%d\n", MboxSize);
return pMBox;
}
/******************************************************************************
* Function: RtlMailboxDel
* Desc: To delete a mailbox by a given mailbox handle.
* Para:
* MboxHdl: The handle of the mailbox to be deleted.
* Return: None.
******************************************************************************/
VOID RtlMailboxDel(
IN PRTL_MAILBOX MboxHdl
)
{
if (NULL == MboxHdl) {
MSG_MBOX_ERR("RtlMailboxDel: Try to delete a NULL mailbox\n");
return;
}
// Remove this mailbox from the link list of created mailbox
RtlDownMutex(&MBox_Entry.Mutex);
RtlListDelete(&MboxHdl->mbox_list);
RtlUpMutex(&MBox_Entry.Mutex);
// delete the Queue/Mailbox
#ifdef PLATFORM_FREERTOS
vQueueDelete((xQueueHandle)(MboxHdl->mbox_hdl));
#endif
#ifdef PLATFORM_ECOS
// TODO: Delete mailbox
#endif
RtlMfree((void *)MboxHdl, sizeof(RTL_MAILBOX));
}
/******************************************************************************
* Function: RtlMailboxSendToBack
* Desc: To put a message block to the tail of a given mailbox.
* Para:
* MboxID: The identifier of the target mailbox.
* pMsg: The pointer of the message block to be put into the mailbox.
* MSToWait: If the mailbox is full, this value gives a time to wait to put
* this message. The time unit is millisecond.
* The special values are:
* 0: no waiting;
* 0xffffffff: wait without timeout.
* If the waiting is timeout, the message sending is failed and
* return _FAIL.
* IsFromISR: Is this function is called from an ISR ?
* Return: _SUCCESS or _FAIL.
******************************************************************************/
u8 RtlMailboxSendToBack(
IN u8 MboxID,
IN MSG_BLK *pMsg,
IN u32 MSToWait,
IN u8 IsFromISR
)
{
RTL_MAILBOX *pMbox=NULL;
u32 wait_ticks;
#ifdef PLATFORM_FREERTOS
portBASE_TYPE ret;
#endif
pMbox = RtlMBoxIdToHdl(MboxID);
if (NULL == pMbox) {
MSG_MBOX_ERR("RtlMailboxSendToBack: Didn't find matched MBoxID=%d\n", MboxID);
return _FAIL;
}
#ifdef PLATFORM_FREERTOS
if (MBOX_WAIT_NO_TIMEOUT == MSToWait) {
wait_ticks = portMAX_DELAY;
}
else if (MBOX_WAIT_NONE == MSToWait) {
wait_ticks = 0;
}
else {
wait_ticks = ((MSToWait/portTICK_RATE_MS)>0)?(MSToWait/portTICK_RATE_MS):(1);
}
if (IsFromISR) {
ret = xQueueSendToBackFromISR(pMbox->mbox_hdl, (void *)pMsg, NULL);//(portTickType) wait_ticks);
}
else {
ret = xQueueSendToBack(pMbox->mbox_hdl, (void *)pMsg, (portTickType) wait_ticks);
}
if(ret != pdPASS ) {
// send message to the queue failed
MSG_MBOX_ERR("RtlMailboxSendToBack: Put Msg to Queue Failed, MBoxID=%d\n", MboxID);
ret = _FAIL;
}
else {
// try to give a semaphore to wake up the receiving task
if (pMbox->pWakeSema) {
RtlUpSema(pMbox->pWakeSema);
}
ret = _SUCCESS;
}
return ret;
#endif
#ifdef PLATFORM_ECOS
// TODO: Put the message to a mailbox
#endif
}
/******************************************************************************
* Function: RtlMailboxSendToFront
* Desc: To put a message block to the head of a mailbox.
* Para:
* MboxID: The identifier of the target mailbox.
* pMsg: The pointer of the message block to be put into the mailbox.
* MSToWait: If the mailbox is full, this value gives a time to wait to put
* this message. The time unit is millisecond.
* The special values are:
* 0: no waiting;
* 0xffffffff: wait without timeout.
* If the waiting is timeout, the message sending is failed and
* return _FAIL.
* IsFromISR: Is this function is called from an ISR ?
* Return: _SUCCESS or _FAIL.
******************************************************************************/
u8 RtlMailboxSendToFront(
IN u8 MboxID,
IN MSG_BLK *pMsg,
IN u32 MSToWait,
IN u8 IsFromISR
)
{
RTL_MAILBOX *pMbox=NULL;
u32 wait_ticks;
#ifdef PLATFORM_FREERTOS
portBASE_TYPE ret;
#endif
pMbox = RtlMBoxIdToHdl(MboxID);
if (NULL == pMbox) {
MSG_MBOX_ERR("RtlMailboxSendToBack: Didn't find matched MBoxID=%d\n", MboxID);
return _FAIL;
}
#ifdef PLATFORM_FREERTOS
if (MBOX_WAIT_NO_TIMEOUT == MSToWait) {
wait_ticks = portMAX_DELAY;
}
else if (MBOX_WAIT_NONE == MSToWait) {
wait_ticks = 0;
}
else {
wait_ticks = ((MSToWait/portTICK_RATE_MS)>0)?(MSToWait/portTICK_RATE_MS):(1);
}
if (IsFromISR) {
ret = xQueueSendToFrontFromISR(pMbox->mbox_hdl, (void *)pMsg, NULL);//(portTickType) wait_ticks);
}
else {
ret = xQueueSendToFront(pMbox->mbox_hdl, (void *)pMsg, (portTickType) wait_ticks);
}
if(ret != pdPASS ) {
// send message to the queue failed
MSG_MBOX_ERR("RtlMailboxSendToBack: Put Msg to Queue Failed, MBoxID=%d\n", MboxID);
ret = _FAIL;
}
else {
// try to give a semaphore to wake up the receiving task
if (pMbox->pWakeSema) {
RtlUpSema(pMbox->pWakeSema);
}
ret = _SUCCESS;
}
return ret;
#endif
#ifdef PLATFORM_ECOS
// TODO: eCos has no API to put message to the head of a mailbox
#endif
}
/******************************************************************************
* Function: RtlMailboxSendToFront
* Desc: To get a message block from a given mailbox.
* Para:
* MboxID: The identifier of the target mailbox.
* pMsg: The message block to store the gotten message.
* MSToWait: If the mailbox is full, this value gives a time to wait to put
* this message. The time unit is millisecond.
* The special values are:
* 0: no waiting;
* 0xffffffff: wait without timeout.
* If the waiting is timeout, the message sending is failed and
* return _FAIL.
* IsFromISR: Is this function is called from an ISR ?
* Return: _SUCCESS or _FAIL.
******************************************************************************/
u8 RtlMailboxReceive(
IN u8 MboxID,
OUT MSG_BLK *pMsg,
IN u32 MSToWait,
IN u8 IsFromISR
)
{
RTL_MAILBOX *pMbox=NULL;
u32 wait_ticks;
#ifdef PLATFORM_FREERTOS
portBASE_TYPE ret;
#endif
pMbox = RtlMBoxIdToHdl(MboxID);
if (NULL == pMbox) {
MSG_MBOX_ERR("RtlMailboxReceive: Didn't find the MBox with ID=%d\n", MboxID);
return _FAIL;
}
#ifdef PLATFORM_FREERTOS
if (MBOX_WAIT_NONE == MSToWait) {
wait_ticks = 0;
}
else if (MBOX_WAIT_NO_TIMEOUT == MSToWait) {
wait_ticks = portMAX_DELAY;
}
else {
wait_ticks = ((MSToWait/portTICK_RATE_MS)>0)?(MSToWait/portTICK_RATE_MS):(1);
}
if (IsFromISR) {
ret = xQueueReceiveFromISR(pMbox->mbox_hdl, (void *)pMsg, NULL);//( portTickType ) wait_ticks);
}
else {
ret = xQueueReceive(pMbox->mbox_hdl, (void *)pMsg, ( portTickType ) wait_ticks);
}
if(ret != pdTRUE ) {
// receive message failed
if (0 != MSToWait) {
MSG_MBOX_ERR("RtlMailboxReceive: Receive Msg Failed, MBoxID=%d\n", MboxID);
}
ret = _FAIL;
}
else {
ret = _SUCCESS;
}
return ret;
#endif
#ifdef PLATFORM_ECOS
// TODO: Get a message from the mailbox
#endif
}
/******************************************************************************
* Function: RtlMailboxPeek
* Desc: To copy the head message from a given mailbox without move this
* message block out from the mailbox.
* Para:
* MboxID: The identifier of the target mailbox.
* pMsg: The message block to store the gotten message.
* MSToWait: If the mailbox is full, this value gives a time to wait to put
* this message. The time unit is millisecond.
* The special values are:
* 0: no waiting;
* 0xffffffff: wait without timeout.
* If the waiting is timeout, the message sending is failed and
* return _FAIL.
* IsFromISR: Is this function is called from an ISR ?
* Return: _SUCCESS or _FAIL.
******************************************************************************/
u8 RtlMailboxPeek(
IN u8 MboxID,
OUT MSG_BLK *pMsg,
IN u32 MSToWait,
IN u8 IsFromISR
)
{
RTL_MAILBOX *pMbox=NULL;
u32 wait_ticks;
#ifdef PLATFORM_FREERTOS
portBASE_TYPE ret;
#endif
pMbox = RtlMBoxIdToHdl(MboxID);
if (NULL == pMbox) {
MSG_MBOX_ERR("RtlMailboxPeek: Didn't find the MBox with ID=%d\n", MboxID);
return _FAIL;
}
#ifdef PLATFORM_FREERTOS
if (MBOX_WAIT_NONE == MSToWait) {
wait_ticks = 0;
}
else if (MBOX_WAIT_NO_TIMEOUT == MSToWait) {
wait_ticks = portMAX_DELAY;
}
else {
wait_ticks = ((MSToWait/portTICK_RATE_MS)>0)?(MSToWait/portTICK_RATE_MS):(1);
}
if (IsFromISR) {
// ret = xQueuePeekFromISR(pMbox->mbox_hdl, (void *)pMsg, ( portTickType ) wait_ticks);
// TODO: check why we have no "xQueuePeekFromISR"
MSG_MBOX_ERR("RtlMailboxPeek: Current version has no 'xQueuePeekFromISR'\n");
ret = pdFALSE;
}
else {
ret = xQueuePeek(pMbox->mbox_hdl, (void *)pMsg, ( portTickType ) wait_ticks);
}
if(ret != pdTRUE ) {
// receive message failed
MSG_MBOX_ERR("RtlMailboxReceive: Receive Msg Failed, MBoxID=%d\n", MboxID);
ret = _FAIL;
}
else {
ret = _SUCCESS;
}
return ret;
#endif
#ifdef PLATFORM_ECOS
// TODO: Get a message from the mailbox
#endif
}
/******************************************************************************
* Function: RtlMailboxMsgWaiting
* Desc: To get the number of message blocks are storing in a given mailbox.
* Para:
* MboxID: The identifier of the target mailbox.
* IsFromISR: Is this function is called from an ISR ?
* Return: The number of message blocks are storing in this mailbox.
******************************************************************************/
u32 RtlMailboxMsgWaiting(
IN u8 MboxID,
IN u8 IsFromISR
)
{
RTL_MAILBOX *pMbox=NULL;
u32 msg_num=0;
pMbox = RtlMBoxIdToHdl(MboxID);
if (NULL == pMbox) {
MSG_MBOX_ERR("RtlMailboxMsgWaiting: Didn't find the MBox with ID=%d\n", MboxID);
return 0;
}
#ifdef PLATFORM_FREERTOS
if (IsFromISR) {
msg_num = uxQueueMessagesWaitingFromISR(pMbox->mbox_hdl);
}
else {
msg_num = uxQueueMessagesWaiting(pMbox->mbox_hdl);
}
#endif
#ifdef PLATFORM_ECOS
// TODO: call eCos API to implement this function
#endif
return msg_num;
}

View file

@ -0,0 +1,836 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
*
******************************************************************************/
#define _OSDEP_API_C_
#include <osdep_api.h>
u8*
RtlMalloc(
IN u32 sz
)
{
u8 *pbuf=NULL;
#ifndef PLATFORM_FREERTOS
u32 v32=0;
#endif
#ifdef PLATFORM_FREERTOS
SaveAndCli( );
#else
SaveAndCli(v32);
#endif
pbuf = RtlKmalloc(sz, GFP_ATOMIC);
#ifdef PLATFORM_FREERTOS
RestoreFlags( );
#else
RestoreFlags(v32);
#endif
return pbuf;
}
u8*
RtlZmalloc(
IN u32 sz
)
{
#ifdef PLATFORM_FREERTOS
u8 *pbuf;
pbuf= RtlMalloc(sz);
if (pbuf != NULL) {
_memset(pbuf, 0, sz);
}
return pbuf;
#else
u8 *pbuf;
pbuf= RtlMalloc(sz);
if (pbuf != NULL) {
_memset(pbuf, 0, sz);
}
return pbuf;
#endif
}
VOID
RtlMfree(
IN u8 *pbuf,
IN u32 sz
)
{
RtlKfree(pbuf);
}
VOID*
RtlMalloc2d(
IN u32 h,
IN u32 w,
IN u32 size
)
{
u32 j;
VOID **a = (VOID **) RtlZmalloc( h*sizeof(VOID *) + h*w*size );
if(a == NULL)
{
DBG_ERROR_LOG("%s: alloc memory fail!\n", __FUNCTION__);
return NULL;
}
for( j=0; j<h; j++ )
a[j] = ((char *)(a+h)) + j*w*size;
return a;
}
VOID
RtlMfree2d(
IN VOID *pbuf,
IN u32 h,
IN u32 w,
IN u32 size
)
{
RtlMfree((u8 *)pbuf, h*sizeof(VOID*) + w*h*size);
}
VOID
RtlInitSema(
IN _Sema *sema,
IN u32 init_val
)
{
#ifdef PLATFORM_FREERTOS
*sema = xSemaphoreCreateCounting(MAX_SEMA_COUNT, init_val);
#endif
#if defined(PLATFORM_LINUX) || defined(PLATFORM_ECOS)
SemaInit(sema, init_val);
#endif
}
VOID
RtlFreeSema(
IN _Sema *sema
)
{
vSemaphoreDelete(*sema);
}
VOID
RtlUpSema(
IN _Sema *sema
)
{
#ifdef PLATFORM_FREERTOS
xSemaphoreGive(*sema);
#endif
#ifdef PLATFORM_ECOS
sema_post(sema);
#endif
}
VOID
RtlUpSemaFromISR(
IN _Sema *sema
)
{
#ifdef PLATFORM_FREERTOS
signed portBASE_TYPE xHigherPriorityTaskWoken=pdFALSE;
xSemaphoreGiveFromISR(*sema, &xHigherPriorityTaskWoken);
// portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
if (pdFALSE != xHigherPriorityTaskWoken)
{
taskYIELD();
}
#endif
#ifdef PLATFORM_ECOS
sema_post(sema);
#endif
}
u32
RtlDownSema(
IN _Sema *sema
)
{
#ifdef PLATFORM_FREERTOS
xSemaphoreTake(*sema, portMAX_DELAY);
return _SUCCESS;
#endif
#ifdef PLATFORM_ECOS
SemaWait(sema);
return _SUCCESS;
#endif
}
u32
RtlDownSemaWithTimeout(
IN _Sema *sema,
IN u32 ms
)
{
#ifdef PLATFORM_FREERTOS
u32 timeout = ms/portTICK_RATE_MS;
if (xSemaphoreTake(*sema, timeout) == pdTRUE) {
return _SUCCESS;
}
else {
return _FAIL;
}
#endif
#ifdef PLATFORM_ECOS
// TODO:
SemaWait(sema);
return _SUCCESS;
#endif
}
VOID
RtlMutexInit(
IN _Mutex *pmutex
)
{
#ifdef PLATFORM_FREERTOS
*pmutex = xSemaphoreCreateMutex();
#endif
#ifdef PLATFORM_ECOS
SemaInit(pmutex, 1);
#endif
}
VOID
RtlMutexFree(
IN _Mutex *pmutex
)
{
vSemaphoreDelete(*pmutex);
}
VOID
RtlSpinlockInit(
IN _Lock *plock
)
{
SpinLockInit(plock);
}
VOID
RtlSpinlockFree(
IN _Lock *plock
)
{
}
VOID
RtlSpinlock(
IN _Lock *plock
)
{
SpinLock(plock);
}
VOID
RtlSpinunlock(
IN _Lock *plock
)
{
SpinUnlock(plock);
}
VOID
RtlSpinlockEx(
IN _Lock *plock
)
{
}
VOID
RtlSpinunlockEx(
IN _Lock *plock
)
{
}
#if 0
VOID
RtlInitQueue(
IN _QUEUE *pqueue
)
{
RtlInitListhead(&(pqueue->Queue));
RtlSpinlockInit(&(pqueue->Lock));
}
u32
RtlQueueEmpty(
IN _QUEUE *pqueue
)
{
return (RtlIsListEmpty(&(pqueue->Queue)));
}
u32
RtlendOfQueueSearch(
IN _LIST *head,
IN _LIST *plist)
{
if (head == plist)
return _TRUE;
else
return _FALSE;
}
#endif
u32
RtlGetCurrentTime(VOID)
{
return JIFFIES;
}
VOID
RtlSleepSchedulable(
IN u32 ms
)
{
#ifdef PLATFORM_LINUX
u32 delta;
delta = (ms * HZ)/1000;//(ms)
if (delta == 0) {
delta = 1;// 1 ms
}
set_current_state(TASK_INTERRUPTIBLE);
if (schedule_timeout(delta) != 0) {
return ;
}
return;
#endif
#ifdef PLATFORM_FREEBSD
DELAY(ms*1000);
return ;
#endif
#ifdef PLATFORM_WINDOWS
NdisMSleep(ms*1000); //(us)*1000=(ms)
#endif
}
VOID
RtlMsleepOS(
IN u32 ms
)
{
#ifdef PLATFORM_FREERTOS
u32 Dealycount = ms/portTICK_RATE_MS;
if (Dealycount > 0) {
vTaskDelay(Dealycount);
}
else {
vTaskDelay(1);
}
#endif
}
VOID
RtlUsleepOS(
IN u32 us
)
{
#ifdef PLATFORM_FREERTOS
u32 Dealycount = us/portTICK_RATE_MS*1000;
if (Dealycount > 0) {
vTaskDelay(Dealycount);
}
else {
vTaskDelay(1);
}
#endif
}
VOID
RtlMdelayOS(
IN u32 ms
)
{
Mdelay((unsigned long)ms);
}
VOID
RtlUdelayOS(
IN u32 us
)
{
Udelay((unsigned long)us);
}
VOID
RtlYieldOS(VOID)
{
}
#if defined(__ICCARM__)
u64
RtlModular64(
IN u64 n,
IN u64 base
)
{
unsigned int __base = (base);
unsigned int __rem;
//(void)(((typeof((n)) *)0) == ((__uint64_t *)0));
if (((n) >> 32) == 0) {
__rem = (unsigned int)(n) % __base;
(n) = (unsigned int)(n) / __base;
} else
__rem = __Div64_32(&(n), __base);
return __rem;
}
#else
u64
RtlModular64(
IN u64 x,
IN u64 y
)
{
return DO_DIV(x, y);
}
#endif
/******************************************************************************
* Function: RtlTimerCallbckEntry
* Desc: This function is a timer callback wrapper. All OS timer callback
* will call this function and then call the real callback function inside
* this function.
*
* Para:
* pxTimer: The FreeRTOS timer handle which is expired and call this callback.
*
* Return: None
*
******************************************************************************/
#ifdef PLATFORM_FREERTOS
void
RtlTimerCallbckEntry (
IN xTimerHandle pxTimer
)
{
PRTL_TIMER pTimer;
if (NULL == pxTimer) {
MSG_TIMER_ERR("RtlTimerCallbckEntry: NULL Timer Handle Err!\n");
return;
}
pTimer = (PRTL_TIMER) pvTimerGetTimerID( pxTimer );
pTimer->CallBackFunc(pTimer->Context);
}
#endif // end of "#ifdef PLATFORM_FREERTOS"
/******************************************************************************
* Function: RtlTimerCreate
* Desc: To create a software timer.
*
* Para:
* pTimerName: A string for the timer name.
* TimerPeriodMS: The timer period, the unit is milli-second.
* CallbckFunc: The callback function of this timer.
* pContext: A pointer will be used as the parameter to call the timer
* callback function.
* isPeriodical: Is this timer periodical ? (Auto reload after expired)
* Return: The created timer handle, a pointer. It can be used to delete the
* timer. If timer createion failed, return NULL.
*
******************************************************************************/
PRTL_TIMER
RtlTimerCreate(
IN char *pTimerName,
IN u32 TimerPeriodMS,
IN RTL_TIMER_CALL_BACK CallbckFunc,
IN void *pContext,
IN u8 isPeriodical
)
{
PRTL_TIMER pTimer;
u32 timer_ticks;
int i;
pTimer = (PRTL_TIMER)RtlZmalloc(sizeof(RTL_TIMER));
if (NULL == pTimer) {
MSG_TIMER_ERR("RtlTimerCreate: Alloc Mem Err!\n");
return NULL;
}
if (portTICK_RATE_MS >= TimerPeriodMS) {
timer_ticks = 1; // at least 1 system tick
}
else {
timer_ticks = TimerPeriodMS/portTICK_RATE_MS;
}
#ifdef PLATFORM_FREERTOS
pTimer->TimerHandle = xTimerCreate (pTimer->TimerName, timer_ticks,
(portBASE_TYPE)isPeriodical, (void *) pTimer, RtlTimerCallbckEntry);
#endif
#ifdef PLATFORM_ECOS
// TODO: create a timer
#endif
#ifdef PLATFORM_FREERTOS // if any RTOS is used
if (pTimer->TimerHandle) {
pTimer->msPeriod = TimerPeriodMS;
pTimer->CallBackFunc = CallbckFunc;
pTimer->Context = pContext;
pTimer->isPeriodical = isPeriodical;
// copy the timer name
if (NULL != pTimerName) {
for(i = 0; i < sizeof(pTimer->TimerName); i++)
{
pTimer->TimerName[i] = pTimerName[i];
if(pTimerName[i] == '\0')
{
break;
}
}
}
else {
_strcpy(pTimer->TimerName, "None");
}
}
else
#endif
{
RtlMfree((u8 *)pTimer, sizeof(RTL_TIMER));
pTimer = NULL;
MSG_TIMER_ERR("RtlTimerCreate: OS Create Timer Failed!\n");
}
MSG_TIMER_INFO("RtlTimerCreate: SW Timer Created: Name=%s Period=%d isPeriodical=%d\n", \
pTimer->TimerName, pTimer->msPeriod, pTimer->isPeriodical);
return (pTimer);
}
/******************************************************************************
* Function: RtlTimerDelete
* Desc: To delete a created software timer.
*
* Para:
* pTimerHdl: The timer to be deleted
*
* Return: None
*
******************************************************************************/
VOID
RtlTimerDelete(
IN PRTL_TIMER pTimerHdl
)
{
#ifdef PLATFORM_FREERTOS
portBASE_TYPE ret;
#endif
MSG_TIMER_INFO("RtlTimerDelete: Name=%s\n", pTimerHdl->TimerName);
if (NULL == pTimerHdl) {
MSG_TIMER_ERR("RtlTimerDelete: NULL Timer Handle!\n");
}
#ifdef PLATFORM_FREERTOS
/* try to delete the soft timer and wait max RTL_TIMER_API_MAX_BLOCK_TICKS
to send the delete command to the timer command queue */
ret = xTimerDelete(pTimerHdl->TimerHandle, RTL_TIMER_API_MAX_BLOCK_TICKS);
if (pdPASS != ret) {
MSG_TIMER_ERR("RtlTimerDelete: Delete OS Timer Failed!\n");
}
#endif
#ifdef PLATFORM_ECOS
// TODO: call OS delete timer
#endif
RtlMfree((u8 *)pTimerHdl, sizeof(RTL_TIMER));
}
/******************************************************************************
* Function: RtlTimerStart
* Desc: To start a created timer..
*
* Para:
* pTimerHdl: The timer to be started.
* isFromISR: The flag to indicate that is this function is called from an ISR.
*
* Return: _SUCCESS or _FAIL
*
******************************************************************************/
u8
RtlTimerStart(
IN PRTL_TIMER pTimerHdl,
IN u8 isFromISR
)
{
#ifdef PLATFORM_FREERTOS
u8 ret=_FAIL;
portBASE_TYPE HigherPriorityTaskWoken=pdFALSE;
if (isFromISR) {
if (pdPASS == xTimerStartFromISR(pTimerHdl->TimerHandle,&HigherPriorityTaskWoken))
{
// start OS timer successful
if (pdFALSE != HigherPriorityTaskWoken) {
taskYIELD();
}
ret = _SUCCESS;
}
else {
MSG_TIMER_ERR("RtlTimerStart: Start Timer(%s) from ISR failed\n", pTimerHdl->TimerName);
}
}
else {
if (pdPASS == xTimerStart(pTimerHdl->TimerHandle, RTL_TIMER_API_MAX_BLOCK_TICKS)) {
ret = _SUCCESS;
}
else {
MSG_TIMER_ERR("RtlTimerStart: Start Timer(%s) failed\n", pTimerHdl->TimerName);
}
}
MSG_TIMER_INFO("RtlTimerStart: SW Timer %s Started\n", pTimerHdl->TimerName);
return ret;
#endif
}
/******************************************************************************
* Function: RtlTimerStop
* Desc: To stop a running timer..
*
* Para:
* pTimerHdl: The timer to be stoped.
* isFromISR: The flag to indicate that is this function is called from an ISR.
*
* Return: _SUCCESS or _FAIL
*
******************************************************************************/
u8
RtlTimerStop(
IN PRTL_TIMER pTimerHdl,
IN u8 isFromISR
)
{
#ifdef PLATFORM_FREERTOS
u8 ret=_FAIL;
portBASE_TYPE HigherPriorityTaskWoken=pdFALSE;
if (isFromISR) {
if (pdPASS == xTimerStopFromISR(pTimerHdl->TimerHandle,&HigherPriorityTaskWoken))
{
// start OS timer successful
if (pdFALSE != HigherPriorityTaskWoken) {
taskYIELD();
}
ret = _SUCCESS;
}
}
else {
if (pdPASS == xTimerStop(pTimerHdl->TimerHandle, RTL_TIMER_API_MAX_BLOCK_TICKS)) {
ret = _SUCCESS;
}
}
if (_FAIL == ret) {
MSG_TIMER_ERR("RtlTimerStop: Stop Timer(%s) Failed, IsFromISR=%d\n", pTimerHdl->TimerName, isFromISR);
}
MSG_TIMER_INFO("RtlTimerStop: SW Timer %s Stoped\n", pTimerHdl->TimerName);
return ret;
#endif
}
/******************************************************************************
* Function: RtlTimerReset
* Desc: To reset a timer. A reset will get a re-start and reset
* the timer ticks counting. A running timer expired time is relative
* to the time when Reset function be called. Please ensure the timer
* is in active state (Started). A stopped timer also will be started
* when this function is called.
*
* Para:
* pTimerHdl: The timer to be reset.
* isFromISR: The flag to indicate that is this function is called from an ISR.
*
* Return: _SUCCESS or _FAIL
*
******************************************************************************/
u8
RtlTimerReset(
IN PRTL_TIMER pTimerHdl,
IN u8 isFromISR
)
{
#ifdef PLATFORM_FREERTOS
u8 ret=_FAIL;
portBASE_TYPE HigherPriorityTaskWoken=pdFALSE;
if (isFromISR) {
if (pdPASS == xTimerResetFromISR(pTimerHdl->TimerHandle,&HigherPriorityTaskWoken))
{
// start OS timer successful
if (pdFALSE != HigherPriorityTaskWoken) {
taskYIELD();
}
ret = _SUCCESS;
}
}
else {
if (pdPASS == xTimerReset(pTimerHdl->TimerHandle, RTL_TIMER_API_MAX_BLOCK_TICKS)) {
ret = _SUCCESS;
}
}
if (_FAIL == ret) {
MSG_TIMER_ERR("RtlTimerReset: Reset Timer(%s) Failed, IsFromISR=%d\n", pTimerHdl->TimerName, isFromISR);
}
MSG_TIMER_INFO("RtlTimerReset: SW Timer %s Reset\n", pTimerHdl->TimerName);
return ret;
#endif
}
/******************************************************************************
* Function: RtlTimerChangePeriod
* Desc: To change the period of a timer that was created previously.
*
* Para:
* pTimerHdl: The timer handle to be changed the priod.
* NewPeriodMS: The new timer period, in milli-second.
* isFromISR: The flag to indicate that is this function is called from an ISR.
*
* Return: _SUCCESS or _FAIL
*
******************************************************************************/
u8
RtlTimerChangePeriod(
IN PRTL_TIMER pTimerHdl,
IN u32 NewPeriodMS,
IN u8 isFromISR
)
{
#ifdef PLATFORM_FREERTOS
u32 timer_ticks;
u8 ret=_FAIL;
portBASE_TYPE HigherPriorityTaskWoken=pdFALSE;
if (portTICK_RATE_MS >= NewPeriodMS) {
timer_ticks = 1; // at least 1 system tick
}
else {
timer_ticks = NewPeriodMS/portTICK_RATE_MS;
}
if (isFromISR) {
if (pdPASS == xTimerChangePeriodFromISR(pTimerHdl->TimerHandle, timer_ticks, &HigherPriorityTaskWoken))
{
// start OS timer successful
if (pdFALSE != HigherPriorityTaskWoken) {
taskYIELD();
}
ret = _SUCCESS;
}
}
else {
if (pdPASS == xTimerChangePeriod(pTimerHdl->TimerHandle, timer_ticks, RTL_TIMER_API_MAX_BLOCK_TICKS)) {
ret = _SUCCESS;
}
}
if (_FAIL == ret) {
MSG_TIMER_ERR("RtlTimerChangePeriod: Change Timer(%s) Period Failed, IsFromISR=%d\n", pTimerHdl->TimerName, isFromISR);
}
else {
pTimerHdl->msPeriod = NewPeriodMS;
MSG_TIMER_INFO("RtlTimerChangePeriod: SW Timer %s change period to %d\n", pTimerHdl->TimerName, pTimerHdl->msPeriod);
}
return ret;
#endif
}