build: W600-SDK importiert, Firmware-Build und Hello am EVK
Docker-Build mit gcc-arm-none-eabi 4.9-2014q4 (statt Homebrew-Cask) verwendet, Dockerfile/tools/docker.sh dafür aus Task 13 vorgezogen. cmake/sdk.cmake schont gcc 4.9 (kennt -fcommon/-Wno-error=... nicht). Zwei zusätzliche SDK-Stubs (EarlyInit, pre_gpio_config) in src/sys/sdk_stubs.c ergänzt, siehe sdk/PATCHES.md.
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
# THE VERSION NUMBER
|
||||
SET(CMAKE_SYSTEM_NAME Generic)
|
||||
CMAKE_MINIMUM_REQUIRED (VERSION 3.10)
|
||||
PROJECT(WCOMMON)
|
||||
|
||||
SET(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 1)
|
||||
SET(CMAKE_NINJA_FORCE_RESPONSE_FILE 1 CACHE INTERNAL "")
|
||||
|
||||
set(CMAKE_VERBOSE_MAKEFILE OFF)
|
||||
|
||||
# ENABLE ASM
|
||||
ENABLE_LANGUAGE(ASM)
|
||||
|
||||
SET(CMAKE_STATIC_LIBRARY_PREFIX)
|
||||
SET(CMAKE_STATIC_LIBRARY_SUFFIX)
|
||||
|
||||
SET(CMAKE_EXECUTABLE_LIBRARY_PREFIX)
|
||||
SET(CMAKE_EXECUTABLE_LIBRARY_SUFFIX)
|
||||
|
||||
# C FLAGS
|
||||
SET(CMAKE_C_FLAGS " -mthumb --function-sections --data-sections -mcpu=cortex-m3 -std=gnu99 -mabi=aapcs -march=armv7-m -fno-builtin -Wall")
|
||||
STRING(APPEND CMAKE_C_FLAGS " -DGCC_COMPILE=1 -DWOLFSSL_USER_SETTINGS -D_IN_ADDR_T_DECLARED -D__MACHINE_ENDIAN_H__ -D_TIMEVAL_DEFINED -D__INSIDE_CYGWIN_NET__ ")
|
||||
|
||||
SET(CMAKE_C_FLAGS_DEBUG "-O0 -g3 -gdwarf-2 -Wall -DDEBUG ")
|
||||
SET(CMAKE_C_FLAGS_RELEASE "-Os -Wall")
|
||||
|
||||
|
||||
# DEBUG ASM FLAGS
|
||||
SET(CMAKE_ASM_FLAGS_DEBUG "${CMAKE_ASM_FLAGS_DEBUG} -O0 -g3 -gdwarf-2 -Wall -mthumb-interwork -mthumb -std=gnu99 -mcpu=cortex-m3 -march=armv7-m -mabi=aapcs -fno-builtin -DDEBUG ")
|
||||
SET(CMAKE_ASM_FLAGS_RELEASE "${CMAKE_ASM_FLAGS_RELEASE} -Os -Wall -mthumb-interwork -mthumb -std=gnu99 -mcpu=cortex-m3 -march=armv7-m -mabi=aapcs -fno-builtin ")
|
||||
|
||||
# Library sources
|
||||
SET(LIBRARY_SOURCES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/fwup/wm_fwup.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/mem/wm_mem.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/Params/wm_param.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/task/wm_wl_mbox.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/task/wm_wl_task.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/task/wm_wl_timers.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/utils/utils.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/crypto/wm_crypto_hard.c"
|
||||
|
||||
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/digest/hmac.c"
|
||||
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/digest/md2.c"
|
||||
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/digest/md4.c"
|
||||
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/digest/sha224.c"
|
||||
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/digest/sha384.c"
|
||||
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/digest/sha512.c"
|
||||
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/keyformat/asn1.c"
|
||||
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/keyformat/base64.c"
|
||||
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/keyformat/x509.c"
|
||||
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/math/pstm_mul_comba.c"
|
||||
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/prng/prng.c"
|
||||
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/prng/yarrow.c"
|
||||
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/pubkey/dh.c"
|
||||
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/pubkey/ecc.c"
|
||||
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/pubkey/pkcs.c"
|
||||
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/pubkey/pubkey.c"
|
||||
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/pubkey/rsa.c"
|
||||
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/symmetric/aesGCM.c"
|
||||
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/symmetric/des3.c"
|
||||
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/symmetric/idea.c"
|
||||
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/symmetric/rc2.c"
|
||||
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/symmetric/seed.c"
|
||||
)
|
||||
|
||||
function(ADD_LIB_TARGET LIBTARGET)
|
||||
add_library(${LIBTARGET} OBJECT ${LIBRARY_SOURCES})
|
||||
# ADD_CUSTOM_COMMAND(TARGET ${LIBTARGET} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${EXECUTABLE_OUTPUT_PATH}/${LIBTARGET} ${CMAKE_CURRENT_SOURCE_DIR}/../../Lib/GNU/${LIBTARGET})
|
||||
endfunction()
|
||||
|
||||
ADD_LIB_TARGET(wmcommon.a)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,124 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File Name : tls_param.h
|
||||
*
|
||||
* Description: param manager Module
|
||||
*
|
||||
* Copyright (c) 2014 Winner Micro Electronic Design Co., Ltd.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author : dave
|
||||
*
|
||||
* Date : 2014-6-12
|
||||
*****************************************************************************/
|
||||
#ifndef TLS_PARAM_H
|
||||
#define TLS_PARAM_H
|
||||
#include "wm_type_def.h"
|
||||
|
||||
|
||||
|
||||
struct tls_param_quick_connect{
|
||||
bool quick_connect_en;
|
||||
u8 chanId;
|
||||
};
|
||||
|
||||
struct tls_sys_param {
|
||||
struct tls_param_hardware_version hardware_version;
|
||||
|
||||
struct tls_param_bssid bssid;
|
||||
struct tls_param_ssid ssid;
|
||||
u8 channel_enable;
|
||||
u8 channel;
|
||||
u8 wireless_region;
|
||||
u8 encry;
|
||||
u8 wireless_protocol;
|
||||
u8 auto_create_adhoc;
|
||||
u8 auto_retrycnt;
|
||||
u8 auto_roam;
|
||||
u8 auto_powersave;
|
||||
u8 ssid_broadcast_enable;
|
||||
u16 channellist;
|
||||
struct tls_param_key key;
|
||||
struct tls_param_bgr wbgr;
|
||||
struct tls_param_wps wps;
|
||||
|
||||
struct tls_param_ip ipcfg;
|
||||
|
||||
u8 local_dnsname[32];
|
||||
u8 local_device_name[32];
|
||||
|
||||
struct tls_param_oray_client oray_client_setting;
|
||||
|
||||
u8 upnp_enable;
|
||||
|
||||
u8 always_online;
|
||||
|
||||
u8 user_port_mode;
|
||||
|
||||
u8 res_2;
|
||||
|
||||
struct tls_param_uart uart_cfg;
|
||||
|
||||
u8 auto_mode;
|
||||
u8 res_3;
|
||||
u16 transparent_trigger_length;
|
||||
u16 transparent_trigger_period;
|
||||
|
||||
struct tls_param_socket remote_socket_cfg;
|
||||
|
||||
u32 debug_mode;
|
||||
u32 res_4[2]; /* reserv and mark the end */
|
||||
|
||||
/*escape char*/
|
||||
u8 EscapeChar;
|
||||
u8 EscReserved;
|
||||
u16 EscapePeriod; /* unit: ms */
|
||||
|
||||
u8 IoMode;
|
||||
u8 CmdMode;
|
||||
u8 PassWord[6];
|
||||
|
||||
struct tls_webs_cfg WebsCfg;
|
||||
u8 oneshotflag;
|
||||
u8 oneshotres[2];
|
||||
struct tls_param_sha1 psk;
|
||||
struct tls_param_original_key original_key;
|
||||
struct tls_param_ssid original_ssid;
|
||||
u8 auto_reconnect;
|
||||
u8 res_5[3];
|
||||
|
||||
struct tls_param_quick_connect quick_connect;
|
||||
|
||||
u8 key_changed;
|
||||
u8 ssid_changed;
|
||||
|
||||
struct tls_param_ssid apsta_ssid;
|
||||
struct tls_param_sha1 apsta_psk;
|
||||
u8 res_6[1];
|
||||
u8 channel4softap;
|
||||
u8 encry4softap;
|
||||
struct tls_param_key key4softap;
|
||||
struct tls_param_ip ipcfg4softap;
|
||||
struct tls_param_bgr wbgr4softap;
|
||||
|
||||
char sntp_service1[32];
|
||||
char sntp_service2[32];
|
||||
char sntp_service3[32];
|
||||
struct tls_param_tem_offset params_tem;
|
||||
};
|
||||
|
||||
struct tls_param_flash {
|
||||
u32 magic;
|
||||
u16 partition_num;
|
||||
u16 modify_count;
|
||||
u32 resv_1;
|
||||
u16 resv_2;
|
||||
u16 length;
|
||||
struct tls_sys_param parameters;
|
||||
u32 crc32;
|
||||
};
|
||||
|
||||
|
||||
#endif /* WM_PARAM_H */
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,765 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File Name : wm_mem.c
|
||||
*
|
||||
* Description: memory manager Module
|
||||
*
|
||||
* Copyright (c) 2014 Winner Micro Electronic Design Co., Ltd.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author : dave
|
||||
*
|
||||
* Date : 2014-6-12
|
||||
*****************************************************************************/
|
||||
|
||||
#include "wm_osal.h"
|
||||
#include "wm_mem.h"
|
||||
#include "list.h"
|
||||
#include <string.h>
|
||||
|
||||
extern u8 tls_get_isr_count(void);
|
||||
/**
|
||||
* This variable is set if the memory mananger has been initialized.
|
||||
* This is available only for debug version of the driver
|
||||
*/
|
||||
bool memory_manager_initialized = false;
|
||||
/**
|
||||
* This mutex is used to synchronize the list of allocated
|
||||
* memory blocks. This is a debug version only feature
|
||||
*/
|
||||
tls_os_sem_t *mem_sem;
|
||||
#if WM_MEM_DEBUG
|
||||
|
||||
|
||||
struct dl_list memory_used_list;
|
||||
struct dl_list memory_free_list;
|
||||
#define MEM_BLOCK_SIZE 600
|
||||
MEMORY_BLOCK mem_blocks[MEM_BLOCK_SIZE];
|
||||
|
||||
|
||||
u32 alloc_heap_mem_bytes = 0;
|
||||
u32 alloc_heap_mem_blk_cnt = 0;
|
||||
u32 alloc_heap_mem_max_size = 0;
|
||||
|
||||
#define PRE_OVERSIZE 0
|
||||
#define OVERSIZE 0
|
||||
|
||||
/**
|
||||
* This is a debug only function that performs memory management operations for us.
|
||||
* Memory allocated using this function is tracked, flagged when leaked, and caught for
|
||||
* overflows and underflows.
|
||||
*
|
||||
* \param size The size in bytes of memory to
|
||||
* allocate
|
||||
*
|
||||
* \param file The full path of file where this
|
||||
* function is invoked from
|
||||
* \param line The line number in the file where this
|
||||
* method was called from
|
||||
* \return Pointer to the allocated memory or NULL in case of a failure
|
||||
*/
|
||||
void * mem_alloc_debug(u32 size, char* file, int line)
|
||||
{
|
||||
void *buf = NULL;
|
||||
u32 pad_len;
|
||||
int i = 0;
|
||||
u32 cpu_sr;
|
||||
//
|
||||
// If the memory manager has not been initialized, do so now
|
||||
//
|
||||
cpu_sr = tls_os_set_critical();
|
||||
if (!memory_manager_initialized) {
|
||||
tls_os_status_t os_status;
|
||||
memory_manager_initialized = true;
|
||||
//
|
||||
// NOTE: If two thread allocate the very first allocation simultaneously
|
||||
// it could cause double initialization of the memory manager. This is a
|
||||
// highly unlikely scenario and will occur in debug versions only.
|
||||
//
|
||||
os_status = tls_os_sem_create(&mem_sem, 1);
|
||||
if(os_status != TLS_OS_SUCCESS)
|
||||
printf("mem_alloc_debug: tls_os_sem_create mem_sem error\n");
|
||||
dl_list_init(&memory_used_list);
|
||||
dl_list_init(&memory_free_list);
|
||||
for(i = 0; i < MEM_BLOCK_SIZE; i++)
|
||||
{
|
||||
dl_list_add_tail(&memory_free_list, &mem_blocks[i].list);
|
||||
}
|
||||
}
|
||||
tls_os_release_critical(cpu_sr);
|
||||
|
||||
tls_os_sem_acquire(mem_sem, 0);
|
||||
cpu_sr = tls_os_set_critical();
|
||||
//
|
||||
// Allocate the required memory chunk plus header and trailer bytes
|
||||
//
|
||||
pad_len = sizeof(u32) - (size & 0x3);
|
||||
buf = malloc(sizeof(MEMORY_PATTERN) + PRE_OVERSIZE + size + pad_len + OVERSIZE + sizeof(MEMORY_PATTERN));
|
||||
|
||||
if (buf) {
|
||||
//
|
||||
// Memory allocation succeeded. Add information about the allocated
|
||||
// block in the list that tracks all allocations.
|
||||
//
|
||||
PMEMORY_PATTERN mem_ptn_hd;
|
||||
PMEMORY_PATTERN mem_ptn_tl;
|
||||
PMEMORY_BLOCK mem_blk_hd1;
|
||||
|
||||
if(dl_list_empty(&memory_free_list))
|
||||
{
|
||||
printf("Memory blocks empty!\n");
|
||||
free(buf);
|
||||
tls_os_release_critical(cpu_sr);
|
||||
tls_os_sem_release(mem_sem);
|
||||
tls_mem_alloc_info();
|
||||
return NULL;
|
||||
}
|
||||
mem_blk_hd1 = dl_list_first(&memory_free_list, MEMORY_BLOCK, list);
|
||||
dl_list_del(&mem_blk_hd1->list);
|
||||
dl_list_add_tail(&memory_used_list, &mem_blk_hd1->list);
|
||||
alloc_heap_mem_bytes += size+sizeof(MEMORY_PATTERN)+sizeof(MEMORY_PATTERN)+pad_len + PRE_OVERSIZE + OVERSIZE;
|
||||
alloc_heap_mem_blk_cnt++;
|
||||
if (alloc_heap_mem_bytes > alloc_heap_mem_max_size)
|
||||
{
|
||||
alloc_heap_mem_max_size = alloc_heap_mem_bytes;
|
||||
//printf("alloc_heap_mem_max_size=%d\n", alloc_heap_mem_max_size);
|
||||
}
|
||||
|
||||
mem_blk_hd1->pad = pad_len;
|
||||
mem_blk_hd1->file = file;
|
||||
mem_blk_hd1->line = line;
|
||||
mem_blk_hd1->length = size;
|
||||
mem_blk_hd1->header_pattern = (u32)buf;
|
||||
|
||||
// Fill in the memory header and trailer
|
||||
mem_ptn_hd = (PMEMORY_PATTERN)buf;
|
||||
mem_ptn_hd->pattern0= MEM_HEADER_PATTERN;
|
||||
/*mem_ptn_hd->pattern1= MEM_HEADER_PATTERN;
|
||||
mem_ptn_hd->pattern2= MEM_HEADER_PATTERN;
|
||||
mem_ptn_hd->pattern3= MEM_HEADER_PATTERN;*/
|
||||
|
||||
mem_ptn_tl = (PMEMORY_PATTERN)(((u8 *)(buf))+size + sizeof(MEMORY_PATTERN)+pad_len + PRE_OVERSIZE + OVERSIZE);
|
||||
mem_ptn_tl->pattern0= MEM_TAILER_PATTERN;
|
||||
/*mem_ptn_tl->pattern1= MEM_TAILER_PATTERN;
|
||||
mem_ptn_tl->pattern2= MEM_TAILER_PATTERN;
|
||||
mem_ptn_tl->pattern3= MEM_TAILER_PATTERN;*/
|
||||
|
||||
// Jump ahead by memory header so pointer returned to caller points at the right place
|
||||
buf = ((u8 *)buf) + sizeof (MEMORY_PATTERN) + PRE_OVERSIZE;
|
||||
|
||||
#if 0
|
||||
|
||||
printf("==>Memory was allocated from %s at line %d with length %d\n",
|
||||
mem_blk_hd->file,
|
||||
mem_blk_hd->line,
|
||||
mem_blk_hd->length);
|
||||
printf("==>mem alloc ptr = 0x%x\n", buf);
|
||||
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("==>Memory was allocated from %s at line %d with length %d, allocated size %d, count %d\n",
|
||||
file,
|
||||
line,
|
||||
size, alloc_heap_mem_bytes, alloc_heap_mem_blk_cnt);
|
||||
tls_os_release_critical(cpu_sr);
|
||||
tls_os_sem_release(mem_sem);
|
||||
tls_mem_alloc_info();
|
||||
return buf;
|
||||
}
|
||||
tls_os_release_critical(cpu_sr);
|
||||
tls_os_sem_release(mem_sem);
|
||||
return buf;
|
||||
}
|
||||
|
||||
void * mem_calloc_debug(u32 n, u32 size, char* file, int line)
|
||||
{
|
||||
void *buf = NULL;
|
||||
u32 pad_len;
|
||||
int i = 0;
|
||||
u32 cpu_sr;
|
||||
//
|
||||
// If the memory manager has not been initialized, do so now
|
||||
//
|
||||
cpu_sr = tls_os_set_critical();
|
||||
if (!memory_manager_initialized) {
|
||||
tls_os_status_t os_status;
|
||||
memory_manager_initialized = true;
|
||||
//
|
||||
// NOTE: If two thread allocate the very first allocation simultaneously
|
||||
// it could cause double initialization of the memory manager. This is a
|
||||
// highly unlikely scenario and will occur in debug versions only.
|
||||
//
|
||||
os_status = tls_os_sem_create(&mem_sem, 1);
|
||||
if(os_status != TLS_OS_SUCCESS)
|
||||
printf("mem_alloc_debug: tls_os_sem_create mem_sem error\n");
|
||||
dl_list_init(&memory_used_list);
|
||||
dl_list_init(&memory_free_list);
|
||||
for(i = 0; i < MEM_BLOCK_SIZE; i++)
|
||||
{
|
||||
dl_list_add_tail(&memory_free_list, &mem_blocks[i].list);
|
||||
}
|
||||
}
|
||||
tls_os_release_critical(cpu_sr);
|
||||
|
||||
tls_os_sem_acquire(mem_sem, 0);
|
||||
cpu_sr = tls_os_set_critical();
|
||||
//
|
||||
// Allocate the required memory chunk plus header and trailer bytes
|
||||
//
|
||||
pad_len = sizeof(u32) - ((n*size) & 0x3);
|
||||
buf = malloc(sizeof(MEMORY_PATTERN) + PRE_OVERSIZE + n*size + pad_len + OVERSIZE + sizeof(MEMORY_PATTERN));
|
||||
|
||||
if (buf) {
|
||||
//
|
||||
// Memory allocation succeeded. Add information about the allocated
|
||||
// block in the list that tracks all allocations.
|
||||
//
|
||||
PMEMORY_PATTERN mem_ptn_hd;
|
||||
PMEMORY_PATTERN mem_ptn_tl;
|
||||
PMEMORY_BLOCK mem_blk_hd1;
|
||||
|
||||
if(dl_list_empty(&memory_free_list))
|
||||
{
|
||||
printf("Memory blocks empty!\n");
|
||||
free(buf);
|
||||
tls_os_release_critical(cpu_sr);
|
||||
tls_os_sem_release(mem_sem);
|
||||
tls_mem_alloc_info();
|
||||
return NULL;
|
||||
}
|
||||
mem_blk_hd1 = dl_list_first(&memory_free_list, MEMORY_BLOCK, list);
|
||||
dl_list_del(&mem_blk_hd1->list);
|
||||
dl_list_add_tail(&memory_used_list, &mem_blk_hd1->list);
|
||||
alloc_heap_mem_bytes += n*size+sizeof(MEMORY_PATTERN)+sizeof(MEMORY_PATTERN)+pad_len + PRE_OVERSIZE + OVERSIZE;
|
||||
alloc_heap_mem_blk_cnt++;
|
||||
if (alloc_heap_mem_bytes > alloc_heap_mem_max_size)
|
||||
{
|
||||
alloc_heap_mem_max_size = alloc_heap_mem_bytes;
|
||||
//printf("alloc_heap_mem_max_size=%d\n", alloc_heap_mem_max_size);
|
||||
}
|
||||
|
||||
mem_blk_hd1->pad = pad_len;
|
||||
mem_blk_hd1->file = file;
|
||||
mem_blk_hd1->line = line;
|
||||
mem_blk_hd1->length = n*size;
|
||||
mem_blk_hd1->header_pattern = (u32)buf;
|
||||
|
||||
// Fill in the memory header and trailer
|
||||
mem_ptn_hd = (PMEMORY_PATTERN)buf;
|
||||
mem_ptn_hd->pattern0= MEM_HEADER_PATTERN;
|
||||
/*mem_ptn_hd->pattern1= MEM_HEADER_PATTERN;
|
||||
mem_ptn_hd->pattern2= MEM_HEADER_PATTERN;
|
||||
mem_ptn_hd->pattern3= MEM_HEADER_PATTERN;*/
|
||||
|
||||
mem_ptn_tl = (PMEMORY_PATTERN)(((u8 *)(buf))+n*size + sizeof(MEMORY_PATTERN)+pad_len + PRE_OVERSIZE + OVERSIZE);
|
||||
mem_ptn_tl->pattern0= MEM_TAILER_PATTERN;
|
||||
/*mem_ptn_tl->pattern1= MEM_TAILER_PATTERN;
|
||||
mem_ptn_tl->pattern2= MEM_TAILER_PATTERN;
|
||||
mem_ptn_tl->pattern3= MEM_TAILER_PATTERN;*/
|
||||
|
||||
// Jump ahead by memory header so pointer returned to caller points at the right place
|
||||
buf = ((u8 *)buf) + sizeof (MEMORY_PATTERN) + PRE_OVERSIZE;
|
||||
|
||||
#if 0
|
||||
|
||||
printf("==>Memory was allocated from %s at line %d with length %d\n",
|
||||
mem_blk_hd->file,
|
||||
mem_blk_hd->line,
|
||||
mem_blk_hd->length);
|
||||
printf("==>mem alloc ptr = 0x%x\n", buf);
|
||||
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("==>Memory was allocated from %s at line %d with length %d, allocated size %d, count %d\n",
|
||||
file,
|
||||
line,
|
||||
n*size, alloc_heap_mem_bytes, alloc_heap_mem_blk_cnt);
|
||||
|
||||
tls_os_release_critical(cpu_sr);
|
||||
tls_os_sem_release(mem_sem);
|
||||
tls_mem_alloc_info();
|
||||
return buf;
|
||||
}
|
||||
tls_os_release_critical(cpu_sr);
|
||||
tls_os_sem_release(mem_sem);
|
||||
return buf;
|
||||
}
|
||||
/**
|
||||
* This routine is called to free memory which was previously allocated using MpAllocateMemory function.
|
||||
* Before freeing the memory, this function checks and makes sure that no overflow or underflows have
|
||||
* happened and will also try to detect multiple frees of the same memory chunk.
|
||||
*
|
||||
* \param p Pointer to allocated memory
|
||||
*/
|
||||
void mem_free_debug(void *p, char* file, int line)
|
||||
{
|
||||
PMEMORY_PATTERN mem_ptn_hd;
|
||||
PMEMORY_PATTERN mem_ptn_tl;
|
||||
PMEMORY_BLOCK mem_blk_hd1;
|
||||
u8 needfree = 0;
|
||||
u8 haserr = 0;
|
||||
u32 cpu_sr;
|
||||
|
||||
// Jump back by memory header size so we can get to the header
|
||||
mem_ptn_hd = (PMEMORY_PATTERN) (((u8 *)p) - sizeof(MEMORY_PATTERN) - PRE_OVERSIZE);
|
||||
tls_os_sem_acquire(mem_sem, 0);
|
||||
cpu_sr = tls_os_set_critical();
|
||||
dl_list_for_each(mem_blk_hd1, &memory_used_list, MEMORY_BLOCK, list){
|
||||
if(mem_blk_hd1->header_pattern == (u32)mem_ptn_hd)
|
||||
{
|
||||
needfree = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(needfree)
|
||||
{
|
||||
dl_list_del(&mem_blk_hd1->list);
|
||||
dl_list_add_tail(&memory_free_list, &mem_blk_hd1->list);
|
||||
alloc_heap_mem_bytes -= mem_blk_hd1->length + sizeof(MEMORY_PATTERN) + sizeof(MEMORY_PATTERN) + PRE_OVERSIZE + OVERSIZE +
|
||||
mem_blk_hd1->pad;
|
||||
alloc_heap_mem_blk_cnt--;
|
||||
}
|
||||
if(needfree == 0)
|
||||
{
|
||||
printf("Memory Block %p was deallocated from %s at line %d \n", mem_ptn_hd, file, line);
|
||||
printf("Memory %p has been deallocated!\n", p);
|
||||
dl_list_for_each_reverse(mem_blk_hd1, &memory_free_list, MEMORY_BLOCK, list){
|
||||
if(mem_blk_hd1->header_pattern == (u32)mem_ptn_hd)
|
||||
{
|
||||
printf("Memory Block %p has been put free list!\n", mem_ptn_hd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
tls_os_release_critical(cpu_sr);
|
||||
tls_os_sem_release(mem_sem);
|
||||
tls_mem_alloc_info();
|
||||
return;
|
||||
}
|
||||
#if 0
|
||||
if(mem_blk_hd1->line == 976 || mem_blk_hd1->line == 983)
|
||||
{
|
||||
printf("Memory Block %p can not deallocated from %s at line %d \n", mem_ptn_hd, file, line);
|
||||
printf("Memory %p has been deallocated!\n", p);
|
||||
tls_mem_alloc_info();
|
||||
}
|
||||
#endif
|
||||
mem_ptn_tl = (PMEMORY_PATTERN) ((u8 *)p + mem_blk_hd1->length + mem_blk_hd1->pad + OVERSIZE);
|
||||
//
|
||||
// Check that header was not corrupted
|
||||
//
|
||||
if (mem_ptn_hd->pattern0 != MEM_HEADER_PATTERN /*|| mem_ptn_hd->pattern1 != MEM_HEADER_PATTERN
|
||||
|| mem_ptn_hd->pattern2 != MEM_HEADER_PATTERN || mem_ptn_hd->pattern3 != MEM_HEADER_PATTERN*/)
|
||||
{
|
||||
printf("Memory %p was deallocated from %s at line %d \n", p, file, line);
|
||||
printf("Memory header corruption due to underflow detected at memory block %p\n",
|
||||
mem_ptn_hd);
|
||||
printf("Header pattern 0(0x%x)\n",//, 1(0x%x), 2(0x%x), 3(0x%x)
|
||||
mem_ptn_hd->pattern0/*,
|
||||
mem_ptn_hd->pattern1,
|
||||
mem_ptn_hd->pattern2,
|
||||
mem_ptn_hd->pattern3*/);
|
||||
//printf("Dumping information about memory block. "
|
||||
// "This information may itself have been "
|
||||
// "corrupted and could cause machine to bugcheck.\n");
|
||||
printf("Memory was allocated from %s at line %d with length %d\n",
|
||||
mem_blk_hd1->file,
|
||||
mem_blk_hd1->line,
|
||||
mem_blk_hd1->length);
|
||||
haserr = 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
printf("<==free memory allocated from %s at line %d with length %d\n",
|
||||
mem_blk_hd->file,
|
||||
mem_blk_hd->line,
|
||||
mem_blk_hd->length);
|
||||
printf("<==free memory 0x%x\n", (u8 *)mem_blk_hd+sizeof(*mem_blk_hd));
|
||||
#endif
|
||||
|
||||
//
|
||||
// Check that trailer was not corrupted
|
||||
//
|
||||
if(mem_ptn_tl->pattern0 != MEM_TAILER_PATTERN /*|| mem_ptn_tl->pattern1 != MEM_TAILER_PATTERN
|
||||
|| mem_ptn_tl->pattern2 != MEM_TAILER_PATTERN || mem_ptn_tl->pattern3 != MEM_TAILER_PATTERN*/) {
|
||||
printf("Memory %p was deallocated from %s at line %d \n", p, file, line);
|
||||
printf("Memory tailer corruption due to overflow detected at %p\n", mem_ptn_hd);
|
||||
printf("Tailer pattern 0(0x%x)\n",//, 1(0x%x), 2(0x%x), 3(0x%x)
|
||||
mem_ptn_tl->pattern0/*,
|
||||
mem_ptn_tl->pattern1,
|
||||
mem_ptn_tl->pattern2,
|
||||
mem_ptn_tl->pattern3*/);
|
||||
//printf("Dumping information about memory block. "
|
||||
// "This information may itself have been "
|
||||
// "corrupted and could cause machine to bugcheck.\n");
|
||||
printf("Memory was allocated from %s at line %d with length %d\n",
|
||||
mem_blk_hd1->file, mem_blk_hd1->line, mem_blk_hd1->length);
|
||||
haserr = 1;
|
||||
}
|
||||
if(needfree){
|
||||
free(mem_ptn_hd);
|
||||
}
|
||||
|
||||
tls_os_release_critical(cpu_sr);
|
||||
tls_os_sem_release(mem_sem);
|
||||
|
||||
if(haserr)
|
||||
tls_mem_alloc_info();
|
||||
}
|
||||
|
||||
void * mem_realloc_debug(void *mem_address, u32 size, char* file, int line)
|
||||
{
|
||||
void * mem_re_addr;
|
||||
u32 cpu_sr;
|
||||
|
||||
if ((mem_re_addr = mem_alloc_debug(size, file, line)) == NULL){
|
||||
printf("mem_realloc_debug failed(size=%d).\n", size);
|
||||
return NULL;
|
||||
}
|
||||
if(mem_address != NULL)
|
||||
{
|
||||
cpu_sr = tls_os_set_critical();
|
||||
memcpy(mem_re_addr, mem_address, size);
|
||||
tls_os_release_critical(cpu_sr);
|
||||
mem_free_debug(mem_address, file, line);
|
||||
}
|
||||
//printf("mem_realloc_debug mem_address=%p, mem_re_addr=%p, size=%d, file=%s, line=%d\n", mem_address, mem_re_addr, size, file, line);
|
||||
return mem_re_addr;
|
||||
}
|
||||
|
||||
void tls_mem_alloc_info(void)
|
||||
{
|
||||
int i;
|
||||
MEMORY_BLOCK * pos;
|
||||
u32 cpu_sr;
|
||||
|
||||
tls_os_sem_acquire(mem_sem, 0);
|
||||
cpu_sr = tls_os_set_critical();
|
||||
printf("==>Memory was allocated size %d, count %d\n",
|
||||
alloc_heap_mem_bytes, alloc_heap_mem_blk_cnt);
|
||||
i = 1;
|
||||
dl_list_for_each(pos, &memory_used_list, MEMORY_BLOCK, list){
|
||||
printf("Block(%2d): addr<%p>, file<%s>, line<%d>, length<%d>\n",
|
||||
i, pos->header_pattern, pos->file, pos->line, pos->length);
|
||||
i++;
|
||||
}
|
||||
tls_os_release_critical(cpu_sr);
|
||||
tls_os_sem_release(mem_sem);
|
||||
|
||||
}
|
||||
|
||||
int is_safe_addr_debug(void* p, u32 len, char* file, int line)
|
||||
{
|
||||
int i;
|
||||
MEMORY_BLOCK * pos;
|
||||
u32 cpu_sr;
|
||||
|
||||
if(((u32)p) >= (u32)0x64ae8 || ((u32)p) < (u32)0x54ae8)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
tls_os_sem_acquire(mem_sem, 0);
|
||||
cpu_sr = tls_os_set_critical();
|
||||
i = 1;
|
||||
dl_list_for_each(pos, &memory_used_list, MEMORY_BLOCK, list){
|
||||
if((pos->header_pattern + sizeof (MEMORY_PATTERN) + PRE_OVERSIZE) <= ((u32)p) && ((u32)p) <= ((u32)(pos->header_pattern + sizeof(MEMORY_PATTERN) + PRE_OVERSIZE + pos->length)))
|
||||
{
|
||||
if(((u32)p) + len > ((u32)(pos->header_pattern + sizeof(MEMORY_PATTERN) + PRE_OVERSIZE + pos->length)))
|
||||
{
|
||||
printf("==>Memory oversize. Block(%2d): addr<%p>, file<%s>, line<%d>, length<%d>\n",
|
||||
i, pos->header_pattern, pos->file, pos->line, pos->length);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
tls_os_release_critical(cpu_sr);
|
||||
tls_os_sem_release(mem_sem);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
//else if(((u32)p) < pos->header_pattern)
|
||||
//{
|
||||
// //tls_os_release_critical(cpu_sr);
|
||||
// tls_os_sem_release(mem_sem);
|
||||
// return 1;
|
||||
// }
|
||||
i++;
|
||||
}
|
||||
tls_os_release_critical(cpu_sr);
|
||||
tls_os_sem_release(mem_sem);
|
||||
printf("==>Memory is not safe addr<%p>, file<%s>, line<%d>.\n",p, file, line);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* WM_MEM_DEBUG */
|
||||
#if TLS_OS_FREERTOS
|
||||
u32 alloc_heap_mem_bytes = 0;
|
||||
u32 alloc_heap_mem_blk_cnt = 0;
|
||||
u32 alloc_heap_mem_max_size = 0;
|
||||
#define OS_MEM_FLAG (0x5AA5A55A)
|
||||
#define MEM_HEAD_FLAG (0xBB55B55B)
|
||||
#endif
|
||||
|
||||
void * mem_alloc_debug(u32 size)
|
||||
{
|
||||
u32 cpu_sr = 0;
|
||||
u32 *buffer = NULL;
|
||||
|
||||
#if TLS_OS_FREERTOS
|
||||
u32 flag = 0;
|
||||
#endif
|
||||
|
||||
if (!memory_manager_initialized) {
|
||||
tls_os_status_t os_status;
|
||||
memory_manager_initialized = true;
|
||||
//
|
||||
// NOTE: If two thread allocate the very first allocation simultaneously
|
||||
// it could cause double initialization of the memory manager. This is a
|
||||
// highly unlikely scenario and will occur in debug versions only.
|
||||
//
|
||||
os_status = tls_os_sem_create(&mem_sem, 1);
|
||||
if(os_status != TLS_OS_SUCCESS)
|
||||
printf("mem_alloc_debug: tls_os_sem_create mem_sem error\n");
|
||||
}
|
||||
|
||||
#if TLS_OS_FREERTOS
|
||||
size += 8;
|
||||
if(tls_get_isr_count() > 0)
|
||||
{
|
||||
extern void *pvPortMalloc( size_t xWantedSize );
|
||||
buffer = pvPortMalloc(size);
|
||||
flag = OS_MEM_FLAG;
|
||||
}
|
||||
else
|
||||
{
|
||||
tls_os_sem_acquire(mem_sem, 0);
|
||||
cpu_sr = tls_os_set_critical();
|
||||
buffer = (u32*)malloc(size);
|
||||
}
|
||||
|
||||
if(buffer)
|
||||
{
|
||||
*buffer = MEM_HEAD_FLAG;
|
||||
buffer++;
|
||||
*buffer = flag;
|
||||
buffer++;
|
||||
}
|
||||
|
||||
if(tls_get_isr_count() == 0)
|
||||
{
|
||||
tls_os_release_critical(cpu_sr);
|
||||
tls_os_sem_release(mem_sem);
|
||||
}
|
||||
#else //UCOSII
|
||||
cpu_sr = tls_os_set_critical();
|
||||
buffer = (u32*)malloc(size);
|
||||
tls_os_release_critical(cpu_sr);
|
||||
#endif
|
||||
// if(buffer == NULL)
|
||||
// {
|
||||
// printf("malloc error \n");
|
||||
// }
|
||||
return buffer;
|
||||
|
||||
}
|
||||
|
||||
void mem_free_debug(void *p)
|
||||
{
|
||||
u32 cpu_sr = 0;
|
||||
#if TLS_OS_FREERTOS
|
||||
u32* intMemPtr = (void*)p;
|
||||
|
||||
if(tls_get_isr_count() == 0)
|
||||
{
|
||||
tls_os_sem_acquire(mem_sem, 0);
|
||||
cpu_sr = tls_os_set_critical();
|
||||
}
|
||||
|
||||
if(p)
|
||||
{
|
||||
intMemPtr = intMemPtr - 2;
|
||||
if(*intMemPtr != MEM_HEAD_FLAG)
|
||||
{
|
||||
//printf("mem_free_debug ptr error!!!!!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
intMemPtr++;
|
||||
if(*intMemPtr == OS_MEM_FLAG)
|
||||
{
|
||||
extern void vPortFree( void *pv );
|
||||
intMemPtr -= 1;
|
||||
vPortFree(intMemPtr);
|
||||
}
|
||||
else
|
||||
{
|
||||
intMemPtr -= 1;
|
||||
free(intMemPtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(tls_get_isr_count() == 0)
|
||||
{
|
||||
tls_os_release_critical(cpu_sr);
|
||||
tls_os_sem_release(mem_sem);
|
||||
}
|
||||
#else //UCOSII
|
||||
cpu_sr = tls_os_set_critical();
|
||||
free(p);
|
||||
tls_os_release_critical(cpu_sr);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void * mem_realloc_debug(void *mem_address, u32 size)
|
||||
{
|
||||
u32 * mem_re_addr = NULL;
|
||||
u32 cpu_sr = 0;
|
||||
#if TLS_OS_FREERTOS
|
||||
u32 flag = 0;
|
||||
u32 length = size + 8;
|
||||
if(tls_get_isr_count() > 0)
|
||||
{
|
||||
extern void *pvPortMalloc( size_t xWantedSize );
|
||||
mem_re_addr = pvPortMalloc(length);
|
||||
flag = OS_MEM_FLAG;
|
||||
if (mem_re_addr)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if(mem_address != NULL)
|
||||
{
|
||||
memcpy((u8 *)(mem_re_addr + 2), (u8 *)mem_address, size);
|
||||
mem_free_debug(mem_address);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tls_os_sem_acquire(mem_sem, 0);
|
||||
cpu_sr = tls_os_set_critical();
|
||||
if (!mem_address)
|
||||
{
|
||||
mem_re_addr = (u32*)malloc(length);
|
||||
}else{
|
||||
mem_re_addr = (u32 *)realloc(((u32 *)mem_address-2), length);
|
||||
}
|
||||
}
|
||||
if(mem_re_addr)
|
||||
{
|
||||
*mem_re_addr = MEM_HEAD_FLAG;
|
||||
mem_re_addr++;
|
||||
*mem_re_addr = flag;
|
||||
mem_re_addr++;
|
||||
}
|
||||
if(tls_get_isr_count() == 0)
|
||||
{
|
||||
tls_os_release_critical(cpu_sr);
|
||||
tls_os_sem_release(mem_sem);
|
||||
}
|
||||
#else
|
||||
cpu_sr = tls_os_set_critical();
|
||||
mem_re_addr = realloc(mem_address, size);
|
||||
tls_os_release_critical(cpu_sr);
|
||||
#endif
|
||||
if(mem_re_addr == NULL)
|
||||
{
|
||||
printf("realloc error \n");
|
||||
}
|
||||
return mem_re_addr;
|
||||
}
|
||||
|
||||
void *mem_calloc_debug(u32 n, u32 size)
|
||||
{
|
||||
u32 cpu_sr = 0;
|
||||
u32 *buffer = NULL;
|
||||
u32 length = 0;
|
||||
#if TLS_OS_FREERTOS
|
||||
u32 flag = 0;
|
||||
length = n*size;
|
||||
length += 8;
|
||||
if(tls_get_isr_count() > 0)
|
||||
{
|
||||
extern void *pvPortMalloc( size_t xWantedSize );
|
||||
buffer = pvPortMalloc(length);
|
||||
flag = OS_MEM_FLAG;
|
||||
}
|
||||
else
|
||||
{
|
||||
tls_os_sem_acquire(mem_sem, 0);
|
||||
cpu_sr = tls_os_set_critical();
|
||||
buffer = (u32*)malloc(length);
|
||||
}
|
||||
if(buffer)
|
||||
{
|
||||
memset(buffer, 0, length);
|
||||
*buffer = MEM_HEAD_FLAG;
|
||||
buffer++;
|
||||
*buffer = flag;
|
||||
buffer++;
|
||||
}
|
||||
if(tls_get_isr_count() == 0)
|
||||
{
|
||||
tls_os_release_critical(cpu_sr);
|
||||
tls_os_sem_release(mem_sem);
|
||||
}
|
||||
#else //UCOSII
|
||||
cpu_sr = tls_os_set_critical();
|
||||
buffer = (u32*)calloc(n,size);
|
||||
tls_os_release_critical(cpu_sr);
|
||||
#endif
|
||||
// if(buffer == NULL)
|
||||
// {
|
||||
// printf("calloc error \n");
|
||||
// }
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function is used to get available memory
|
||||
*
|
||||
* @param[in] None
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note None.
|
||||
*/
|
||||
#if !defined(__CC_ARM)
|
||||
extern unsigned int __HeapLimit;
|
||||
#else
|
||||
extern unsigned int __heap_limit;
|
||||
#endif
|
||||
unsigned int tls_mem_get_avail_heapsize(void)
|
||||
{
|
||||
unsigned int heap_size;
|
||||
int *p = NULL;
|
||||
unsigned int cpu_sr = 0;
|
||||
|
||||
tls_os_sem_acquire(mem_sem, 0);
|
||||
cpu_sr = tls_os_set_critical();
|
||||
|
||||
p = malloc(4);
|
||||
if (p)
|
||||
{
|
||||
#if !defined(__CC_ARM)
|
||||
heap_size = (unsigned int)&__HeapLimit - (unsigned int)p;
|
||||
#else
|
||||
heap_size = (unsigned int)&__heap_limit - (unsigned int)p;
|
||||
#endif
|
||||
free(p);
|
||||
p = NULL;
|
||||
}else{
|
||||
heap_size = 0;
|
||||
}
|
||||
tls_os_release_critical(cpu_sr);
|
||||
tls_os_sem_release(mem_sem);
|
||||
|
||||
return heap_size;
|
||||
}
|
||||
|
||||
#endif /* WM_MEM_DEBUG */
|
||||
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
/**
|
||||
* @file wm_wl_mbox.c
|
||||
*
|
||||
* @brief mailbox (mbox) APIs
|
||||
*
|
||||
* @author dave
|
||||
*
|
||||
* Copyright (c) 2015 Winner Microelectronics Co., Ltd.
|
||||
*/
|
||||
#include "wm_mem.h"
|
||||
#include "wm_wl_mbox.h"
|
||||
#include "wm_wl_task.h"
|
||||
const void * const tls_null_pointer = (void *)0;
|
||||
|
||||
/**
|
||||
* @brief create a malibox
|
||||
*
|
||||
* @param[out] *mbox pointer to the mailbox
|
||||
* @param[in] size size of mailbox
|
||||
*
|
||||
* @retval TLS_OS_SUCCESS success
|
||||
* @retval TLS_OS_ERROR failed
|
||||
*
|
||||
* @note None
|
||||
*/
|
||||
s8 tls_mbox_new(tls_mbox_t *mbox, int size)
|
||||
{
|
||||
s8 err;
|
||||
tls_os_status_t status;
|
||||
|
||||
if (size == 0)
|
||||
size = 10;
|
||||
|
||||
status = tls_os_queue_create(mbox, size);
|
||||
if (status == TLS_OS_SUCCESS) {
|
||||
err = TLS_OS_SUCCESS;
|
||||
}
|
||||
else
|
||||
err = TLS_OS_ERROR;
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifndef tls_mbox_valid
|
||||
/**
|
||||
* @brief check if an mbox is valid/allocated
|
||||
*
|
||||
* @param[in] mbox pointer to the mailbox
|
||||
*
|
||||
* @retval 0 invalid
|
||||
* @retval 1 valid
|
||||
*
|
||||
* @note None
|
||||
*/
|
||||
int tls_mbox_valid(tls_mbox_t mbox)
|
||||
{
|
||||
if (mbox == NULL)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief sends a message to a mailbox
|
||||
*
|
||||
* @param[in] mbox pointer to the mailbox
|
||||
* @param[in] *msg pointer to the message to be post
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note None
|
||||
*/
|
||||
void tls_mbox_post(tls_mbox_t mbox, void *msg)
|
||||
{
|
||||
u8 err;
|
||||
u8 i=0;
|
||||
|
||||
if(msg == NULL )
|
||||
msg = (void*)tls_null_pointer;
|
||||
|
||||
/* try 10 times */
|
||||
while (i < 10)
|
||||
{
|
||||
err = tls_os_queue_send(mbox, msg, 0);
|
||||
if(err == TLS_OS_SUCCESS)
|
||||
break;
|
||||
i++;
|
||||
tls_os_time_delay(5);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief posts the "msg" to the mailbox.
|
||||
*
|
||||
* @param[in] mbox pointer to the mailbox
|
||||
* @param[in] *msg pointer to the message to be post
|
||||
*
|
||||
* @retval TLS_OS_SUCCESS success
|
||||
* @retval TLS_OS_ERROR failed
|
||||
*
|
||||
* @note this function have to block until the "msg" is really posted.
|
||||
*/
|
||||
s8 tls_mbox_trypost(tls_mbox_t mbox, void *msg)
|
||||
{
|
||||
u8 err;
|
||||
|
||||
if( msg == NULL )
|
||||
{
|
||||
msg = (void*)tls_null_pointer;
|
||||
}
|
||||
|
||||
err = tls_os_queue_send(mbox, msg, 0);
|
||||
if(err == TLS_OS_SUCCESS)
|
||||
return TLS_OS_SUCCESS;
|
||||
|
||||
return TLS_OS_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief waits for a message within the specified time
|
||||
*
|
||||
* @param[in] mbox pointer to the mailbox
|
||||
* @param[out] **msg pointer to the message to be received
|
||||
* @param[in] timeout the specified time
|
||||
*
|
||||
* @retval SYS_ARCH_TIMEOUT time out
|
||||
* @retval other time of elapsed
|
||||
*
|
||||
* @note None
|
||||
*/
|
||||
u32 tls_arch_mbox_fetch(tls_mbox_t mbox, void **msg, u32 timeout)
|
||||
{
|
||||
u8 err;
|
||||
u32 ucos_timeout = 0;
|
||||
u32 in_timeout = timeout * HZ / 1000;
|
||||
u32 tick_start, tick_stop, tick_elapsed;
|
||||
|
||||
if(timeout && in_timeout == 0)
|
||||
in_timeout = 1;
|
||||
|
||||
tick_start = tls_os_get_time();
|
||||
// *msg = OSQPend(mbox, in_timeout, &err);
|
||||
err = tls_os_queue_receive(mbox,msg,0,in_timeout);
|
||||
// if (err == OS_ERR_TIMEOUT ) {
|
||||
if (err != TLS_OS_SUCCESS ) {
|
||||
ucos_timeout = SYS_ARCH_TIMEOUT;
|
||||
return ucos_timeout;
|
||||
}
|
||||
tick_stop = tls_os_get_time();
|
||||
|
||||
// Take care of wrap-around.
|
||||
if( tick_stop >= tick_start )
|
||||
tick_elapsed = tick_stop - tick_start;
|
||||
else
|
||||
tick_elapsed = 0xFFFFFFFF - tick_start + tick_stop ;
|
||||
|
||||
|
||||
return tick_elapsed * 1000/HZ;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
#include "wm_mem.h"
|
||||
#include "wm_wl_timers.h"
|
||||
#include "wm_wl_task.h"
|
||||
#include <string.h>
|
||||
|
||||
static tls_mbox_t task_mbox[TLS_MBOX_ALL_COUNT];
|
||||
struct task_msg wl_msg[TLS_MSG_ALL_COUONT];
|
||||
//#define TLS_MSG_ID_TX_MGMT_CMPLT 0
|
||||
//#define TLS_MSG_ID_MLME_TASK 1
|
||||
|
||||
static void
|
||||
task_thread(void *arg)
|
||||
{
|
||||
struct task_msg *msg;
|
||||
start_routine fun;
|
||||
void * argu;
|
||||
struct task_parameter *task_param = (struct task_parameter *)arg;
|
||||
|
||||
while (1) { /* MAIN Loop */
|
||||
/* wait for a message, timeouts are processed while waiting */
|
||||
tls_timeouts_mbox_fetch_p(task_param->timeo_id, task_mbox[task_param->mbox_id], (void **)&msg);
|
||||
switch (msg->type) {
|
||||
case TASK_MSG_CALLBACK:
|
||||
msg->msg.cb.function(msg->msg.cb.ctx);
|
||||
tls_mem_free(msg);
|
||||
break;
|
||||
case TASK_MSG_CALLBACK_STATIC:
|
||||
fun = msg->msg.cbs.function;
|
||||
argu = msg->msg.cbs.ctx;
|
||||
msg->msg.cbs.cnt--;
|
||||
fun(argu);
|
||||
break;
|
||||
case TASK_MSG_TIMEOUT:
|
||||
tls_timeout_p(task_param->timeo_id, msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg);
|
||||
tls_mem_free(msg);
|
||||
break;
|
||||
case TASK_MSG_UNTIMEOUT:
|
||||
tls_untimeout_p(task_param->timeo_id, msg->msg.tmo.h, msg->msg.tmo.arg);
|
||||
tls_mem_free(msg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s8 tls_wl_task_run(struct task_parameter *task_param)
|
||||
{
|
||||
if(tls_mbox_new(&task_mbox[task_param->mbox_id], task_param->mbox_size) != TLS_OS_SUCCESS) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
tls_os_task_create(NULL, "WL_TSK",
|
||||
//tls_os_task_create(NULL, task_param->name,
|
||||
task_thread,
|
||||
(void *)task_param,
|
||||
(void *)(task_param->stk_start),
|
||||
task_param->stk_size * sizeof(u32),
|
||||
TLS_TASK_START_PRIO+task_param->task_id,
|
||||
0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
s8
|
||||
tls_wl_task_callback_static(struct task_parameter *task_param, start_routine function, void *ctx, u8 block, u8 msg_id)
|
||||
{
|
||||
struct task_msg *msg = &wl_msg[msg_id];
|
||||
|
||||
if (msg->msg.cbs.cnt > 0)
|
||||
return TLS_OS_ERROR;
|
||||
|
||||
if (tls_mbox_valid(task_mbox[task_param->mbox_id])) {
|
||||
msg->type = TASK_MSG_CALLBACK_STATIC;
|
||||
msg->msg.cbs.function = function;
|
||||
msg->msg.cbs.ctx = ctx;
|
||||
if (block) {
|
||||
tls_mbox_post(task_mbox[task_param->mbox_id], (void *)msg);
|
||||
}
|
||||
else {
|
||||
if (tls_mbox_trypost(task_mbox[task_param->mbox_id], (void *)msg) != TLS_OS_SUCCESS)
|
||||
return TLS_OS_ERROR;
|
||||
}
|
||||
msg->msg.cbs.cnt++;
|
||||
return TLS_OS_SUCCESS;
|
||||
}
|
||||
return TLS_OS_ERROR;
|
||||
}
|
||||
|
||||
s8
|
||||
tls_wl_task_callback(struct task_parameter *task_param, start_routine function, void *ctx, u8 block)
|
||||
{
|
||||
struct task_msg *msg;
|
||||
|
||||
if (tls_mbox_valid(task_mbox[task_param->mbox_id])) {
|
||||
msg = (struct task_msg *)tls_mem_alloc(sizeof(struct task_msg));
|
||||
if (msg == NULL) {
|
||||
return TLS_OS_ERROR;
|
||||
}
|
||||
|
||||
msg->type = TASK_MSG_CALLBACK;
|
||||
msg->msg.cb.function = function;
|
||||
msg->msg.cb.ctx = ctx;
|
||||
if (block) {
|
||||
tls_mbox_post(task_mbox[task_param->mbox_id], msg);
|
||||
} else {
|
||||
if (tls_mbox_trypost(task_mbox[task_param->mbox_id], msg) != TLS_OS_SUCCESS) {
|
||||
//printf("tls_mbox_trypost error.\n");
|
||||
tls_mem_free(msg);
|
||||
return TLS_OS_ERROR;
|
||||
}
|
||||
}
|
||||
return TLS_OS_SUCCESS;
|
||||
}
|
||||
return TLS_OS_ERROR;
|
||||
}
|
||||
|
||||
s8
|
||||
tls_wl_task_add_timeout(struct task_parameter *task_param, u32 msecs, tls_timeout_handler h, void *arg)
|
||||
{
|
||||
struct task_msg *msg;
|
||||
|
||||
if (tls_mbox_valid(task_mbox[task_param->mbox_id])) {
|
||||
msg = (struct task_msg *)tls_mem_alloc(sizeof(struct task_msg));
|
||||
if (msg == NULL) {
|
||||
return TLS_OS_ERROR;
|
||||
}
|
||||
|
||||
msg->type = TASK_MSG_TIMEOUT;
|
||||
msg->msg.tmo.msecs = msecs;
|
||||
msg->msg.tmo.h = h;
|
||||
msg->msg.tmo.arg = arg;
|
||||
tls_mbox_post(task_mbox[task_param->mbox_id], msg);
|
||||
return TLS_OS_SUCCESS;
|
||||
}
|
||||
return TLS_OS_ERROR;
|
||||
}
|
||||
|
||||
s8
|
||||
tls_wl_task_untimeout(struct task_parameter *task_param, tls_timeout_handler h, void *arg)
|
||||
{
|
||||
struct task_msg *msg;
|
||||
|
||||
if (tls_mbox_valid(task_mbox[task_param->mbox_id])) {
|
||||
msg = (struct task_msg *)tls_mem_alloc(sizeof(struct task_msg));
|
||||
if (msg == NULL) {
|
||||
return TLS_OS_ERROR;
|
||||
}
|
||||
|
||||
msg->type = TASK_MSG_UNTIMEOUT;
|
||||
msg->msg.tmo.h = h;
|
||||
msg->msg.tmo.arg = arg;
|
||||
tls_mbox_post(task_mbox[task_param->mbox_id], msg);
|
||||
return TLS_OS_SUCCESS;
|
||||
}
|
||||
return TLS_OS_ERROR;
|
||||
}
|
||||
|
||||
s8
|
||||
tls_wl_task_init(void)
|
||||
{
|
||||
memset(wl_msg, 0, sizeof(struct task_msg));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
#include <string.h>
|
||||
#include "wm_mem.h"
|
||||
#include "wm_wl_timers.h"
|
||||
#include "wm_wl_task.h"
|
||||
|
||||
struct tls_timeo {
|
||||
struct tls_timeo *next;
|
||||
u32 time;
|
||||
tls_timeout_handler h;
|
||||
void *arg;
|
||||
};
|
||||
|
||||
/** The one and only timeout list */
|
||||
struct tls_timeo *next_timeout[TLS_TIMEO_ALL_COUONT];
|
||||
|
||||
/**
|
||||
* @brief Wait (forever) for a message to arrive in an mbox.
|
||||
* While waiting, timeouts are processed
|
||||
*
|
||||
* @param[in] timeo_assigned timer NO. by assigned
|
||||
* @param[in] mbox the mbox to fetch the message from
|
||||
* @param[out] **msg the place to store the message
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note None
|
||||
*/
|
||||
void tls_timeouts_mbox_fetch_p(u8 timeo_assigned, tls_mbox_t mbox, void **msg)
|
||||
{
|
||||
u32 time_needed;
|
||||
struct tls_timeo *tmptimeout;
|
||||
tls_timeout_handler handler;
|
||||
void *arg;
|
||||
|
||||
struct tls_timeo **timeo = &next_timeout[timeo_assigned];
|
||||
|
||||
again:
|
||||
if (!(*timeo)) {
|
||||
time_needed = tls_arch_mbox_fetch(mbox, msg, 0);
|
||||
} else {
|
||||
if ((*timeo)->time > 0) {
|
||||
time_needed = tls_arch_mbox_fetch(mbox, msg, (*timeo)->time);
|
||||
} else {
|
||||
time_needed = SYS_ARCH_TIMEOUT;
|
||||
}
|
||||
|
||||
if (time_needed == SYS_ARCH_TIMEOUT) {
|
||||
/* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message
|
||||
could be fetched. We should now call the timeout handler and
|
||||
deallocate the memory allocated for the timeout. */
|
||||
tmptimeout = *timeo;
|
||||
*timeo = tmptimeout->next;
|
||||
handler = tmptimeout->h;
|
||||
arg = tmptimeout->arg;
|
||||
tls_mem_free(tmptimeout);
|
||||
if (handler != NULL) {
|
||||
handler(arg);
|
||||
}
|
||||
|
||||
/* We try again to fetch a message from the mbox. */
|
||||
goto again;
|
||||
} else {
|
||||
/* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout
|
||||
occured. The time variable is set to the number of
|
||||
milliseconds we waited for the message. */
|
||||
if (time_needed < (*timeo)->time) {
|
||||
(*timeo)->time -= time_needed;
|
||||
} else {
|
||||
(*timeo)->time = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief create a one-shot timer (aka timeout)
|
||||
*
|
||||
* @param[in] timeo_assigned timer NO. by assigned
|
||||
* @param[in] msecs time in milliseconds after that the timer should expire
|
||||
* @param[in] handler callback function that would be called by the timeout
|
||||
* @param[in] *arg callback argument that would be passed to handler
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note while waiting for a message using sys_timeouts_mbox_fetch()
|
||||
*/
|
||||
void tls_timeout_p(u8 timeo_assigned, u32 msecs, tls_timeout_handler handler, void *arg)
|
||||
{
|
||||
struct tls_timeo *timeout, *t;
|
||||
struct tls_timeo **timeo = &next_timeout[timeo_assigned];
|
||||
|
||||
timeout = (struct tls_timeo *)tls_mem_alloc(sizeof(struct tls_timeo));
|
||||
if (timeout == NULL) {
|
||||
return;
|
||||
}
|
||||
timeout->next = NULL;
|
||||
timeout->h = handler;
|
||||
timeout->arg = arg;
|
||||
timeout->time = msecs;
|
||||
|
||||
if (*timeo == NULL) {
|
||||
*timeo = timeout;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((*timeo)->time > msecs) {
|
||||
(*timeo)->time -= msecs;
|
||||
timeout->next = *timeo;
|
||||
*timeo = timeout;
|
||||
} else {
|
||||
for(t = *timeo; t != NULL; t = t->next) {
|
||||
timeout->time -= t->time;
|
||||
if (t->next == NULL || t->next->time > timeout->time) {
|
||||
if (t->next != NULL) {
|
||||
t->next->time -= timeout->time;
|
||||
}
|
||||
timeout->next = t->next;
|
||||
t->next = timeout;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Go through timeout list (for this task only) and remove the first
|
||||
* matching entry, even though the timeout has not triggered yet
|
||||
*
|
||||
* @param[in] timeo_assigned timer NO. by assigned
|
||||
* @param[in] handler callback function that would be called by the timeout
|
||||
* @param[in] *arg callback argument that would be passed to handler
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note None
|
||||
*/
|
||||
void tls_untimeout_p(u8 timeo_assigned, tls_timeout_handler handler, void *arg)
|
||||
{
|
||||
struct tls_timeo *prev_t, *t;
|
||||
struct tls_timeo **timeo = &next_timeout[timeo_assigned];
|
||||
|
||||
if (*timeo == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (t = *timeo, prev_t = NULL; t != NULL; prev_t = t, t = t->next) {
|
||||
if ((t->h == handler) && (t->arg == arg)) {
|
||||
/* We have a match */
|
||||
/* Unlink from previous in list */
|
||||
if (prev_t == NULL) {
|
||||
*timeo = t->next;
|
||||
} else {
|
||||
prev_t->next = t->next;
|
||||
}
|
||||
/* If not the last one, add time of this one back to next */
|
||||
if (t->next != NULL) {
|
||||
t->next->time += t->time;
|
||||
}
|
||||
tls_mem_free(t);
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief timer initialized
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note None
|
||||
*/
|
||||
s8 tls_wl_timer_init(void)
|
||||
{
|
||||
memset(next_timeout, 0, sizeof(struct tls_timeo *) * TLS_TIMEO_ALL_COUONT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
#ifndef WM_COMMON
|
||||
#define WM_COMMON
|
||||
#include "../Platform/Common/fwup/wm_fwup.c"
|
||||
#include "../Platform/Common/task/wm_wl_mbox.c"
|
||||
#include "../Platform/Common/task/wm_wl_task.c"
|
||||
#include "../Platform/Common/task/wm_wl_timers.c"
|
||||
#include "../Platform/Common/utils/utils.c"
|
||||
#include "../Platform/Common/crypto/wm_crypto_hard.c"
|
||||
#include "../Platform/Common/mem/wm_mem.c"
|
||||
#include "../Platform/Common/Params/wm_param.c"
|
||||
#endif //WM_COMMON
|
||||
Reference in New Issue
Block a user