RTL8710_SDK_GCC_VERSION/component/os/os_dep/osdep_api.c
RtlduinoMan 1d3357d3b0 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.
2016-09-08 20:52:17 +08:00

835 lines
17 KiB
C

/******************************************************************************
*
* 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
}