打包keil_MDK的工程

This commit is contained in:
不吃油炸鸡
2026-02-26 11:25:38 +08:00
parent ef38c0f19f
commit aae7ce5938
1200 changed files with 0 additions and 832317 deletions

View File

@@ -1,273 +0,0 @@
/**
* @file lv_malloc_core.c
*/
/*********************
* INCLUDES
*********************/
#include "../lv_mem.h"
#if LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN
#include "lv_tlsf.h"
#include "../lv_string.h"
#include "../../misc/lv_assert.h"
#include "../../misc/lv_log.h"
#include "../../misc/lv_ll.h"
#include "../../misc/lv_math.h"
#include "../../osal/lv_os.h"
#include "../../core/lv_global.h"
#ifdef LV_MEM_POOL_INCLUDE
#include LV_MEM_POOL_INCLUDE
#endif
/*********************
* DEFINES
*********************/
/*memset the allocated memories to 0xaa and freed memories to 0xbb (just for testing purposes)*/
#ifndef LV_MEM_ADD_JUNK
#define LV_MEM_ADD_JUNK 0
#endif
#ifdef LV_ARCH_64
#define MEM_UNIT uint64_t
#define ALIGN_MASK 0x7
#else
#define MEM_UNIT uint32_t
#define ALIGN_MASK 0x3
#endif
#define state LV_GLOBAL_DEFAULT()->tlsf_state
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static void lv_mem_walker(void * ptr, size_t size, int used, void * user);
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
#if LV_USE_LOG && LV_LOG_TRACE_MEM
#define LV_TRACE_MEM(...) LV_LOG_TRACE(__VA_ARGS__)
#else
#define LV_TRACE_MEM(...)
#endif
#define _COPY(d, s) *d = *s; d++; s++;
#define _SET(d, v) *d = v; d++;
#define _REPEAT8(expr) expr expr expr expr expr expr expr expr
/**********************
* GLOBAL FUNCTIONS
**********************/
void lv_mem_init(void)
{
#if LV_USE_OS
lv_mutex_init(&state.mutex);
#endif
#if LV_MEM_ADR == 0
#ifdef LV_MEM_POOL_ALLOC
state.tlsf = lv_tlsf_create_with_pool((void *)LV_MEM_POOL_ALLOC(LV_MEM_SIZE), LV_MEM_SIZE);
#else
/*Allocate a large array to store the dynamically allocated data*/
static LV_ATTRIBUTE_LARGE_RAM_ARRAY MEM_UNIT work_mem_int[LV_MEM_SIZE / sizeof(MEM_UNIT)];
state.tlsf = lv_tlsf_create_with_pool((void *)work_mem_int, LV_MEM_SIZE);
#endif
#else
state.tlsf = lv_tlsf_create_with_pool((void *)LV_MEM_ADR, LV_MEM_SIZE);
#endif
lv_ll_init(&state.pool_ll, sizeof(lv_pool_t));
/*Record the first pool*/
lv_pool_t * pool_p = lv_ll_ins_tail(&state.pool_ll);
LV_ASSERT_MALLOC(pool_p);
*pool_p = lv_tlsf_get_pool(state.tlsf);
#if LV_MEM_ADD_JUNK
LV_LOG_WARN("LV_MEM_ADD_JUNK is enabled which makes LVGL much slower");
#endif
}
void lv_mem_deinit(void)
{
lv_ll_clear(&state.pool_ll);
lv_tlsf_destroy(state.tlsf);
#if LV_USE_OS
lv_mutex_delete(&state.mutex);
#endif
}
lv_mem_pool_t lv_mem_add_pool(void * mem, size_t bytes)
{
lv_mem_pool_t new_pool = lv_tlsf_add_pool(state.tlsf, mem, bytes);
if(!new_pool) {
LV_LOG_WARN("failed to add memory pool, address: %p, size: %zu", mem, bytes);
return NULL;
}
lv_pool_t * pool_p = lv_ll_ins_tail(&state.pool_ll);
LV_ASSERT_MALLOC(pool_p);
*pool_p = new_pool;
return new_pool;
}
void lv_mem_remove_pool(lv_mem_pool_t pool)
{
lv_pool_t * pool_p;
LV_LL_READ(&state.pool_ll, pool_p) {
if(*pool_p == pool) {
lv_ll_remove(&state.pool_ll, pool_p);
lv_free(pool_p);
lv_tlsf_remove_pool(state.tlsf, pool);
return;
}
}
LV_LOG_WARN("invalid pool: %p", pool);
}
void * lv_malloc_core(size_t size)
{
#if LV_USE_OS
lv_mutex_lock(&state.mutex);
#endif
void * p = lv_tlsf_malloc(state.tlsf, size);
if(p) {
state.cur_used += lv_tlsf_block_size(p);
state.max_used = LV_MAX(state.cur_used, state.max_used);
}
#if LV_USE_OS
lv_mutex_unlock(&state.mutex);
#endif
return p;
}
void * lv_realloc_core(void * p, size_t new_size)
{
#if LV_USE_OS
lv_mutex_lock(&state.mutex);
#endif
size_t old_size = lv_tlsf_block_size(p);
void * p_new = lv_tlsf_realloc(state.tlsf, p, new_size);
if(p_new) {
state.cur_used -= old_size;
state.cur_used += lv_tlsf_block_size(p_new);
state.max_used = LV_MAX(state.cur_used, state.max_used);
}
#if LV_USE_OS
lv_mutex_unlock(&state.mutex);
#endif
return p_new;
}
void lv_free_core(void * p)
{
#if LV_USE_OS
lv_mutex_lock(&state.mutex);
#endif
#if LV_MEM_ADD_JUNK
lv_memset(p, 0xbb, lv_tlsf_block_size(data));
#endif
size_t size = lv_tlsf_block_size(p);
lv_tlsf_free(state.tlsf, p);
if(state.cur_used > size) state.cur_used -= size;
else state.cur_used = 0;
#if LV_USE_OS
lv_mutex_unlock(&state.mutex);
#endif
}
void lv_mem_monitor_core(lv_mem_monitor_t * mon_p)
{
/*Init the data*/
lv_memzero(mon_p, sizeof(lv_mem_monitor_t));
LV_TRACE_MEM("begin");
lv_pool_t * pool_p;
LV_LL_READ(&state.pool_ll, pool_p) {
lv_tlsf_walk_pool(*pool_p, lv_mem_walker, mon_p);
}
mon_p->used_pct = 100 - (uint64_t)100U * mon_p->free_size / mon_p->total_size;
if(mon_p->free_size > 0) {
mon_p->frag_pct = (uint64_t)mon_p->free_biggest_size * 100U / mon_p->free_size;
mon_p->frag_pct = 100 - mon_p->frag_pct;
}
else {
mon_p->frag_pct = 0; /*no fragmentation if all the RAM is used*/
}
mon_p->max_used = state.max_used;
LV_TRACE_MEM("finished");
}
lv_result_t lv_mem_test_core(void)
{
#if LV_USE_OS
lv_mutex_lock(&state.mutex);
#endif
if(lv_tlsf_check(state.tlsf)) {
LV_LOG_WARN("failed");
#if LV_USE_OS
lv_mutex_unlock(&state.mutex);
#endif
return LV_RESULT_INVALID;
}
lv_pool_t * pool_p;
LV_LL_READ(&state.pool_ll, pool_p) {
if(lv_tlsf_check_pool(*pool_p)) {
LV_LOG_WARN("pool failed");
#if LV_USE_OS
lv_mutex_unlock(&state.mutex);
#endif
return LV_RESULT_INVALID;
}
}
LV_TRACE_MEM("passed");
#if LV_USE_OS
lv_mutex_unlock(&state.mutex);
#endif
return LV_RESULT_OK;
}
/**********************
* STATIC FUNCTIONS
**********************/
static void lv_mem_walker(void * ptr, size_t size, int used, void * user)
{
LV_UNUSED(ptr);
lv_mem_monitor_t * mon_p = user;
mon_p->total_size += size;
if(used) {
mon_p->used_cnt++;
}
else {
mon_p->free_cnt++;
mon_p->free_size += size;
if(size > mon_p->free_biggest_size)
mon_p->free_biggest_size = size;
}
}
#endif /*LV_STDLIB_BUILTIN*/

View File

@@ -1,886 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
// \author (c) Marco Paland (info@paland.com)
// 2014-2019, PALANDesign Hannover, Germany
//
// \license The MIT License (MIT)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// \brief Tiny printf, sprintf and (v)snprintf implementation, optimized for speed on
// embedded systems with a very limited resources. These routines are thread
// safe and reentrant!
// Use this instead of the bloated standard/newlib printf cause these use
// malloc for printf (and may not be thread safe).
//
///////////////////////////////////////////////////////////////////////////////
/*Original repository: https://github.com/mpaland/printf*/
#include "../../lv_conf_internal.h"
#if LV_USE_STDLIB_SPRINTF == LV_STDLIB_BUILTIN
#include "../lv_sprintf.h"
#include "../../misc/lv_types.h"
#define PRINTF_DISABLE_SUPPORT_FLOAT (!LV_USE_FLOAT)
// 'ntoa' conversion buffer size, this must be big enough to hold one converted
// numeric number including padded zeros (dynamically created on stack)
// default: 32 byte
#ifndef PRINTF_NTOA_BUFFER_SIZE
#define PRINTF_NTOA_BUFFER_SIZE 32U
#endif
// 'ftoa' conversion buffer size, this must be big enough to hold one converted
// float number including padded zeros (dynamically created on stack)
// default: 32 byte
#ifndef PRINTF_FTOA_BUFFER_SIZE
#define PRINTF_FTOA_BUFFER_SIZE 32U
#endif
// support for the floating point type (%f)
// default: activated
#if !PRINTF_DISABLE_SUPPORT_FLOAT
#define PRINTF_SUPPORT_FLOAT
#endif
// support for exponential floating point notation (%e/%g)
// default: activated
#ifndef PRINTF_DISABLE_SUPPORT_EXPONENTIAL
#define PRINTF_SUPPORT_EXPONENTIAL
#endif
// define the default floating point precision
// default: 6 digits
#ifndef PRINTF_DEFAULT_FLOAT_PRECISION
#define PRINTF_DEFAULT_FLOAT_PRECISION 6U
#endif
// define the largest float suitable to print with %f
// default: 1e9
#ifndef PRINTF_MAX_FLOAT
#define PRINTF_MAX_FLOAT 1e9
#endif
// support for the long long types (%llu or %p)
// default: activated
#ifndef PRINTF_DISABLE_SUPPORT_LONG_LONG
#define PRINTF_SUPPORT_LONG_LONG
#endif
// support for the ptrdiff_t type (%t)
// ptrdiff_t is normally defined in <stddef.h> as long or long long type
// default: activated
#ifndef PRINTF_DISABLE_SUPPORT_PTRDIFF_T
#define PRINTF_SUPPORT_PTRDIFF_T
#endif
///////////////////////////////////////////////////////////////////////////////
// internal flag definitions
#define FLAGS_ZEROPAD (1U << 0U)
#define FLAGS_LEFT (1U << 1U)
#define FLAGS_PLUS (1U << 2U)
#define FLAGS_SPACE (1U << 3U)
#define FLAGS_HASH (1U << 4U)
#define FLAGS_UPPERCASE (1U << 5U)
#define FLAGS_CHAR (1U << 6U)
#define FLAGS_SHORT (1U << 7U)
#define FLAGS_LONG (1U << 8U)
#define FLAGS_LONG_LONG (1U << 9U)
#define FLAGS_PRECISION (1U << 10U)
#define FLAGS_ADAPT_EXP (1U << 11U)
typedef struct {
const char * fmt;
va_list * va;
} lv_vaformat_t;
// import float.h for DBL_MAX
#if defined(PRINTF_SUPPORT_FLOAT)
#include <float.h>
#endif
// output function type
typedef void (*out_fct_type)(char character, void * buffer, size_t idx, size_t maxlen);
// wrapper (used as buffer) for output function type
typedef struct {
void (*fct)(char character, void * arg);
void * arg;
} out_fct_wrap_type;
// internal buffer output
static inline void _out_buffer(char character, void * buffer, size_t idx, size_t maxlen)
{
if(idx < maxlen) {
((char *)buffer)[idx] = character;
}
}
// internal null output
static inline void _out_null(char character, void * buffer, size_t idx, size_t maxlen)
{
LV_UNUSED(character);
LV_UNUSED(buffer);
LV_UNUSED(idx);
LV_UNUSED(maxlen);
}
// internal secure strlen
// \return The length of the string (excluding the terminating 0) limited by 'maxsize'
static inline unsigned int _strnlen_s(const char * str, size_t maxsize)
{
const char * s;
for(s = str; *s && maxsize--; ++s);
return (unsigned int)(s - str);
}
// internal test if char is a digit (0-9)
// \return true if char is a digit
static inline bool _is_digit(char ch)
{
return (ch >= '0') && (ch <= '9');
}
// internal ASCII string to unsigned int conversion
static unsigned int _atoi(const char ** str)
{
unsigned int i = 0U;
while(_is_digit(**str)) {
i = i * 10U + (unsigned int)(*((*str)++) - '0');
}
return i;
}
// output the specified string in reverse, taking care of any zero-padding
static size_t _out_rev(out_fct_type out, char * buffer, size_t idx, size_t maxlen, const char * buf, size_t len,
unsigned int width, unsigned int flags)
{
const size_t start_idx = idx;
// pad spaces up to given width
if(!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) {
size_t i;
for(i = len; i < width; i++) {
out(' ', buffer, idx++, maxlen);
}
}
// reverse string
while(len) {
out(buf[--len], buffer, idx++, maxlen);
}
// append pad spaces up to given width
if(flags & FLAGS_LEFT) {
while(idx - start_idx < width) {
out(' ', buffer, idx++, maxlen);
}
}
return idx;
}
// internal itoa format
static size_t _ntoa_format(out_fct_type out, char * buffer, size_t idx, size_t maxlen, char * buf, size_t len,
bool negative, unsigned int base, unsigned int prec, unsigned int width, unsigned int flags)
{
// pad leading zeros
if(!(flags & FLAGS_LEFT)) {
if(width && (flags & FLAGS_ZEROPAD) && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) {
width--;
}
while((len < prec) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = '0';
}
while((flags & FLAGS_ZEROPAD) && (len < width) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = '0';
}
}
// handle hash
if(flags & FLAGS_HASH) {
if(!(flags & FLAGS_PRECISION) && len && ((len == prec) || (len == width))) {
len--;
if(len && (base == 16U)) {
len--;
}
}
if((base == 16U) && !(flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = 'x';
}
else if((base == 16U) && (flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = 'X';
}
else if((base == 2U) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = 'b';
}
if(len < PRINTF_NTOA_BUFFER_SIZE) {
buf[len++] = '0';
}
}
if(len < PRINTF_NTOA_BUFFER_SIZE) {
if(negative) {
buf[len++] = '-';
}
else if(flags & FLAGS_PLUS) {
buf[len++] = '+'; // ignore the space if the '+' exists
}
else if(flags & FLAGS_SPACE) {
buf[len++] = ' ';
}
}
return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags);
}
// internal itoa for 'long' type
static size_t _ntoa_long(out_fct_type out, char * buffer, size_t idx, size_t maxlen, unsigned long value, bool negative,
unsigned long base, unsigned int prec, unsigned int width, unsigned int flags)
{
char buf[PRINTF_NTOA_BUFFER_SIZE];
size_t len = 0U;
// no hash for 0 values
if(!value) {
flags &= ~FLAGS_HASH;
}
// write if precision != 0 and value is != 0
if(!(flags & FLAGS_PRECISION) || value) {
do {
const char digit = (char)(value % base);
buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10;
value /= base;
} while(value && (len < PRINTF_NTOA_BUFFER_SIZE));
}
return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags);
}
// internal itoa for 'long long' type
#if defined(PRINTF_SUPPORT_LONG_LONG)
static size_t _ntoa_long_long(out_fct_type out, char * buffer, size_t idx, size_t maxlen, unsigned long long value,
bool negative, unsigned long long base, unsigned int prec, unsigned int width, unsigned int flags)
{
char buf[PRINTF_NTOA_BUFFER_SIZE];
size_t len = 0U;
// no hash for 0 values
if(!value) {
flags &= ~FLAGS_HASH;
}
// write if precision != 0 and value is != 0
if(!(flags & FLAGS_PRECISION) || value) {
do {
const char digit = (char)(value % base);
buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10;
value /= base;
} while(value && (len < PRINTF_NTOA_BUFFER_SIZE));
}
return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags);
}
#endif // PRINTF_SUPPORT_LONG_LONG
#if defined(PRINTF_SUPPORT_FLOAT)
#if defined(PRINTF_SUPPORT_EXPONENTIAL)
// forward declaration so that _ftoa can switch to exp notation for values > PRINTF_MAX_FLOAT
static size_t _etoa(out_fct_type out, char * buffer, size_t idx, size_t maxlen, double value, unsigned int prec,
unsigned int width, unsigned int flags);
#endif
// internal ftoa for fixed decimal floating point
static size_t _ftoa(out_fct_type out, char * buffer, size_t idx, size_t maxlen, double value, unsigned int prec,
unsigned int width, unsigned int flags)
{
char buf[PRINTF_FTOA_BUFFER_SIZE];
size_t len = 0U;
double diff = 0.0;
// powers of 10
static const double pow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
// test for special values
if(value != value)
return _out_rev(out, buffer, idx, maxlen, "nan", 3, width, flags);
if(value < -DBL_MAX)
return _out_rev(out, buffer, idx, maxlen, "fni-", 4, width, flags);
if(value > DBL_MAX)
return _out_rev(out, buffer, idx, maxlen, (flags & FLAGS_PLUS) ? "fni+" : "fni", (flags & FLAGS_PLUS) ? 4U : 3U, width,
flags);
// test for very large values
// standard printf behavior is to print EVERY whole number digit -- which could be 100s of characters overflowing your buffers == bad
if((value > PRINTF_MAX_FLOAT) || (value < -PRINTF_MAX_FLOAT)) {
#if defined(PRINTF_SUPPORT_EXPONENTIAL)
return _etoa(out, buffer, idx, maxlen, value, prec, width, flags);
#else
return 0U;
#endif
}
// test for negative
bool negative = false;
if(value < 0) {
negative = true;
value = 0 - value;
}
// set default precision, if not set explicitly
if(!(flags & FLAGS_PRECISION)) {
prec = PRINTF_DEFAULT_FLOAT_PRECISION;
}
// limit precision to 9, cause a prec >= 10 can lead to overflow errors
while((len < PRINTF_FTOA_BUFFER_SIZE) && (prec > 9U)) {
buf[len++] = '0';
prec--;
}
int whole = (int)value;
double tmp = (value - whole) * pow10[prec];
unsigned long frac = (unsigned long)tmp;
diff = tmp - frac;
if(diff > 0.5) {
++frac;
// handle rollover, e.g. case 0.99 with prec 1 is 1.0
if(frac >= pow10[prec]) {
frac = 0;
++whole;
}
}
else if(diff < 0.5) {
}
else if((frac == 0U) || (frac & 1U)) {
// if halfway, round up if odd OR if last digit is 0
++frac;
}
if(prec == 0U) {
diff = value - (double)whole;
if((!(diff < 0.5) || (diff > 0.5)) && (whole & 1)) {
// exactly 0.5 and ODD, then round up
// 1.5 -> 2, but 2.5 -> 2
++whole;
}
}
else {
unsigned int count = prec;
// now do fractional part, as an unsigned number
while(len < PRINTF_FTOA_BUFFER_SIZE) {
--count;
buf[len++] = (char)(48U + (frac % 10U));
if(!(frac /= 10U)) {
break;
}
}
// add extra 0s
while((len < PRINTF_FTOA_BUFFER_SIZE) && (count-- > 0U)) {
buf[len++] = '0';
}
if(len < PRINTF_FTOA_BUFFER_SIZE) {
// add decimal
buf[len++] = '.';
}
}
// do whole part, number is reversed
while(len < PRINTF_FTOA_BUFFER_SIZE) {
buf[len++] = (char)(48 + (whole % 10));
if(!(whole /= 10)) {
break;
}
}
// pad leading zeros
if(!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD)) {
if(width && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) {
width--;
}
while((len < width) && (len < PRINTF_FTOA_BUFFER_SIZE)) {
buf[len++] = '0';
}
}
if(len < PRINTF_FTOA_BUFFER_SIZE) {
if(negative) {
buf[len++] = '-';
}
else if(flags & FLAGS_PLUS) {
buf[len++] = '+'; // ignore the space if the '+' exists
}
else if(flags & FLAGS_SPACE) {
buf[len++] = ' ';
}
}
return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags);
}
#if defined(PRINTF_SUPPORT_EXPONENTIAL)
// internal ftoa variant for exponential floating-point type, contributed by Martijn Jasperse <m.jasperse@gmail.com>
static size_t _etoa(out_fct_type out, char * buffer, size_t idx, size_t maxlen, double value, unsigned int prec,
unsigned int width, unsigned int flags)
{
// check for NaN and special values
if((value != value) || (value > DBL_MAX) || (value < -DBL_MAX)) {
return _ftoa(out, buffer, idx, maxlen, value, prec, width, flags);
}
// determine the sign
const bool negative = value < 0;
if(negative) {
value = -value;
}
// default precision
if(!(flags & FLAGS_PRECISION)) {
prec = PRINTF_DEFAULT_FLOAT_PRECISION;
}
// determine the decimal exponent
// based on the algorithm by David Gay (https://www.ampl.com/netlib/fp/dtoa.c)
union {
uint64_t U;
double F;
} conv;
conv.F = value;
int exp2 = (int)((conv.U >> 52U) & 0x07FFU) - 1023; // effectively log2
conv.U = (conv.U & ((1ULL << 52U) - 1U)) | (1023ULL << 52U); // drop the exponent so conv.F is now in [1,2)
// now approximate log10 from the log2 integer part and an expansion of ln around 1.5
int expval = (int)(0.1760912590558 + exp2 * 0.301029995663981 + (conv.F - 1.5) * 0.289529654602168);
// now we want to compute 10^expval but we want to be sure it won't overflow
exp2 = (int)(expval * 3.321928094887362 + 0.5);
const double z = expval * 2.302585092994046 - exp2 * 0.6931471805599453;
const double z2 = z * z;
conv.U = (uint64_t)(exp2 + 1023) << 52U;
// compute exp(z) using continued fractions, see https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex
conv.F *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14)))));
// correct for rounding errors
if(value < conv.F) {
expval--;
conv.F /= 10;
}
// the exponent format is "%+03d" and largest value is "307", so set aside 4-5 characters
unsigned int minwidth = ((expval < 100) && (expval > -100)) ? 4U : 5U;
// in "%g" mode, "prec" is the number of *significant figures* not decimals
if(flags & FLAGS_ADAPT_EXP) {
// do we want to fall-back to "%f" mode?
if((value >= 1e-4) && (value < 1e6)) {
if((int)prec > expval) {
prec = (unsigned)((int)prec - expval - 1);
}
else {
prec = 0;
}
flags |= FLAGS_PRECISION; // make sure _ftoa respects precision
// no characters in exponent
minwidth = 0U;
expval = 0;
}
else {
// we use one sigfig for the whole part
if((prec > 0) && (flags & FLAGS_PRECISION)) {
--prec;
}
}
}
// will everything fit?
unsigned int fwidth = width;
if(width > minwidth) {
// we didn't fall-back so subtract the characters required for the exponent
fwidth -= minwidth;
}
else {
// not enough characters, so go back to default sizing
fwidth = 0U;
}
if((flags & FLAGS_LEFT) && minwidth) {
// if we're padding on the right, DON'T pad the floating part
fwidth = 0U;
}
// rescale the float value
if(expval) {
value /= conv.F;
}
// output the floating part
const size_t start_idx = idx;
idx = _ftoa(out, buffer, idx, maxlen, negative ? -value : value, prec, fwidth, flags & ~FLAGS_ADAPT_EXP);
// output the exponent part
if(minwidth) {
// output the exponential symbol
out((flags & FLAGS_UPPERCASE) ? 'E' : 'e', buffer, idx++, maxlen);
// output the exponent value
idx = _ntoa_long(out, buffer, idx, maxlen, (expval < 0) ? -expval : expval, expval < 0, 10, 0, minwidth - 1,
FLAGS_ZEROPAD | FLAGS_PLUS);
// might need to right-pad spaces
if(flags & FLAGS_LEFT) {
while(idx - start_idx < width) out(' ', buffer, idx++, maxlen);
}
}
return idx;
}
#endif // PRINTF_SUPPORT_EXPONENTIAL
#endif // PRINTF_SUPPORT_FLOAT
// internal vsnprintf
static int lv_vsnprintf_inner(out_fct_type out, char * buffer, const size_t maxlen, const char * format, va_list va)
{
unsigned int flags, width, precision, n;
size_t idx = 0U;
if(!buffer) {
// use null output function
out = _out_null;
}
while(*format) {
// format specifier? %[flags][width][.precision][length]
if(*format != '%') {
// no
out(*format, buffer, idx++, maxlen);
format++;
continue;
}
else {
// yes, evaluate it
format++;
}
// evaluate flags
flags = 0U;
do {
switch(*format) {
case '0':
flags |= FLAGS_ZEROPAD;
format++;
n = 1U;
break;
case '-':
flags |= FLAGS_LEFT;
format++;
n = 1U;
break;
case '+':
flags |= FLAGS_PLUS;
format++;
n = 1U;
break;
case ' ':
flags |= FLAGS_SPACE;
format++;
n = 1U;
break;
case '#':
flags |= FLAGS_HASH;
format++;
n = 1U;
break;
default :
n = 0U;
break;
}
} while(n);
// evaluate width field
width = 0U;
if(_is_digit(*format)) {
width = _atoi(&format);
}
else if(*format == '*') {
const int w = va_arg(va, int);
if(w < 0) {
flags |= FLAGS_LEFT; // reverse padding
width = (unsigned int) - w;
}
else {
width = (unsigned int)w;
}
format++;
}
// evaluate precision field
precision = 0U;
if(*format == '.') {
flags |= FLAGS_PRECISION;
format++;
if(_is_digit(*format)) {
precision = _atoi(&format);
}
else if(*format == '*') {
const int prec = (int)va_arg(va, int);
precision = prec > 0 ? (unsigned int)prec : 0U;
format++;
}
}
// evaluate length field
switch(*format) {
case 'l' :
flags |= FLAGS_LONG;
format++;
if(*format == 'l') {
flags |= FLAGS_LONG_LONG;
format++;
}
break;
case 'h' :
flags |= FLAGS_SHORT;
format++;
if(*format == 'h') {
flags |= FLAGS_CHAR;
format++;
}
break;
#if defined(PRINTF_SUPPORT_PTRDIFF_T)
case 't' :
flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG);
format++;
break;
#endif
case 'j' :
flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG);
format++;
break;
case 'z' :
flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG);
format++;
break;
default :
break;
}
// evaluate specifier
switch(*format) {
case 'd' :
case 'i' :
case 'u' :
case 'x' :
case 'X' :
case 'p' :
case 'P' :
case 'o' :
case 'b' : {
// set the base
unsigned int base;
if(*format == 'x' || *format == 'X') {
base = 16U;
}
else if(*format == 'p' || *format == 'P') {
base = 16U;
flags |= FLAGS_HASH; // always hash for pointer format
#if defined(PRINTF_SUPPORT_LONG_LONG)
if(sizeof(uintptr_t) == sizeof(long long))
flags |= FLAGS_LONG_LONG;
else
#endif
flags |= FLAGS_LONG;
if(*(format + 1) == 'V')
format++;
}
else if(*format == 'o') {
base = 8U;
}
else if(*format == 'b') {
base = 2U;
}
else {
base = 10U;
flags &= ~FLAGS_HASH; // no hash for dec format
}
// uppercase
if(*format == 'X' || *format == 'P') {
flags |= FLAGS_UPPERCASE;
}
// no plus or space flag for u, x, X, o, b
if((*format != 'i') && (*format != 'd')) {
flags &= ~(FLAGS_PLUS | FLAGS_SPACE);
}
// ignore '0' flag when precision is given
if(flags & FLAGS_PRECISION) {
flags &= ~FLAGS_ZEROPAD;
}
// convert the integer
if((*format == 'i') || (*format == 'd')) {
// signed
if(flags & FLAGS_LONG_LONG) {
#if defined(PRINTF_SUPPORT_LONG_LONG)
const long long value = va_arg(va, long long);
idx = _ntoa_long_long(out, buffer, idx, maxlen, (unsigned long long)(value > 0 ? value : 0 - value), value < 0, base,
precision, width, flags);
#endif
}
else if(flags & FLAGS_LONG) {
const long value = va_arg(va, long);
idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)(value > 0 ? value : 0 - value), value < 0, base, precision,
width, flags);
}
else {
const int value = (flags & FLAGS_CHAR) ? (char)va_arg(va, int) : (flags & FLAGS_SHORT) ? (short int)va_arg(va,
int) : va_arg(va, int);
idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned int)(value > 0 ? value : 0 - value), value < 0, base, precision,
width, flags);
}
}
else if(*format == 'V') {
lv_vaformat_t * vaf = va_arg(va, lv_vaformat_t *);
va_list copy;
va_copy(copy, *vaf->va);
idx += lv_vsnprintf_inner(out, buffer + idx, maxlen - idx, vaf->fmt, copy);
va_end(copy);
}
else {
// unsigned
if(flags & FLAGS_LONG_LONG) {
#if defined(PRINTF_SUPPORT_LONG_LONG)
idx = _ntoa_long_long(out, buffer, idx, maxlen, va_arg(va, unsigned long long), false, base, precision, width, flags);
#endif
}
else if(flags & FLAGS_LONG) {
idx = _ntoa_long(out, buffer, idx, maxlen, va_arg(va, unsigned long), false, base, precision, width, flags);
}
else {
const unsigned int value = (flags & FLAGS_CHAR) ? (unsigned char)va_arg(va,
unsigned int) : (flags & FLAGS_SHORT) ? (unsigned short int)va_arg(va, unsigned int) : va_arg(va, unsigned int);
idx = _ntoa_long(out, buffer, idx, maxlen, value, false, base, precision, width, flags);
}
}
format++;
break;
}
#if defined(PRINTF_SUPPORT_FLOAT)
case 'f' :
case 'F' :
if(*format == 'F') flags |= FLAGS_UPPERCASE;
idx = _ftoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags);
format++;
break;
#if defined(PRINTF_SUPPORT_EXPONENTIAL)
case 'e':
case 'E':
case 'g':
case 'G':
if((*format == 'g') || (*format == 'G')) flags |= FLAGS_ADAPT_EXP;
if((*format == 'E') || (*format == 'G')) flags |= FLAGS_UPPERCASE;
idx = _etoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags);
format++;
break;
#endif // PRINTF_SUPPORT_EXPONENTIAL
#endif // PRINTF_SUPPORT_FLOAT
case 'c' : {
unsigned int l = 1U;
// pre padding
if(!(flags & FLAGS_LEFT)) {
while(l++ < width) {
out(' ', buffer, idx++, maxlen);
}
}
// char output
out((char)va_arg(va, int), buffer, idx++, maxlen);
// post padding
if(flags & FLAGS_LEFT) {
while(l++ < width) {
out(' ', buffer, idx++, maxlen);
}
}
format++;
break;
}
case 's' : {
const char * p = va_arg(va, char *);
unsigned int l = _strnlen_s(p, precision ? precision : (size_t) -1);
// pre padding
if(flags & FLAGS_PRECISION) {
l = (l < precision ? l : precision);
}
if(!(flags & FLAGS_LEFT)) {
while(l++ < width) {
out(' ', buffer, idx++, maxlen);
}
}
// string output
while((*p != 0) && (!(flags & FLAGS_PRECISION) || precision--)) {
out(*(p++), buffer, idx++, maxlen);
}
// post padding
if(flags & FLAGS_LEFT) {
while(l++ < width) {
out(' ', buffer, idx++, maxlen);
}
}
format++;
break;
}
case '%' :
out('%', buffer, idx++, maxlen);
format++;
break;
default :
out(*format, buffer, idx++, maxlen);
format++;
break;
}
}
// termination
out((char)0, buffer, idx < maxlen ? idx : maxlen - 1U, maxlen);
// return written chars without terminating \0
return (int)idx;
}
///////////////////////////////////////////////////////////////////////////////
/// GLOBAL FUNCTIONS FOR LVGL
///////////////////////////////////////////////////////////////////////////////
int lv_snprintf(char * buffer, size_t count, const char * format, ...)
{
va_list va;
va_start(va, format);
const int ret = lv_vsnprintf_inner(_out_buffer, buffer, count, format, va);
va_end(va);
return ret;
}
int lv_vsnprintf(char * buffer, size_t count, const char * format, va_list va)
{
return lv_vsnprintf_inner(_out_buffer, buffer, count, format, va);
}
#endif /*LV_STDLIB_BUILTIN*/

View File

@@ -1,269 +0,0 @@
/**
* @file lv_string.c
*/
/*********************
* INCLUDES
*********************/
#include "../../lv_conf_internal.h"
#if LV_USE_STDLIB_STRING == LV_STDLIB_BUILTIN
#include "../../misc/lv_assert.h"
#include "../../misc/lv_log.h"
#include "../../misc/lv_math.h"
#include "../../stdlib/lv_string.h"
#include "../../stdlib/lv_mem.h"
/*********************
* DEFINES
*********************/
#ifdef LV_ARCH_64
#define MEM_UNIT uint64_t
#define ALIGN_MASK 0x7
#else
#define MEM_UNIT uint32_t
#define ALIGN_MASK 0x3
#endif
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
#if LV_USE_LOG && LV_LOG_TRACE_MEM
#define LV_TRACE_MEM(...) LV_LOG_TRACE(__VA_ARGS__)
#else
#define LV_TRACE_MEM(...)
#endif
#define _COPY(d, s) *d = *s; d++; s++;
#define _SET(d, v) *d = v; d++;
#define _REPEAT8(expr) expr expr expr expr expr expr expr expr
/**********************
* GLOBAL FUNCTIONS
**********************/
void * LV_ATTRIBUTE_FAST_MEM lv_memcpy(void * dst, const void * src, size_t len)
{
uint8_t * d8 = dst;
const uint8_t * s8 = src;
/*Simplify for small memories*/
if(len < 16) {
while(len) {
*d8 = *s8;
d8++;
s8++;
len--;
}
return dst;
}
lv_uintptr_t d_align = (lv_uintptr_t)d8 & ALIGN_MASK;
lv_uintptr_t s_align = (lv_uintptr_t)s8 & ALIGN_MASK;
/*Byte copy for unaligned memories*/
if(s_align != d_align) {
while(len > 32) {
_REPEAT8(_COPY(d8, s8));
_REPEAT8(_COPY(d8, s8));
_REPEAT8(_COPY(d8, s8));
_REPEAT8(_COPY(d8, s8));
len -= 32;
}
while(len) {
_COPY(d8, s8)
len--;
}
return dst;
}
/*Make the memories aligned*/
if(d_align) {
d_align = ALIGN_MASK + 1 - d_align;
while(d_align && len) {
_COPY(d8, s8);
d_align--;
len--;
}
}
uint32_t * d32 = (uint32_t *)d8;
const uint32_t * s32 = (uint32_t *)s8;
while(len > 32) {
_REPEAT8(_COPY(d32, s32))
len -= 32;
}
d8 = (uint8_t *)d32;
s8 = (const uint8_t *)s32;
while(len) {
_COPY(d8, s8)
len--;
}
return dst;
}
void LV_ATTRIBUTE_FAST_MEM lv_memset(void * dst, uint8_t v, size_t len)
{
uint8_t * d8 = (uint8_t *)dst;
uintptr_t d_align = (lv_uintptr_t) d8 & ALIGN_MASK;
/*Make the address aligned*/
if(d_align) {
d_align = ALIGN_MASK + 1 - d_align;
while(d_align && len) {
_SET(d8, v);
len--;
d_align--;
}
}
uint32_t v32 = (uint32_t)v + ((uint32_t)v << 8) + ((uint32_t)v << 16) + ((uint32_t)v << 24);
uint32_t * d32 = (uint32_t *)d8;
while(len > 32) {
_REPEAT8(_SET(d32, v32));
len -= 32;
}
d8 = (uint8_t *)d32;
while(len) {
_SET(d8, v);
len--;
}
}
void * LV_ATTRIBUTE_FAST_MEM lv_memmove(void * dst, const void * src, size_t len)
{
if(dst < src || (char *)dst > ((char *)src + len)) {
return lv_memcpy(dst, src, len);
}
if(dst > src) {
char * tmp = (char *)dst + len - 1;
char * s = (char *)src + len - 1;
while(len--) {
*tmp-- = *s--;
}
}
else {
char * tmp = (char *)dst;
char * s = (char *)src;
while(len--) {
*tmp++ = *s++;
}
}
return dst;
}
int lv_memcmp(const void * p1, const void * p2, size_t len)
{
const char * s1 = (const char *) p1;
const char * s2 = (const char *) p2;
while(--len > 0 && (*s1 == *s2)) {
s1++;
s2++;
}
return *s1 - *s2;
}
/* See https://en.cppreference.com/w/c/string/byte/strlen for reference */
size_t lv_strlen(const char * str)
{
size_t i = 0;
while(str[i]) i++;
return i;
}
size_t lv_strlcpy(char * dst, const char * src, size_t dst_size)
{
size_t i = 0;
if(dst_size > 0) {
for(; i < dst_size - 1 && src[i]; i++) {
dst[i] = src[i];
}
dst[i] = '\0';
}
while(src[i]) i++;
return i;
}
char * lv_strncpy(char * dst, const char * src, size_t dst_size)
{
size_t i;
for(i = 0; i < dst_size && src[i]; i++) {
dst[i] = src[i];
}
for(; i < dst_size; i++) {
dst[i] = '\0';
}
return dst;
}
char * lv_strcpy(char * dst, const char * src)
{
char * tmp = dst;
while((*dst++ = *src++) != '\0');
return tmp;
}
int lv_strcmp(const char * s1, const char * s2)
{
while(*s1 && (*s1 == *s2)) {
s1++;
s2++;
}
return *(const unsigned char *)s1 - *(const unsigned char *)s2;
}
char * lv_strdup(const char * src)
{
size_t len = lv_strlen(src) + 1;
char * dst = lv_malloc(len);
if(dst == NULL) return NULL;
lv_memcpy(dst, src, len); /*memcpy is faster than strncpy when length is known*/
return dst;
}
char * lv_strcat(char * dst, const char * src)
{
lv_strcpy(dst + lv_strlen(dst), src);
return dst;
}
char * lv_strncat(char * dst, const char * src, size_t src_len)
{
char * tmp = dst;
while(*dst != '\0') {
dst++;
}
while(src_len != 0 && *src != '\0') {
src_len--;
*dst++ = *src++;
}
*dst = '\0';
return tmp;
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif /*LV_STDLIB_BUILTIN*/

View File

@@ -1,97 +0,0 @@
#include "../../lv_conf_internal.h"
#if LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN
#ifndef LV_TLSF_H
#define LV_TLSF_H
/*
** Two Level Segregated Fit memory allocator, version 3.1.
** Written by Matthew Conte
** http://tlsf.baisoku.org
**
** Based on the original documentation by Miguel Masmano:
** http://www.gii.upv.es/tlsf/main/docs
**
** This implementation was written to the specification
** of the document, therefore no GPL restrictions apply.
**
** Copyright (c) 2006-2016, Matthew Conte
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** * Neither the name of the copyright holder nor the
** names of its contributors may be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL MATTHEW CONTE BE LIABLE FOR ANY
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "../../osal/lv_os.h"
#include "../../misc/lv_ll.h"
#include "../../misc/lv_types.h"
#if defined(__cplusplus)
extern "C" {
#endif
/* lv_tlsf_t: a TLSF structure. Can contain 1 to N pools. */
/* lv_pool_t: a block of memory that TLSF can manage. */
typedef void * lv_tlsf_t;
typedef void * lv_pool_t;
/* Create/destroy a memory pool. */
lv_tlsf_t lv_tlsf_create(void * mem);
lv_tlsf_t lv_tlsf_create_with_pool(void * mem, size_t bytes);
void lv_tlsf_destroy(lv_tlsf_t tlsf);
lv_pool_t lv_tlsf_get_pool(lv_tlsf_t tlsf);
/* Add/remove memory pools. */
lv_pool_t lv_tlsf_add_pool(lv_tlsf_t tlsf, void * mem, size_t bytes);
void lv_tlsf_remove_pool(lv_tlsf_t tlsf, lv_pool_t pool);
/* malloc/memalign/realloc/free replacements. */
void * lv_tlsf_malloc(lv_tlsf_t tlsf, size_t bytes);
void * lv_tlsf_memalign(lv_tlsf_t tlsf, size_t align, size_t bytes);
void * lv_tlsf_realloc(lv_tlsf_t tlsf, void * ptr, size_t size);
size_t lv_tlsf_free(lv_tlsf_t tlsf, const void * ptr);
/* Returns internal block size, not original request size */
size_t lv_tlsf_block_size(void * ptr);
/* Overheads/limits of internal structures. */
size_t lv_tlsf_size(void);
size_t lv_tlsf_align_size(void);
size_t lv_tlsf_block_size_min(void);
size_t lv_tlsf_block_size_max(void);
size_t lv_tlsf_pool_overhead(void);
size_t lv_tlsf_alloc_overhead(void);
/* Debugging. */
typedef void (*lv_tlsf_walker)(void * ptr, size_t size, int used, void * user);
void lv_tlsf_walk_pool(lv_pool_t pool, lv_tlsf_walker walker, void * user);
/* Returns nonzero if any internal consistency check fails. */
int lv_tlsf_check(lv_tlsf_t tlsf);
int lv_tlsf_check_pool(lv_pool_t pool);
#if defined(__cplusplus)
};
#endif
#endif /*LV_TLSF_H*/
#endif /*LV_STDLIB_BUILTIN*/

View File

@@ -1,53 +0,0 @@
/**
* @file lv_tlsf_private.h
*
*/
#ifndef LV_TLSF_PRIVATE_H
#define LV_TLSF_PRIVATE_H
#if LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "lv_tlsf.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
typedef struct {
#if LV_USE_OS
lv_mutex_t mutex;
#endif
lv_tlsf_t tlsf;
size_t cur_used;
size_t max_used;
lv_ll_t pool_ll;
} lv_tlsf_state_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN*/
#endif /*LV_TLSF_PRIVATE_H*/

View File

@@ -1,94 +0,0 @@
/**
* @file lv_malloc_core.c
*/
/*********************
* INCLUDES
*********************/
#include "../lv_mem.h"
#if LV_USE_STDLIB_MALLOC == LV_STDLIB_CLIB
#include "../../stdlib/lv_mem.h"
#include <stdlib.h>
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
void lv_mem_init(void)
{
return; /*Nothing to init*/
}
void lv_mem_deinit(void)
{
return; /*Nothing to deinit*/
}
lv_mem_pool_t lv_mem_add_pool(void * mem, size_t bytes)
{
/*Not supported*/
LV_UNUSED(mem);
LV_UNUSED(bytes);
return NULL;
}
void lv_mem_remove_pool(lv_mem_pool_t pool)
{
/*Not supported*/
LV_UNUSED(pool);
return;
}
void * lv_malloc_core(size_t size)
{
return malloc(size);
}
void * lv_realloc_core(void * p, size_t new_size)
{
return realloc(p, new_size);
}
void lv_free_core(void * p)
{
free(p);
}
void lv_mem_monitor_core(lv_mem_monitor_t * mon_p)
{
/*Not supported*/
LV_UNUSED(mon_p);
return;
}
lv_result_t lv_mem_test_core(void)
{
/*Not supported*/
return LV_RESULT_OK;
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif /*LV_STDLIB_CLIB*/

View File

@@ -1,58 +0,0 @@
/**
* @file lv_templ.c
*
*/
/*********************
* INCLUDES
*********************/
#include "../../lv_conf_internal.h"
#if LV_USE_STDLIB_SPRINTF == LV_STDLIB_CLIB
#include <stdio.h>
#include <stdarg.h>
#include "../lv_sprintf.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
int lv_snprintf(char * buffer, size_t count, const char * format, ...)
{
va_list va;
va_start(va, format);
const int ret = vsnprintf(buffer, count, format, va);
va_end(va);
return ret;
}
int lv_vsnprintf(char * buffer, size_t count, const char * format, va_list va)
{
return vsnprintf(buffer, count, format, va);
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif

View File

@@ -1,114 +0,0 @@
/**
* @file lv_string.c
*/
/*********************
* INCLUDES
*********************/
#include "../../lv_conf_internal.h"
#if LV_USE_STDLIB_STRING == LV_STDLIB_CLIB
#include "../lv_string.h"
#include "../lv_mem.h" /*Need lv_malloc*/
#include <string.h>
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
void * LV_ATTRIBUTE_FAST_MEM lv_memcpy(void * dst, const void * src, size_t len)
{
return memcpy(dst, src, len);
}
void LV_ATTRIBUTE_FAST_MEM lv_memset(void * dst, uint8_t v, size_t len)
{
memset(dst, v, len);
}
void * LV_ATTRIBUTE_FAST_MEM lv_memmove(void * dst, const void * src, size_t len)
{
return memmove(dst, src, len);
}
int lv_memcmp(const void * p1, const void * p2, size_t len)
{
return memcmp(p1, p2, len);
}
size_t lv_strlen(const char * str)
{
return strlen(str);
}
size_t lv_strlcpy(char * dst, const char * src, size_t dst_size)
{
size_t src_len = strlen(src);
if(dst_size > 0) {
size_t copy_size = src_len < dst_size ? src_len : dst_size - 1;
memcpy(dst, src, copy_size);
dst[copy_size] = '\0';
}
return src_len;
}
char * lv_strncpy(char * dst, const char * src, size_t dest_size)
{
return strncpy(dst, src, dest_size);
}
char * lv_strcpy(char * dst, const char * src)
{
return strcpy(dst, src);
}
int lv_strcmp(const char * s1, const char * s2)
{
return strcmp(s1, s2);
}
char * lv_strdup(const char * src)
{
/*strdup uses malloc, so use the lv_malloc when LV_USE_STDLIB_MALLOC is not LV_STDLIB_CLIB */
size_t len = lv_strlen(src) + 1;
char * dst = lv_malloc(len);
if(dst == NULL) return NULL;
lv_memcpy(dst, src, len); /*do memcpy is faster than strncpy when length is known*/
return dst;
}
char * lv_strcat(char * dst, const char * src)
{
return strcat(dst, src);
}
char * lv_strncat(char * dst, const char * src, size_t src_len)
{
return strncat(dst, src, src_len);
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif /*LV_STDLIB_CLIB*/

View File

@@ -1,168 +0,0 @@
/**
* @file lv_mem.c
*/
/*********************
* INCLUDES
*********************/
#include "lv_mem_private.h"
#include "lv_string.h"
#include "../misc/lv_assert.h"
#include "../misc/lv_log.h"
#include "../core/lv_global.h"
#if LV_USE_OS == LV_OS_PTHREAD
#include <pthread.h>
#endif
/*********************
* DEFINES
*********************/
/*memset the allocated memories to 0xaa and freed memories to 0xbb (just for testing purposes)*/
#ifndef LV_MEM_ADD_JUNK
#define LV_MEM_ADD_JUNK 0
#endif
#define zero_mem LV_GLOBAL_DEFAULT()->memory_zero
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void * lv_malloc_core(size_t size);
void * lv_realloc_core(void * p, size_t new_size);
void lv_free_core(void * p);
void lv_mem_monitor_core(lv_mem_monitor_t * mon_p);
lv_result_t lv_mem_test_core(void);
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
#if LV_USE_LOG && LV_LOG_TRACE_MEM
#define LV_TRACE_MEM(...) LV_LOG_TRACE(__VA_ARGS__)
#else
#define LV_TRACE_MEM(...)
#endif
/**********************
* GLOBAL FUNCTIONS
**********************/
void * lv_malloc(size_t size)
{
LV_TRACE_MEM("allocating %lu bytes", (unsigned long)size);
if(size == 0) {
LV_TRACE_MEM("using zero_mem");
return &zero_mem;
}
void * alloc = lv_malloc_core(size);
if(alloc == NULL) {
LV_LOG_INFO("couldn't allocate memory (%lu bytes)", (unsigned long)size);
#if LV_LOG_LEVEL <= LV_LOG_LEVEL_INFO
lv_mem_monitor_t mon;
lv_mem_monitor(&mon);
LV_LOG_INFO("used: %zu (%3d %%), frag: %3d %%, biggest free: %zu",
mon.total_size - mon.free_size, mon.used_pct, mon.frag_pct,
mon.free_biggest_size);
#endif
return NULL;
}
#if LV_MEM_ADD_JUNK
lv_memset(alloc, 0xaa, size);
#endif
LV_TRACE_MEM("allocated at %p", alloc);
return alloc;
}
void * lv_malloc_zeroed(size_t size)
{
LV_TRACE_MEM("allocating %lu bytes", (unsigned long)size);
if(size == 0) {
LV_TRACE_MEM("using zero_mem");
return &zero_mem;
}
void * alloc = lv_malloc_core(size);
if(alloc == NULL) {
LV_LOG_INFO("couldn't allocate memory (%lu bytes)", (unsigned long)size);
#if LV_LOG_LEVEL <= LV_LOG_LEVEL_INFO
lv_mem_monitor_t mon;
lv_mem_monitor(&mon);
LV_LOG_INFO("used: %zu (%3d %%), frag: %3d %%, biggest free: %zu",
mon.total_size - mon.free_size, mon.used_pct, mon.frag_pct,
mon.free_biggest_size);
#endif
return NULL;
}
lv_memzero(alloc, size);
LV_TRACE_MEM("allocated at %p", alloc);
return alloc;
}
void lv_free(void * data)
{
LV_TRACE_MEM("freeing %p", data);
if(data == &zero_mem) return;
if(data == NULL) return;
lv_free_core(data);
}
void * lv_realloc(void * data_p, size_t new_size)
{
LV_TRACE_MEM("reallocating %p with %lu size", data_p, (unsigned long)new_size);
if(new_size == 0) {
LV_TRACE_MEM("using zero_mem");
lv_free(data_p);
return &zero_mem;
}
if(data_p == &zero_mem) return lv_malloc(new_size);
void * new_p = lv_realloc_core(data_p, new_size);
if(new_p == NULL) {
LV_LOG_ERROR("couldn't reallocate memory");
return NULL;
}
LV_TRACE_MEM("reallocated at %p", new_p);
return new_p;
}
lv_result_t lv_mem_test(void)
{
if(zero_mem != ZERO_MEM_SENTINEL) {
LV_LOG_WARN("zero_mem is written");
return LV_RESULT_INVALID;
}
return lv_mem_test_core();
}
void lv_mem_monitor(lv_mem_monitor_t * mon_p)
{
lv_memzero(mon_p, sizeof(lv_mem_monitor_t));
lv_mem_monitor_core(mon_p);
}
/**********************
* STATIC FUNCTIONS
**********************/

View File

@@ -1,141 +0,0 @@
/**
* @file lv_mem.h
*
*/
#ifndef LV_MEM_H
#define LV_MEM_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../lv_conf_internal.h"
#include "lv_string.h"
#include "../misc/lv_types.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
typedef void * lv_mem_pool_t;
/**
* Heap information structure.
*/
typedef struct {
size_t total_size; /**< Total heap size */
size_t free_cnt;
size_t free_size; /**< Size of available memory */
size_t free_biggest_size;
size_t used_cnt;
size_t max_used; /**< Max size of Heap memory used */
uint8_t used_pct; /**< Percentage used */
uint8_t frag_pct; /**< Amount of fragmentation */
} lv_mem_monitor_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Initialize to use malloc/free/realloc etc
*/
void lv_mem_init(void);
/**
* Drop all dynamically allocated memory and reset the memory pools' state
*/
void lv_mem_deinit(void);
lv_mem_pool_t lv_mem_add_pool(void * mem, size_t bytes);
void lv_mem_remove_pool(lv_mem_pool_t pool);
/**
* Allocate memory dynamically
* @param size requested size in bytes
* @return pointer to allocated uninitialized memory, or NULL on failure
*/
void * lv_malloc(size_t size);
/**
* Allocate zeroed memory dynamically
* @param size requested size in bytes
* @return pointer to allocated zeroed memory, or NULL on failure
*/
void * lv_malloc_zeroed(size_t size);
/**
* Free an allocated data
* @param data pointer to an allocated memory
*/
void lv_free(void * data);
/**
* Reallocate a memory with a new size. The old content will be kept.
* @param data_p pointer to an allocated memory.
* Its content will be copied to the new memory block and freed
* @param new_size the desired new size in byte
* @return pointer to the new memory, NULL on failure
*/
void * lv_realloc(void * data_p, size_t new_size);
/**
* Used internally to execute a plain `malloc` operation
* @param size size in bytes to `malloc`
*/
void * lv_malloc_core(size_t size);
/**
* Used internally to execute a plain `free` operation
* @param p memory address to free
*/
void lv_free_core(void * p);
/**
* Used internally to execute a plain realloc operation
* @param p memory address to realloc
* @param new_size size in bytes to realloc
*/
void * lv_realloc_core(void * p, size_t new_size);
/**
* Used internally by lv_mem_monitor() to gather LVGL heap state information.
* @param mon_p pointer to lv_mem_monitor_t object to be populated.
*/
void lv_mem_monitor_core(lv_mem_monitor_t * mon_p);
lv_result_t lv_mem_test_core(void);
/**
* @brief Tests the memory allocation system by allocating and freeing a block of memory.
* @return LV_RESULT_OK if the memory allocation system is working properly, or LV_RESULT_INVALID if there is an error.
*/
lv_result_t lv_mem_test(void);
/**
* Give information about the work memory of dynamic allocation
* @param mon_p pointer to a lv_mem_monitor_t variable,
* the result of the analysis will be stored here
*/
void lv_mem_monitor(lv_mem_monitor_t * mon_p);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_MEM_H*/

View File

@@ -1,39 +0,0 @@
/**
* @file lv_mem_private.h
*
*/
#ifndef LV_MEM_PRIVATE_H
#define LV_MEM_PRIVATE_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "lv_mem.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_MEM_PRIVATE_H*/

View File

@@ -1,45 +0,0 @@
/**
* @file lv_sprintf.h
*
*/
#ifndef LV_SPRINTF_H
#define LV_SPRINTF_H
#if defined(__has_include)
#if __has_include(LV_INTTYPES_INCLUDE)
#include LV_INTTYPES_INCLUDE
/* platform-specific printf format for int32_t, usually "d" or "ld" */
#define LV_PRId32 PRId32
#define LV_PRIu32 PRIu32
#define LV_PRIx32 PRIx32
#define LV_PRIX32 PRIX32
#else
#define LV_PRId32 "d"
#define LV_PRIu32 "u"
#define LV_PRIx32 "x"
#define LV_PRIX32 "X"
#endif
#else
/* hope this is correct for ports without __has_include or without inttypes.h */
#define LV_PRId32 "d"
#define LV_PRIu32 "u"
#define LV_PRIx32 "x"
#define LV_PRIX32 "X"
#endif
#include "../misc/lv_types.h"
#ifdef __cplusplus
extern "C" {
#endif
int lv_snprintf(char * buffer, size_t count, const char * format, ...);
int lv_vsnprintf(char * buffer, size_t count, const char * format, va_list va);
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /* LV_SPRINTF_H */

View File

@@ -1,158 +0,0 @@
/**
* @file lv_string.h
*
*/
#ifndef LV_STRING_H
#define LV_STRING_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../lv_conf_internal.h"
#include "../misc/lv_types.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* @brief Copies a block of memory from a source address to a destination address.
* @param dst Pointer to the destination array where the content is to be copied.
* @param src Pointer to the source of data to be copied.
* @param len Number of bytes to copy.
* @return Pointer to the destination array.
* @note The function does not check for any overlapping of the source and destination memory blocks.
*/
void * lv_memcpy(void * dst, const void * src, size_t len);
/**
* @brief Fills a block of memory with a specified value.
* @param dst Pointer to the destination array to fill with the specified value.
* @param v Value to be set. The value is passed as an int, but the function fills
* the block of memory using the unsigned char conversion of this value.
* @param len Number of bytes to be set to the value.
*/
void lv_memset(void * dst, uint8_t v, size_t len);
/**
* @brief Move a block of memory from source to destination
* @param dst Pointer to the destination array where the content is to be copied.
* @param src Pointer to the source of data to be copied.
* @param len Number of bytes to copy
* @return Pointer to the destination array.
*/
void * lv_memmove(void * dst, const void * src, size_t len);
/**
* @brief This function will compare two memory blocks
* @param p1 Pointer to the first memory block
* @param p2 Pointer to the second memory block
* @param len Number of bytes to compare
* @return The difference between the value of the first unmatching byte.
*/
int lv_memcmp(const void * p1, const void * p2, size_t len);
/**
* Same as `memset(dst, 0x00, len)`.
* @param dst pointer to the destination buffer
* @param len number of byte to set
*/
static inline void lv_memzero(void * dst, size_t len)
{
lv_memset(dst, 0x00, len);
}
/**
* @brief Computes the length of the string str up to, but not including the terminating null character.
* @param str Pointer to the null-terminated byte string to be examined.
* @return The length of the string in bytes.
*/
size_t lv_strlen(const char * str);
/**
* @brief Copies up to dst_size-1 (non-null) characters from src to dst. A null terminator is always added.
* @param dst Pointer to the destination array where the content is to be copied.
* @param src Pointer to the source of data to be copied.
* @param dst_size Maximum number of characters to be copied to dst, including the null character.
* @return The length of src. The return value is equivalent to the value returned by lv_strlen(src)
*/
size_t lv_strlcpy(char * dst, const char * src, size_t dst_size);
/**
* @brief Copies up to dest_size characters from the string pointed to by src to the character array pointed to by dst
* and fills the remaining length with null bytes.
* @param dst Pointer to the destination array where the content is to be copied.
* @param src Pointer to the source of data to be copied.
* @param dest_size Maximum number of characters to be copied to dst.
* @return A pointer to the destination array, which is dst.
* @note dst will not be null terminated if dest_size bytes were copied from src before the end of src was reached.
*/
char * lv_strncpy(char * dst, const char * src, size_t dest_size);
/**
* @brief Copies the string pointed to by src, including the terminating null character,
* to the character array pointed to by dst.
* @param dst Pointer to the destination array where the content is to be copied.
* @param src Pointer to the source of data to be copied.
* @return A pointer to the destination array, which is dst.
*/
char * lv_strcpy(char * dst, const char * src);
/**
* @brief This function will compare two strings without specified length.
* @param s1 pointer to the first string
* @param s2 pointer to the second string
* @return the difference between the value of the first unmatching character.
*/
int lv_strcmp(const char * s1, const char * s2);
/**
* @brief Duplicate a string by allocating a new one and copying the content.
* @param src Pointer to the source of data to be copied.
* @return A pointer to the new allocated string. NULL if failed.
*/
char * lv_strdup(const char * src);
/**
* @brief Copies the string pointed to by src, including the terminating null character,
* to the end of the string pointed to by dst.
* @param dst Pointer to the destination string where the content is to be appended.
* @param src Pointer to the source of data to be copied.
* @return A pointer to the destination string, which is dst.
*/
char * lv_strcat(char * dst, const char * src);
/**
* @brief Copies up to src_len characters from the string pointed to by src
* to the end of the string pointed to by dst.
* A terminating null character is appended to dst even if no null character
* was encountered in src after src_len characters were copied.
* @param dst Pointer to the destination string where the content is to be appended.
* @param src Pointer to the source of data to be copied.
* @param src_len Maximum number of characters from src to be copied to the end of dst.
* @return A pointer to the destination string, which is dst.
*/
char * lv_strncat(char * dst, const char * src, size_t src_len);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_STRING_H*/

View File

@@ -1,110 +0,0 @@
/**
* @file lv_malloc_core.c
*/
/*********************
* INCLUDES
*********************/
#include "../lv_mem.h"
#if LV_USE_STDLIB_MALLOC == LV_STDLIB_MICROPYTHON
#include "../../stdlib/lv_mem.h"
#include "include/lv_mp_mem_custom_include.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
void lv_mem_init(void)
{
return; /*Nothing to init*/
}
void lv_mem_deinit(void)
{
return; /*Nothing to deinit*/
}
lv_mem_pool_t lv_mem_add_pool(void * mem, size_t bytes)
{
/*Not supported*/
LV_UNUSED(mem);
LV_UNUSED(bytes);
return NULL;
}
void lv_mem_remove_pool(lv_mem_pool_t pool)
{
/*Not supported*/
LV_UNUSED(pool);
return;
}
void * lv_malloc_core(size_t size)
{
#if MICROPY_MALLOC_USES_ALLOCATED_SIZE
return gc_alloc(size, true);
#else
return m_malloc(size);
#endif
}
void * lv_realloc_core(void * p, size_t new_size)
{
#if MICROPY_MALLOC_USES_ALLOCATED_SIZE
return gc_realloc(p, new_size, true);
#else
return m_realloc(p, new_size);
#endif
}
void lv_free_core(void * p)
{
#if MICROPY_MALLOC_USES_ALLOCATED_SIZE
gc_free(p);
#else
m_free(p);
#endif
}
void lv_mem_monitor_core(lv_mem_monitor_t * mon_p)
{
/*Not supported*/
LV_UNUSED(mon_p);
return;
}
lv_result_t lv_mem_test_core(void)
{
/*Not supported*/
return LV_RESULT_OK;
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif /*LV_STDLIB_MICROPYTHON*/

View File

@@ -1,98 +0,0 @@
/**
* @file lv_malloc_core_rtthread.c
*/
/*********************
* INCLUDES
*********************/
#include "../lv_mem.h"
#if LV_USE_STDLIB_MALLOC == LV_STDLIB_RTTHREAD
#include "../../stdlib/lv_mem.h"
#include <rtthread.h>
#ifndef RT_USING_HEAP
#error "lv_mem_core_rtthread: RT_USING_HEAP is required. Define it in rtconfig.h"
#endif
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
void lv_mem_init(void)
{
return; /*Nothing to init*/
}
void lv_mem_deinit(void)
{
return; /*Nothing to deinit*/
}
lv_mem_pool_t lv_mem_add_pool(void * mem, size_t bytes)
{
/*Not supported*/
LV_UNUSED(mem);
LV_UNUSED(bytes);
return NULL;
}
void lv_mem_remove_pool(lv_mem_pool_t pool)
{
/*Not supported*/
LV_UNUSED(pool);
return;
}
void * lv_malloc_core(size_t size)
{
return rt_malloc(size);
}
void * lv_realloc_core(void * p, size_t new_size)
{
return rt_realloc(p, new_size);
}
void lv_free_core(void * p)
{
rt_free(p);
}
void lv_mem_monitor_core(lv_mem_monitor_t * mon_p)
{
/*Not supported*/
LV_UNUSED(mon_p);
return;
}
lv_result_t lv_mem_test_core(void)
{
/*Not supported*/
return LV_RESULT_OK;
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif /*LV_STDLIB_RTTHREAD*/

View File

@@ -1,61 +0,0 @@
/**
* @file lv_sprintf_rtthread.c
*
*/
/*********************
* INCLUDES
*********************/
#include "../../lv_conf_internal.h"
#if LV_USE_STDLIB_SPRINTF == LV_STDLIB_RTTHREAD
#include <rtthread.h>
#include <stdarg.h>
#include "../lv_sprintf.h"
#if LV_USE_FLOAT == 1
#warning "lv_sprintf_rtthread: rtthread not support float in sprintf"
#endif
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
int lv_snprintf(char * buffer, size_t count, const char * format, ...)
{
va_list va;
va_start(va, format);
const int ret = rt_vsnprintf(buffer, count, format, va);
va_end(va);
return ret;
}
int lv_vsnprintf(char * buffer, size_t count, const char * format, va_list va)
{
return rt_vsnprintf(buffer, count, format, va);
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif /*LV_STDLIB_RTTHREAD*/

View File

@@ -1,123 +0,0 @@
/**
* @file lv_string_rtthread.c
*/
/*********************
* INCLUDES
*********************/
#include "../../lv_conf_internal.h"
#if LV_USE_STDLIB_STRING == LV_STDLIB_RTTHREAD
#include "../lv_string.h"
#include "../lv_mem.h" /*Need lv_malloc*/
#include <rtthread.h>
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
void * LV_ATTRIBUTE_FAST_MEM lv_memcpy(void * dst, const void * src, size_t len)
{
return rt_memcpy(dst, src, len);
}
void LV_ATTRIBUTE_FAST_MEM lv_memset(void * dst, uint8_t v, size_t len)
{
rt_memset(dst, v, len);
}
void * LV_ATTRIBUTE_FAST_MEM lv_memmove(void * dst, const void * src, size_t len)
{
return rt_memmove(dst, src, len);
}
size_t lv_strlen(const char * str)
{
return rt_strlen(str);
}
int lv_memcmp(const void * p1, const void * p2, size_t len)
{
return rt_memcmp(p1, p2, len);
}
size_t lv_strlcpy(char * dst, const char * src, size_t dst_size)
{
size_t src_len = lv_strlen(src);
if(dst_size > 0) {
size_t copy_size = src_len < dst_size ? src_len : dst_size - 1;
lv_memcpy(dst, src, copy_size);
dst[copy_size] = '\0';
}
return src_len;
}
char * lv_strncpy(char * dst, const char * src, size_t dest_size)
{
return rt_strncpy(dst, src, dest_size);
}
char * lv_strcpy(char * dst, const char * src)
{
return rt_strcpy(dst, src);
}
int lv_strcmp(const char * s1, const char * s2)
{
return rt_strcmp(s1, s2);
}
char * lv_strdup(const char * src)
{
size_t len = lv_strlen(src) + 1;
char * dst = lv_malloc(len);
if(dst == NULL) return NULL;
lv_memcpy(dst, src, len); /*memcpy is faster than strncpy when length is known*/
return dst;
}
char * lv_strcat(char * dst, const char * src)
{
/*Since RT-thread does not have rt_strcat,
the following code is used instead.*/
lv_strcpy(dst + lv_strlen(dst), src);
return dst;
}
char * lv_strncat(char * dst, const char * src, size_t src_len)
{
char * tmp = dst;
dst += lv_strlen(dst);
while(src_len != 0 && *src != '\0') {
src_len--;
*dst++ = *src++;
}
*dst = '\0';
return tmp;
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif /*LV_STDLIB_RTTHREAD*/