GCC SDK RTL8710 basic version (including the window platform cygwin installation and Ubuntu platform Linux Installation routines),

including cross compilation of the installation, compile, link, run, debug, and so on.
SDK implementation of the function:
1, WiFi connection settings (including AP mode and STA mode).
2, peripheral resource control (including GPIO, SPI, UART, IIC, etc.).
3, the user uses the sample method.
This commit is contained in:
RtlduinoMan 2016-09-08 18:11:26 +08:00
parent 36b1b0dcd9
commit 905d81784e
2094 changed files with 779991 additions and 0 deletions

View file

@ -0,0 +1,64 @@
/*
* Routines to access hardware
*
* Copyright (c) 2013 Realtek Semiconductor Corp.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*/
#include "osdep_service.h"
#include "device_lock.h"
//------------------------------------------------------
#define DEVICE_MUTEX_IS_INIT(device) (mutex_init & (1<<device))
#define DEVICE_MUTEX_SET_INIT(device) (mutex_init |= (1<<device))
#define DEVICE_MUTEX_CLR_INIT(device) (mutex_init &= (~(1<<device)))
static u32 mutex_init = 0;
static _mutex device_mutex[RT_DEV_LOCK_MAX];
//======================================================
static void device_mutex_init(RT_DEV_LOCK_E device)
{
if(!DEVICE_MUTEX_IS_INIT(device)){
_lock lock;
_irqL irqL;
rtw_enter_critical(&lock, &irqL);
if(!DEVICE_MUTEX_IS_INIT(device)){
rtw_mutex_init(&device_mutex[device]);
DEVICE_MUTEX_SET_INIT(device);
}
rtw_exit_critical(&lock, &irqL);
}
}
//======================================================
static void device_mutex_free(RT_DEV_LOCK_E device)
{
if(DEVICE_MUTEX_IS_INIT(device)){
_lock lock;
_irqL irqL;
rtw_enter_critical(&lock, &irqL);
if(!DEVICE_MUTEX_IS_INIT(device)){
rtw_mutex_free(&device_mutex[device]);
DEVICE_MUTEX_CLR_INIT(device);
}
rtw_exit_critical(&lock, &irqL);
}
}
//======================================================
void device_mutex_lock(RT_DEV_LOCK_E device)
{
device_mutex_init(device);
while(rtw_mutex_get_timeout(&device_mutex[device], 10000)<0)
printf("device lock timeout: %d\n", device);
}
//======================================================
void device_mutex_unlock(RT_DEV_LOCK_E device)
{
device_mutex_init(device);
rtw_mutex_put(&device_mutex[device]);
}

View file

@ -0,0 +1,23 @@
/*
* Routines to access hardware
*
* Copyright (c) 2013 Realtek Semiconductor Corp.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*/
#ifndef _DEVICE_LOCK_H_
#define _DEVICE_LOCK_H_
typedef enum _RT_DEV_LOCK_E
{
RT_DEV_LOCK_EFUSE = 0,
RT_DEV_LOCK_FLASH = 1,
RT_DEV_LOCK_MAX = 2
}RT_DEV_LOCK_E;
void device_mutex_lock(RT_DEV_LOCK_E device);
void device_mutex_unlock(RT_DEV_LOCK_E device);
#endif //_DEVICE_LOCK_H_

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,343 @@
/******************************************************************************
*
* 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
#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))
static __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))
static __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.
*/
static __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.
*/
static __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
}
static __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
}
static __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
static inline VOID
RTL_ATOMIC_SET(
IN RTL_ATOMIC_T *v,
IN u32 i
)
{
AtomicSet(i,v);
}
static inline uint32_t
RTL_ATOMIC_READ(
IN RTL_ATOMIC_T *v
)
{
return AtomicRead(v);
}
static inline VOID
RTL_ATOMIC_ADD(
IN RTL_ATOMIC_T *v,
IN u32 i
)
{
AtomicAdd(i,v);
}
static inline VOID
RTL_ATOMIC_SUB(
IN RTL_ATOMIC_T *v,
IN u32 i
)
{
AtomicSub(i,v);
}
static inline VOID
RTL_ATOMIC_INC(
IN RTL_ATOMIC_T *v
)
{
AtomicInc(v);
}
static inline VOID
RTL_ATOMIC_DEC(
IN RTL_ATOMIC_T *v
)
{
AtomicDec(v);
}
static inline u32
RTL_ATOMIC_ADD_RETURN(
IN RTL_ATOMIC_T *v,
IN u32 i
)
{
return AtomicAddReturn(i,v);
}
static inline u32
RTL_ATOMIC_SUB_RETURN(
IN RTL_ATOMIC_T *v,
IN u32 i
)
{
return AtomicSubReturn(i,v);
}
static inline u32
RTL_ATOMIC_INC_RETURN(
IN RTL_ATOMIC_T *v
)
{
return AtomicIncReturn(v);
}
static 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,582 @@
/******************************************************************************
*
* 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_SERVICE_H_
#define __OSDEP_SERVICE_H_
/* OS dep feature enable */
#include <autoconf.h>
#define CONFIG_LITTLE_ENDIAN
#if defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B)
#define CONFIG_PLATFORM_AMEBA_X
#endif
#if defined(CONFIG_PLATFORM_8195A)
#define CONFIG_USE_TCM_HEAP 1 /* USE TCM HEAP */
#define USE_MUTEX_FOR_SPINLOCK 1
#endif
#if defined(CONFIG_PLATFORM_AMEBA_X)
#define CONFIG_MEM_MONITOR MEM_MONITOR_SIMPLE
#else
#define CONFIG_MEM_MONITOR MEM_MONITOR_LEAK
#endif
/* Define compilor specific symbol */
//
// inline function
//
#if defined ( __ICCARM__ )
#define __inline__ inline
#define __inline inline
#define __inline_definition //In dialect C99, inline means that a function's definition is provided
//only for inlining, and that there is another definition
//(without inline) somewhere else in the program.
//That means that this program is incomplete, because if
//add isn't inlined (for example, when compiling without optimization),
//then main will have an unresolved reference to that other definition.
// Do not inline function is the function body is defined .c file and this
// function will be called somewhere else, otherwise there is compile error
#elif defined ( __CC_ARM )
#define __inline__ __inline //__linine__ is not supported in keil compilor, use __inline instead
#define inline __inline
#define __inline_definition // for dialect C99
#elif defined ( __GNUC__ )
#define __inline__ inline
#define __inline inline
#define __inline_definition inline
#endif
#include <stdio.h>
#if defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B)
#include "platform_autoconf.h"
#else
#ifndef SUCCESS
#define SUCCESS 0
#endif
#ifndef FAIL
#define FAIL (-1)
#endif
#ifndef _SUCCESS
#define _SUCCESS 1
#endif
#ifndef _FAIL
#define _FAIL 0
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE (!FALSE)
#endif
#define _TRUE TRUE
#define _FALSE FALSE
#endif
#if defined( PLATFORM_FREERTOS)
#include "freertos_service.h"
#elif defined( PLATFORM_ECOS)
#include "ecos/ecos_service.h"
#endif
#define RTW_MAX_DELAY 0xFFFFFFFF
#define RTW_WAIT_FOREVER 0xFFFFFFFF
/* Definitions returned by xTaskGetSchedulerState(). */
#define OS_SCHEDULER_NOT_STARTED 0
#define OS_SCHEDULER_RUNNING 1
#define OS_SCHEDULER_SUSPENDED 2
struct timer_list {
_timerHandle timer_hdl;
unsigned long data;
void (*function)(void *);
};
typedef thread_return (*thread_func_t)(thread_context context);
typedef void (*TIMER_FUN)(void *context);
typedef int (*event_handler_t)(char *buf, int buf_len, int flags, void *user_data);
#define CONFIG_THREAD_COMM_SEMA
struct task_struct {
const char *task_name;
_thread_hdl_ task; /* I: workqueue thread */
#ifdef CONFIG_THREAD_COMM_SIGNAL
const char *name; /* I: workqueue thread name */
u32 queue_num; /* total signal num */
u32 cur_queue_num; /* cur signal num should < queue_num */
#elif defined(CONFIG_THREAD_COMM_SEMA)
_sema wakeup_sema;
_sema terminate_sema;
// _queue work_queue; //TODO
#endif
u32 blocked;
u32 callback_running;
};
typedef struct {
_xqueue event_queue;
struct task_struct thread;
}rtw_worker_thread_t;
typedef struct
{
event_handler_t function;
char *buf;
int buf_len;
int flags;
void *user_data;
} rtw_event_message_t;
struct worker_timer_entry {
struct list_head list;
_timerHandle timer_hdl;
rtw_event_message_t message;
rtw_worker_thread_t *worker_thread;
u32 timeout;
};
#ifdef CONFIG_THREAD_COMM_SIGNAL
struct work_struct;
typedef void (*work_func_t)(void *context);
struct work_struct {
_list list;
u32 data;
work_func_t func;
void *context;
struct task_struct *used_wq;
};
struct delayed_work {
struct work_struct work;
struct timer_list timer;
};
#endif
#ifdef CONFIG_MEM_MONITOR
//----- ------------------------------------------------------------------
// Memory Monitor
//----- ------------------------------------------------------------------
#define MEM_MONITOR_SIMPLE 0x1
#define MEM_MONITOR_LEAK 0x2
#define MEM_MONITOR_FLAG_WIFI_DRV 0x1
#define MEM_MONITOR_FLAG_WPAS 0x2
#if CONFIG_MEM_MONITOR & MEM_MONITOR_LEAK
struct mem_entry {
struct list_head list;
int size;
void *ptr;
};
#endif
void init_mem_monitor(_list *pmem_table, int *used_num);
void deinit_mem_monitor(_list *pmem_table, int *used_num);
void add_mem_usage(_list *pmem_table, void *ptr, int size, int *used_num, int flag);
void del_mem_usage(_list *pmem_table, void *ptr, int *used_num, int flag);
int get_mem_usage(_list *pmem_table);
#endif
/*********************************** OSDEP API *****************************************/
u8* _rtw_vmalloc(u32 sz);
u8* _rtw_zvmalloc(u32 sz);
void _rtw_vmfree(u8 *pbuf, u32 sz);
u8* _rtw_zmalloc(u32 sz);
u8* _rtw_malloc(u32 sz);
void _rtw_mfree(u8 *pbuf, u32 sz);
#ifdef CONFIG_MEM_MONITOR
u8* rtw_vmalloc(u32 sz);
u8* rtw_zvmalloc(u32 sz);
void rtw_vmfree(u8 *pbuf, u32 sz);
u8* rtw_zmalloc(u32 sz);
u8* rtw_malloc(u32 sz);
void rtw_mfree(u8 *pbuf, u32 sz);
#else
#define rtw_vmalloc _rtw_vmalloc
#define rtw_zvmalloc _rtw_zvmalloc
#define rtw_vmfree _rtw_vmfree
#define rtw_zmalloc _rtw_zmalloc
#define rtw_malloc _rtw_malloc
#define rtw_mfree _rtw_mfree
#endif
#define rtw_free(buf) rtw_mfree((u8 *)buf, 0)
void* rtw_malloc2d(int h, int w, int size);
void rtw_mfree2d(void *pbuf, int h, int w, int size);
void rtw_memcpy(void* dst, void* src, u32 sz);
int rtw_memcmp(void *dst, void *src, u32 sz);
void rtw_memset(void *pbuf, int c, u32 sz);
void rtw_init_listhead(_list *list);
u32 rtw_is_list_empty(_list *phead);
void rtw_list_insert_head(_list *plist, _list *phead);
void rtw_list_insert_tail(_list *plist, _list *phead);
void rtw_list_delete(_list *plist);
void rtw_init_sema(_sema *sema, int init_val);
void rtw_free_sema(_sema *sema);
void rtw_up_sema(_sema *sema);
void rtw_up_sema_from_isr(_sema *sema);
u32 rtw_down_sema(_sema *sema);
u32 rtw_down_timeout_sema(_sema *sema, u32 timeout);
void rtw_mutex_init(_mutex *pmutex);
void rtw_mutex_free(_mutex *pmutex);
void rtw_mutex_put(_mutex *pmutex);
void rtw_mutex_get(_mutex *pmutex);
int rtw_mutex_get_timeout(_mutex *pmutex, u32 timeout_ms);
void rtw_enter_critical(_lock *plock, _irqL *pirqL);
void rtw_exit_critical(_lock *plock, _irqL *pirqL);
void rtw_enter_critical_from_isr(_lock *plock, _irqL *pirqL);
void rtw_exit_critical_from_isr(_lock *plock, _irqL *pirqL);
void rtw_enter_critical_bh(_lock *plock, _irqL *pirqL);
void rtw_exit_critical_bh(_lock *plock, _irqL *pirqL);
int rtw_enter_critical_mutex(_mutex *pmutex, _irqL *pirqL);
void rtw_exit_critical_mutex(_mutex *pmutex, _irqL *pirqL);
void rtw_spinlock_init(_lock *plock);
void rtw_spinlock_free(_lock *plock);
void rtw_spinlock_init(_lock *plock);
void rtw_spinlock_free(_lock *plock);
void rtw_spin_lock(_lock *plock);
void rtw_spin_unlock(_lock *plock);
void rtw_spinlock_irqsave(_lock *plock, _irqL *irqL);
void rtw_spinunlock_irqsave(_lock *plock, _irqL *irqL);
int rtw_init_xqueue( _xqueue* queue, const char* name, u32 message_size, u32 number_of_messages );
int rtw_push_to_xqueue( _xqueue* queue, void* message, u32 timeout_ms );
int rtw_pop_from_xqueue( _xqueue* queue, void* message, u32 timeout_ms );
int rtw_deinit_xqueue( _xqueue* queue );
void rtw_init_queue(_queue *pqueue);
void rtw_deinit_queue(_queue *pqueue);
u32 rtw_is_queue_empty(_queue *pqueue);
u32 rtw_queue_empty(_queue *pqueue);
u32 rtw_end_of_queue_search(_list *queue, _list *pelement);
_list* rtw_get_queue_head(_queue *queue);
u32 rtw_get_current_time(void);
u32 rtw_systime_to_ms(u32 systime);
u32 rtw_systime_to_sec(u32 systime);
u32 rtw_ms_to_systime(u32 ms);
u32 rtw_sec_to_systime(u32 sec);
s32 rtw_get_passing_time_ms(u32 start);
s32 rtw_get_time_interval_ms(u32 start, u32 end);
void rtw_msleep_os(int ms);
void rtw_usleep_os(int us);
u32 rtw_atoi(u8* s);
void rtw_mdelay_os(int ms);
void rtw_udelay_os(int us);
void rtw_yield_os(void);
//Atomic integer operations
void ATOMIC_SET(ATOMIC_T *v, int i);
int ATOMIC_READ(ATOMIC_T *v);
void ATOMIC_ADD(ATOMIC_T *v, int i);
void ATOMIC_SUB(ATOMIC_T *v, int i);
void ATOMIC_INC(ATOMIC_T *v);
void ATOMIC_DEC(ATOMIC_T *v);
int ATOMIC_ADD_RETURN(ATOMIC_T *v, int i);
int ATOMIC_SUB_RETURN(ATOMIC_T *v, int i);
int ATOMIC_INC_RETURN(ATOMIC_T *v);
int ATOMIC_DEC_RETURN(ATOMIC_T *v);
int ATOMIC_DEC_AND_TEST(ATOMIC_T *v);
u64 rtw_modular64(u64 x, u64 y);
int rtw_get_random_bytes(void* dst, u32 size);
u32 rtw_getFreeHeapSize(void);
void flush_signals_thread(void);
void rtw_acquire_wakelock(void);
void rtw_release_wakelock(void);
/*********************************** Thread related *****************************************/
int rtw_create_task(struct task_struct *task, const char *name, u32 stack_size, u32 priority, thread_func_t func, void *thctx);
void rtw_delete_task(struct task_struct * task);
void rtw_wakeup_task(struct task_struct *task);
int rtw_create_worker_thread( rtw_worker_thread_t* worker_thread, u8 priority, u32 stack_size, u32 event_queue_size );
int rtw_delete_worker_thread( rtw_worker_thread_t* worker_thread );
#if 0 //TODO
void rtw_init_delayed_work(struct delayed_work *dwork, work_func_t func, const char *name);
void rtw_deinit_delayed_work(struct delayed_work *dwork);
int rtw_queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *dwork, u32 delay, void* context);
BOOLEAN rtw_cancel_delayed_work(struct delayed_work *dwork);
#endif
void rtw_thread_enter(char *name);
void rtw_thread_exit(void);
u8 rtw_get_scheduler_state(void);
#ifdef PLATFORM_LINUX
#define rtw_warn_on(condition) WARN_ON(condition)
#else
#define rtw_warn_on(condition) do {} while (0)
#endif
/*********************************** Timer related *****************************************/
_timerHandle rtw_timerCreate( const signed char *pcTimerName,
osdepTickType xTimerPeriodInTicks,
u32 uxAutoReload,
void * pvTimerID,
TIMER_FUN pxCallbackFunction );
u32 rtw_timerDelete( _timerHandle xTimer,
osdepTickType xBlockTime );
u32 rtw_timerIsTimerActive( _timerHandle xTimer );
u32 rtw_timerStop( _timerHandle xTimer,
osdepTickType xBlockTime );
u32 rtw_timerChangePeriod( _timerHandle xTimer,
osdepTickType xNewPeriod,
osdepTickType xBlockTime );
/*********************************** OSDEP API end *****************************************/
#define LIST_CONTAINOR(ptr, type, member) \
((type *)((char *)(ptr)-(SIZE_T)((char *)&((type *)ptr)->member - (char *)ptr)))
#define time_after(a,b) ((long)(b) - (long)(a) < 0)
#define time_before(a,b) time_after(b,a)
#define time_after_eq(a,b) ((long)(a) - (long)(b) >= 0)
#define time_before_eq(a,b) time_after_eq(b,a)
#define _RND(sz, r) ((((sz)+((r)-1))/(r))*(r))
#define RND4(x) (((x >> 2) + (((x & 3) == 0) ? 0: 1)) << 2)
__inline static u32 _RND4(u32 sz)
{
u32 val;
val = ((sz >> 2) + ((sz & 3) ? 1: 0)) << 2;
return val;
}
__inline static u32 _RND8(u32 sz)
{
u32 val;
val = ((sz >> 3) + ((sz & 7) ? 1: 0)) << 3;
return val;
}
__inline static u32 _RND128(u32 sz)
{
u32 val;
val = ((sz >> 7) + ((sz & 127) ? 1: 0)) << 7;
return val;
}
__inline static u32 _RND256(u32 sz)
{
u32 val;
val = ((sz >> 8) + ((sz & 255) ? 1: 0)) << 8;
return val;
}
__inline static u32 _RND512(u32 sz)
{
u32 val;
val = ((sz >> 9) + ((sz & 511) ? 1: 0)) << 9;
return val;
}
__inline static u32 bitshift(u32 bitmask)
{
u32 i;
for (i = 0; i <= 31; i++)
if (((bitmask>>i) & 0x1) == 1) break;
return i;
}
/* Macros for handling unaligned memory accesses */
#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]))
struct osdep_service_ops {
u8* (*rtw_vmalloc)(u32 sz);
u8* (*rtw_zvmalloc)(u32 sz);
void (*rtw_vmfree)(u8 *pbuf, u32 sz);
u8* (*rtw_malloc)(u32 sz);
u8* (*rtw_zmalloc)(u32 sz);
void (*rtw_mfree)(u8 *pbuf, u32 sz);
void (*rtw_memcpy)(void* dst, void* src, u32 sz);
int (*rtw_memcmp)(void *dst, void *src, u32 sz);
void (*rtw_memset)(void *pbuf, int c, u32 sz);
void (*rtw_init_sema)(_sema *sema, int init_val);
void (*rtw_free_sema)(_sema *sema);
void (*rtw_up_sema)(_sema *sema);
void (*rtw_up_sema_from_isr)(_sema *sema);
u32 (*rtw_down_timeout_sema)(_sema *sema, u32 timeout);
void (*rtw_mutex_init)(_mutex *pmutex);
void (*rtw_mutex_free)(_mutex *pmutex);
void (*rtw_mutex_get)(_mutex *pmutex);
int (*rtw_mutex_get_timeout)(_mutex *pmutex, u32 timeout_ms);
void (*rtw_mutex_put)(_mutex *pmutex);
void (*rtw_enter_critical)(_lock *plock, _irqL *pirqL);
void (*rtw_exit_critical)(_lock *plock, _irqL *pirqL);
void (*rtw_enter_critical_from_isr)(_lock *plock, _irqL *pirqL);
void (*rtw_exit_critical_from_isr)(_lock *plock, _irqL *pirqL);
void (*rtw_enter_critical_bh)(_lock *plock, _irqL *pirqL);
void (*rtw_exit_critical_bh)(_lock *plock, _irqL *pirqL);
int (*rtw_enter_critical_mutex)(_mutex *pmutex, _irqL *pirqL);
void (*rtw_exit_critical_mutex)(_mutex *pmutex, _irqL *pirqL);
void (*rtw_spinlock_init)(_lock *plock);
void (*rtw_spinlock_free)(_lock *plock);
void (*rtw_spin_lock)(_lock *plock);
void (*rtw_spin_unlock)(_lock *plock);
void (*rtw_spinlock_irqsave)(_lock *plock, _irqL *irqL);
void (*rtw_spinunlock_irqsave)(_lock *plock, _irqL *irqL);
int (*rtw_init_xqueue)( _xqueue* queue, const char* name, u32 message_size, u32 number_of_messages );
int (*rtw_push_to_xqueue)( _xqueue* queue, void* message, u32 timeout_ms );
int (*rtw_pop_from_xqueue)( _xqueue* queue, void* message, u32 timeout_ms );
int (*rtw_deinit_xqueue)( _xqueue* queue );
u32 (*rtw_get_current_time)(void);
u32 (*rtw_systime_to_ms)(u32 systime);
u32 (*rtw_systime_to_sec)(u32 systime);
u32 (*rtw_ms_to_systime)(u32 ms);
u32 (*rtw_sec_to_systime)(u32 sec);
void (*rtw_msleep_os)(int ms);
void (*rtw_usleep_os)(int us);
void (*rtw_mdelay_os)(int ms);
void (*rtw_udelay_os)(int us);
void (*rtw_yield_os)(void);
void (*ATOMIC_SET)(ATOMIC_T *v, int i);
int (*ATOMIC_READ)(ATOMIC_T *v);
void (*ATOMIC_ADD)(ATOMIC_T *v, int i);
void (*ATOMIC_SUB)(ATOMIC_T *v, int i);
void (*ATOMIC_INC)(ATOMIC_T *v);
void (*ATOMIC_DEC)(ATOMIC_T *v);
int (*ATOMIC_ADD_RETURN)(ATOMIC_T *v, int i);
int (*ATOMIC_SUB_RETURN)(ATOMIC_T *v, int i);
int (*ATOMIC_INC_RETURN)(ATOMIC_T *v);
int (*ATOMIC_DEC_RETURN)(ATOMIC_T *v);
u64 (*rtw_modular64)(u64 x, u64 y);
int (*rtw_get_random_bytes)(void* dst, u32 size);
u32 (*rtw_getFreeHeapSize)(void);
int (*rtw_create_task)(struct task_struct *task, const char *name, u32 stack_size, u32 priority, thread_func_t func, void *thctx);
void (*rtw_delete_task)(struct task_struct *task);
void (*rtw_wakeup_task)(struct task_struct *task);
#if 0 //TODO
void (*rtw_init_delayed_work)(struct delayed_work *dwork, work_func_t func, const char *name);
void (*rtw_deinit_delayed_work)(struct delayed_work *dwork);
int (*rtw_queue_delayed_work)(struct workqueue_struct *wq, struct delayed_work *dwork, unsigned long delay, void* context);
BOOLEAN (*rtw_cancel_delayed_work)(struct delayed_work *dwork);
#endif
void (*rtw_thread_enter)(char *name);
void (*rtw_thread_exit)(void);
_timerHandle (*rtw_timerCreate)( const signed char *pcTimerName,
osdepTickType xTimerPeriodInTicks,
u32 uxAutoReload,
void * pvTimerID,
TIMER_FUN pxCallbackFunction );
u32 (*rtw_timerDelete)( _timerHandle xTimer,
osdepTickType xBlockTime );
u32 (*rtw_timerIsTimerActive)( _timerHandle xTimer );
u32 (*rtw_timerStop)( _timerHandle xTimer,
osdepTickType xBlockTime );
u32 (*rtw_timerChangePeriod)( _timerHandle xTimer,
osdepTickType xNewPeriod,
osdepTickType xBlockTime );
void (*rtw_acquire_wakelock)(void);
void (*rtw_release_wakelock)(void);
u8 (*rtw_get_scheduler_state)(void);
};
/*********************************** OSDEP API end *****************************************/
#endif //#ifndef __OSDEP_SERVICE_H_

View file

@ -0,0 +1,66 @@
#ifndef STRUCT_HEAP_H
#define STRUCT_HEAP_H
//#include <stdio.h>
#include <stdint.h>
#include <osdep_service.h>
/* NOTE: struct size must be a 2's power! */
typedef struct _MemChunk
{
struct _MemChunk *next;
int size;
} MemChunk;
typedef MemChunk heap_buf_t;
/// A heap
typedef struct Heap
{
struct _MemChunk *FreeList; ///< Head of the free list
} Heap;
/**
* Utility macro to allocate a heap of size \a size.
*
* \param name Variable name for the heap.
* \param size Heap size in bytes.
*/
#define HEAP_DEFINE_BUF(name, size) \
heap_buf_t name[((size) + sizeof(heap_buf_t) - 1) / sizeof(heap_buf_t)]
/// Initialize \a heap within the buffer pointed by \a memory which is of \a size bytes
void tcm_heap_init(void);
/// Allocate a chunk of memory of \a size bytes from the heap
void *tcm_heap_allocmem(int size);
/// Free a chunk of memory of \a size bytes from the heap
void tcm_heap_freemem(void *mem, int size);
int tcm_heap_freeSpace(void);
#define HNEW(heap, type) \
(type*)tcm_heap_allocmem(heap, sizeof(type))
#define HNEWVEC(heap, type, nelem) \
(type*)tcm_heap_allocmem(heap, sizeof(type) * (nelem))
#define HDELETE(heap, type, mem) \
tcm_heap_freemem(heap, mem, sizeof(type))
#define HDELETEVEC(heap, type, nelem, mem) \
tcm_heap_freemem(heap, mem, sizeof(type) * (nelem))
/**
* \name Compatibility interface with C standard library
* \{
*/
void *tcm_heap_malloc(int size);
void *tcm_heap_calloc(int size);
void tcm_heap_free(void * mem);
/** \} */
#endif /* STRUCT_HEAP_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;
/******************************************************************************
* 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,835 @@
/******************************************************************************
*
* 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>
extern _LONG_CALL_ char *_strcpy(char *dest, const char *src);
extern _LONG_CALL_ VOID *_memset(void *dst0, int Val,SIZE_T length);
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 ((const char*)(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((char*)(pTimer->TimerName), "None");
}
MSG_TIMER_INFO("RtlTimerCreate: SW Timer Created: Name=%s Period=%d isPeriodical=%d\n", \
pTimer->TimerName, pTimer->msPeriod, pTimer->isPeriodical);
}
else
#endif
{
RtlMfree((u8 *)pTimer, sizeof(RTL_TIMER));
pTimer = NULL;
MSG_TIMER_ERR("RtlTimerCreate: OS Create Timer Failed!\n");
}
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
if (NULL == pTimerHdl) {
MSG_TIMER_ERR("RtlTimerDelete: NULL Timer Handle!\n");
return;
}
MSG_TIMER_INFO("RtlTimerDelete: Name=%s\n", pTimerHdl->TimerName);
#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
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,352 @@
//#include <autoconf.h>
#include "tcm_heap.h"
#include <string.h> // memset()
#include <osdep_service.h>
//#define _DEBUG
#if CONFIG_USE_TCM_HEAP
#define FREE_FILL_CODE 0xDEAD
#define ALLOC_FILL_CODE 0xBEEF
#define ROUND_UP2(x, pad) (((x) + ((pad) - 1)) & ~((pad) - 1))
#define TCM_HEAP_SIZE (40*1024)
static struct Heap g_tcm_heap;
#if defined (__ICCARM__)
#pragma location=".tcm.heap"
#else
__attribute__((section(".tcm.heap")))
#endif
HEAP_DEFINE_BUF(tcm_heap, TCM_HEAP_SIZE);
//unsigned char tcm_heap[TCM_HEAP_SIZE];
static int g_heap_inited=0;
static _lock tcm_lock;
extern void vPortSetExtFree( void (*free)( void *p ), uint32_t upper, uint32_t lower );
void tcm_heap_init(void)
{
//#ifdef _DEBUG
//memset(memory, FREE_FILL_CODE, size);
//#endif
//ASSERT2(((int)memory % alignof(heap_buf_t)) == 0,
//"memory buffer is unaligned, please use the HEAP_DEFINE_BUF() macro to declare heap buffers!\n");
/* Initialize heap with a single big chunk */
g_tcm_heap.FreeList = (MemChunk *)&tcm_heap;
g_tcm_heap.FreeList->next = NULL;
g_tcm_heap.FreeList->size = sizeof(tcm_heap);
g_heap_inited = 1;
rtw_spinlock_init(&tcm_lock);
#if PLATFORM_FREERTOS
// let RTOS know how to free memory if using as task stack
vPortSetExtFree(tcm_heap_free, 0x20000000, 0x1fff0000);
#endif
}
void tcm_heap_dump(void)
{
MemChunk *chunk, *prev;
struct Heap* h = &g_tcm_heap;
printf("---Free List--\n\r");
for (prev = (MemChunk *)&h->FreeList, chunk = h->FreeList;
chunk;
prev = chunk, chunk = chunk->next)
{
printf(" prev %x, chunk %x, size %d \n\r", prev, chunk, chunk->size);
}
printf("--------------\n\r");
}
void *tcm_heap_allocmem(int size)
{
MemChunk *chunk, *prev;
struct Heap* h = &g_tcm_heap;
_irqL irqL;
rtw_enter_critical(&tcm_lock, &irqL);
if(!g_heap_inited) tcm_heap_init();
/* Round size up to the allocation granularity */
size = ROUND_UP2(size, sizeof(MemChunk));
/* Handle allocations of 0 bytes */
if (!size)
size = sizeof(MemChunk);
/* Walk on the free list looking for any chunk big enough to
* fit the requested block size.
*/
for (prev = (MemChunk *)&h->FreeList, chunk = h->FreeList;
chunk;
prev = chunk, chunk = chunk->next)
{
if (chunk->size >= size)
{
if (chunk->size == size)
{
/* Just remove this chunk from the free list */
prev->next = chunk->next;
#ifdef _DEBUG
memset(chunk, ALLOC_FILL_CODE, size);
#endif
rtw_exit_critical(&tcm_lock, &irqL);
//printf("----ALLOC1-----\n\r");
//tcm_heap_dump();
//printf("--------------\n\r");
return (void *)chunk;
}
else
{
/* Allocate from the END of an existing chunk */
chunk->size -= size;
#ifdef _DEBUG
memset((uint8_t *)chunk + chunk->size, ALLOC_FILL_CODE, size);
#endif
rtw_exit_critical(&tcm_lock, &irqL);
//printf("----ALLOC2-----\n\r");
//tcm_heap_dump();
//printf("--------------\n\r");
return (void *)((uint8_t *)chunk + chunk->size);
}
}
}
rtw_exit_critical(&tcm_lock, &irqL);
//printf("----ALLOC3-----\n\r");
//tcm_heap_dump();
//printf("--------------\n\r");
return NULL; /* fail */
}
void tcm_heap_freemem(void *mem, int size)
{
MemChunk *prev;
//ASSERT(mem);
struct Heap* h = &g_tcm_heap;
_irqL irqL;
rtw_enter_critical(&tcm_lock, &irqL);
if(!g_heap_inited) tcm_heap_init();
#ifdef _DEBUG
memset(mem, FREE_FILL_CODE, size);
#endif
/* Round size up to the allocation granularity */
size = ROUND_UP2(size, sizeof(MemChunk));
/* Handle allocations of 0 bytes */
if (!size)
size = sizeof(MemChunk);
/* Special cases: first chunk in the free list or memory completely full */
//ASSERT((uint8_t*)mem != (uint8_t*)h->FreeList);
if (((uint8_t *)mem) < ((uint8_t *)h->FreeList) || !h->FreeList)
{
/* Insert memory block before the current free list head */
prev = (MemChunk *)mem;
prev->next = h->FreeList;
prev->size = size;
h->FreeList = prev;
}
else /* Normal case: not the first chunk in the free list */
{
/*
* Walk on the free list. Stop at the insertion point (when mem
* is between prev and prev->next)
*/
prev = h->FreeList;
while (prev->next < (MemChunk *)mem && prev->next)
prev = prev->next;
/* Make sure mem is not *within* prev */
//ASSERT((uint8_t*)mem >= (uint8_t*)prev + prev->size);
/* Should it be merged with previous block? */
if (((uint8_t *)prev) + prev->size == ((uint8_t *)mem))
{
/* Yes */
prev->size += size;
}
else /* not merged with previous chunk */
{
MemChunk *curr = (MemChunk*)mem;
/* insert it after the previous node
* and move the 'prev' pointer forward
* for the following operations
*/
curr->next = prev->next;
curr->size = size;
prev->next = curr;
/* Adjust for the following test */
prev = curr;
}
}
/* Also merge with next chunk? */
if (((uint8_t *)prev) + prev->size == ((uint8_t *)prev->next))
{
prev->size += prev->next->size;
prev->next = prev->next->next;
/* There should be only one merge opportunity, becuase we always merge on free */
//ASSERT((uint8_t*)prev + prev->size != (uint8_t*)prev->next);
}
rtw_exit_critical(&tcm_lock, &irqL);
//printf("---FREE %x--\n\r", mem);
//tcm_heap_dump();
//printf("--------------\n\r");
}
int tcm_heap_freeSpace(void)
{
int free_mem = 0;
struct Heap* h = &g_tcm_heap;
_irqL irqL;
MemChunk *chunk;
rtw_enter_critical(&tcm_lock, &irqL);
if(!g_heap_inited) tcm_heap_init();
for (chunk = h->FreeList; chunk; chunk = chunk->next)
free_mem += chunk->size;
rtw_exit_critical(&tcm_lock, &irqL);
return free_mem;
}
/**
* Standard malloc interface
*/
void *tcm_heap_malloc(int size)
{
int *mem;
size += sizeof(int);
if ((mem = (int*)tcm_heap_allocmem(size))){
*mem++ = size;
}
return mem;
}
/**
* Standard calloc interface
*/
void *tcm_heap_calloc(int size)
{
void *mem;
if ((mem = tcm_heap_malloc(size)))
memset(mem, 0, size);
return mem;
}
/**
* Free a block of memory, determining its size automatically.
*
* \param h Heap from which the block was allocated.
* \param mem Pointer to a block of memory previously allocated with
* either heap_malloc() or heap_calloc().
*
* \note If \a mem is a NULL pointer, no operation is performed.
*
* \note Freeing the same memory block twice has undefined behavior.
*
* \note This function works like the ANSI C free().
*/
void tcm_heap_free(void *mem)
{
int *_mem = (int *)mem;
if (_mem)
{
--_mem;
tcm_heap_freemem(_mem, *_mem);
}
}
static void alloc_test(int size, int test_len)
{
//Simple test
uint8_t *a[100];
int i, j;
for (i = 0; i < test_len; i++)
{
a[i] = tcm_heap_allocmem(size);
//ASSERT(a[i]);
for (j = 0; j < size; j++)
a[i][j] = i;
}
//ASSERT(heap_freeSpace(&h) == HEAP_SIZE - test_len * ROUND_UP2(size, sizeof(MemChunk)));
for (i = 0; i < test_len; i++)
{
for (j = 0; j < size; j++)
{
printf("a[%d][%d] = %d\n", i, j, a[i][j]);
//ASSERT(a[i][j] == i);
}
tcm_heap_freemem(a[i], size);
}
//ASSERT(heap_freeSpace(&h) == HEAP_SIZE);
}
#define ALLOC_SIZE 256
#define ALLOC_SIZE2 1024
#define TEST_LEN 20
#define TEST_LEN2 10
#define HEAP_SIZE 59*1024
int tcm_heap_testRun(void)
{
alloc_test(ALLOC_SIZE, TEST_LEN);
alloc_test(ALLOC_SIZE2, TEST_LEN2);
/* Try to allocate the whole heap */
uint8_t *b = tcm_heap_allocmem(HEAP_SIZE);
int i, j;
//ASSERT(b);
//ASSERT(heap_freeSpace(&h) == 0);
//ASSERT(!heap_allocmem(&h, HEAP_SIZE));
for (j = 0; j < HEAP_SIZE; j++)
b[j] = j;
for (j = 0; j < HEAP_SIZE; j++)
{
printf("b[%d] = %d\n", j, j);
//ASSERT(b[j] == (j & 0xff));
}
tcm_heap_freemem(b, HEAP_SIZE);
//ASSERT(heap_freeSpace(&h) == HEAP_SIZE);
return 0;
}
#endif