initial commit
This commit is contained in:
64
lib/amb1_sdk/os/os_dep/device_lock.c
Normal file
64
lib/amb1_sdk/os/os_dep/device_lock.c
Normal 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]);
|
||||
}
|
||||
26
lib/amb1_sdk/os/os_dep/include/device_lock.h
Normal file
26
lib/amb1_sdk/os/os_dep/include/device_lock.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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_CRYPTO = 2,
|
||||
RT_DEV_LOCK_PTA = 3,
|
||||
RT_DEV_LOCK_WLAN = 4,
|
||||
RT_DEV_LOCK_MAX = 5
|
||||
}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_
|
||||
1366
lib/amb1_sdk/os/os_dep/include/osdep_service.h
Normal file
1366
lib/amb1_sdk/os/os_dep/include/osdep_service.h
Normal file
File diff suppressed because it is too large
Load Diff
66
lib/amb1_sdk/os/os_dep/include/tcm_heap.h
Normal file
66
lib/amb1_sdk/os/os_dep/include/tcm_heap.h
Normal 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 */
|
||||
1318
lib/amb1_sdk/os/os_dep/osdep_service.c
Normal file
1318
lib/amb1_sdk/os/os_dep/osdep_service.c
Normal file
File diff suppressed because it is too large
Load Diff
352
lib/amb1_sdk/os/os_dep/tcm_heap.c
Normal file
352
lib/amb1_sdk/os/os_dep/tcm_heap.c
Normal 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
|
||||
Reference in New Issue
Block a user