[core] Move arduino/ files to cores/
This commit is contained in:
38
cores/common/base/config/fal_cfg.h
Normal file
38
cores/common/base/config/fal_cfg.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2022-05-24. */
|
||||
|
||||
#pragma once
|
||||
|
||||
inline void printf_nop(const char *fmt, ...) {}
|
||||
|
||||
#define FAL_PRINTF printf_nop
|
||||
#define FAL_DEBUG 0
|
||||
|
||||
// Flash device configuration
|
||||
extern const struct fal_flash_dev flash0;
|
||||
|
||||
#define FAL_FLASH_DEV_NAME "flash0"
|
||||
|
||||
#define FAL_FLASH_DEV_TABLE \
|
||||
{ &flash0, }
|
||||
|
||||
#define FAL_DEV_NAME_MAX 16 // no need for 24 chars (default)
|
||||
|
||||
// Partition table
|
||||
#define FAL_PART_HAS_TABLE_CFG
|
||||
|
||||
#define FAL_PART_TABLE_ITEM(part_lower, part_upper) \
|
||||
{ \
|
||||
.magic_word = FAL_PART_MAGIC_WORD, /* magic word */ \
|
||||
.name = #part_lower, /* lowercase name as string */ \
|
||||
.flash_name = FAL_FLASH_DEV_NAME, /* flash device name */ \
|
||||
.offset = FLASH_##part_upper##_OFFSET, /* partition offset macro as uppercase string */ \
|
||||
.len = FLASH_##part_upper##_LENGTH, /* partition length macro as uppercase string */ \
|
||||
},
|
||||
|
||||
// for fal_partition_t
|
||||
#include <fal_def.h>
|
||||
|
||||
/**
|
||||
* @brief Root partition table, representing the entire flash.
|
||||
*/
|
||||
extern fal_partition_t fal_root_part;
|
||||
49
cores/common/base/config/fdb_cfg.h
Normal file
49
cores/common/base/config/fdb_cfg.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Armink, <armink.ztl@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _FDB_CFG_H_
|
||||
#define _FDB_CFG_H_
|
||||
|
||||
/* using KVDB feature */
|
||||
#define FDB_USING_KVDB
|
||||
|
||||
#ifdef FDB_USING_KVDB
|
||||
/* Auto update KV to latest default when current KVDB version number is changed. @see fdb_kvdb.ver_num */
|
||||
// #define FDB_KV_AUTO_UPDATE
|
||||
#endif
|
||||
|
||||
/* using TSDB (Time series database) feature */
|
||||
// #define FDB_USING_TSDB
|
||||
|
||||
/* Using FAL storage mode */
|
||||
#define FDB_USING_FAL_MODE
|
||||
|
||||
#ifdef FDB_USING_FAL_MODE
|
||||
/* the flash write granularity, unit: bit
|
||||
* only support 1(nor flash)/ 8(stm32f2/f4)/ 32(stm32f1) */
|
||||
#define FDB_WRITE_GRAN 8
|
||||
#endif
|
||||
|
||||
/* Using file storage mode by LIBC file API, like fopen/fread/fwrte/fclose */
|
||||
// #define FDB_USING_FILE_LIBC_MODE
|
||||
|
||||
/* Using file storage mode by POSIX file API, like open/read/write/close */
|
||||
// #define FDB_USING_FILE_POSIX_MODE
|
||||
|
||||
/* MCU Endian Configuration, default is Little Endian Order. */
|
||||
// #define FDB_BIG_ENDIAN
|
||||
|
||||
#include <printf_config.h>
|
||||
|
||||
#if LT_DEBUG_FDB
|
||||
#include <printf/printf.h>
|
||||
#define FDB_PRINT(...) __wrap_printf(__VA_ARGS__)
|
||||
#define FDB_DEBUG_ENABLE
|
||||
#else
|
||||
#define FDB_PRINT(...)
|
||||
#endif
|
||||
|
||||
#endif /* _FDB_CFG_H_ */
|
||||
129
cores/common/base/config/printf_config.h
Normal file
129
cores/common/base/config/printf_config.h
Normal file
@@ -0,0 +1,129 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2022-06-19. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibreTuyaConfig.h>
|
||||
|
||||
#define PRINTF_HAS_DISABLE 1
|
||||
|
||||
// make printf.c define wrapper functions
|
||||
#define printf_ __wrap_printf
|
||||
#define sprintf_ __wrap_sprintf
|
||||
#define vsprintf_ __wrap_vsprintf
|
||||
#define snprintf_ __wrap_snprintf
|
||||
#define vsnprintf_ __wrap_vsnprintf
|
||||
#define vprintf_ __wrap_vprintf
|
||||
|
||||
// declare putchar() method with custom output port
|
||||
void putchar_p(char c, unsigned long port);
|
||||
|
||||
#define WRAP_DISABLE_DEF(name) \
|
||||
extern void __wrap_##name##_disable(); \
|
||||
extern void __wrap_##name##_enable(); \
|
||||
extern void __wrap_##name##_set(unsigned char disabled); \
|
||||
extern unsigned char __wrap_##name##_get();
|
||||
|
||||
#if !LT_UART_SILENT_ENABLED || LT_UART_SILENT_ALL
|
||||
|
||||
#define WRAP_DISABLE_DECL(name) \
|
||||
void __wrap_##name##_disable() {} \
|
||||
void __wrap_##name##_enable() {} \
|
||||
void __wrap_##name##_set(unsigned char disabled) {} \
|
||||
unsigned char __wrap_##name##_get() { \
|
||||
return LT_UART_SILENT_ALL; \
|
||||
}
|
||||
|
||||
#define WRAP_DISABLE_CHECK(name) \
|
||||
{ \
|
||||
if (LT_UART_SILENT_ALL) \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#else // LT_UART_SILENT_ENABLED && !LT_UART_SILENT_ALL
|
||||
|
||||
#define WRAP_DISABLE_DECL(name) \
|
||||
static unsigned char __wrap_##name##_disabled = 0; \
|
||||
void __wrap_##name##_disable() { \
|
||||
__wrap_##name##_disabled = 1; \
|
||||
} \
|
||||
void __wrap_##name##_enable() { \
|
||||
__wrap_##name##_disabled = 0; \
|
||||
} \
|
||||
void __wrap_##name##_set(unsigned char disabled) { \
|
||||
__wrap_##name##_disabled = disabled; \
|
||||
} \
|
||||
unsigned char __wrap_##name##_get() { \
|
||||
return __wrap_##name##_disabled; \
|
||||
}
|
||||
|
||||
#define WRAP_DISABLE_CHECK(name) \
|
||||
{ \
|
||||
if (__wrap_##name##_disabled) \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#endif // LT_UART_SILENT_ENABLED && !LT_UART_SILENT_ALL
|
||||
|
||||
#if LT_UART_SILENT_ALL
|
||||
|
||||
#define WRAP_PRINTF(name) \
|
||||
WRAP_DISABLE_DECL(name) \
|
||||
int __wrap_##name(const char *format, ...) { \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#define WRAP_VPRINTF(name) \
|
||||
WRAP_DISABLE_DECL(name) \
|
||||
int __wrap_##name(const char *format, va_list arg) { \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#else // !LT_UART_SILENT_ALL
|
||||
|
||||
#define WRAP_PRINTF(name) \
|
||||
WRAP_DISABLE_DECL(name) \
|
||||
int __wrap_##name(const char *format, ...) { \
|
||||
WRAP_DISABLE_CHECK(name); \
|
||||
va_list va; \
|
||||
va_start(va, format); \
|
||||
const int ret = vprintf(format, va); \
|
||||
va_end(va); \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
#define WRAP_VPRINTF(name) \
|
||||
WRAP_DISABLE_DECL(name) \
|
||||
int __wrap_##name(const char *format, va_list arg) { \
|
||||
WRAP_DISABLE_CHECK(name); \
|
||||
return vprintf(format, arg); \
|
||||
}
|
||||
|
||||
#endif // !LT_UART_SILENT_ALL
|
||||
|
||||
#define WRAP_SPRINTF(name) \
|
||||
int __wrap_##name(char *s, const char *format, ...) { \
|
||||
va_list va; \
|
||||
va_start(va, format); \
|
||||
const int ret = vsprintf(s, format, va); \
|
||||
va_end(va); \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
#define WRAP_SNPRINTF(name) \
|
||||
int __wrap_##name(char *s, size_t count, const char *format, ...) { \
|
||||
va_list va; \
|
||||
va_start(va, format); \
|
||||
const int ret = vsnprintf(s, count, format, va); \
|
||||
va_end(va); \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
#define WRAP_VSPRINTF(name) \
|
||||
int __wrap_##name(char *s, const char *format, va_list arg) { \
|
||||
return vsprintf(s, format, arg); \
|
||||
}
|
||||
|
||||
#define WRAP_VSNPRINTF(name) \
|
||||
int __wrap_##name(char *s, size_t count, const char *format, va_list arg) { \
|
||||
return vsnprintf(s, count, format, arg); \
|
||||
}
|
||||
65
cores/common/base/lt_api.c
Normal file
65
cores/common/base/lt_api.c
Normal file
@@ -0,0 +1,65 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2022-04-29. */
|
||||
|
||||
#include "LibreTuyaAPI.h"
|
||||
|
||||
String ipToString(const IPAddress &ip) {
|
||||
char szRet[16];
|
||||
sprintf(szRet, "%hhu.%hhu.%hhu.%hhu", ip[0], ip[1], ip[2], ip[3]);
|
||||
return String(szRet);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Generate random bytes using rand().
|
||||
*
|
||||
* @param buf destination pointer
|
||||
* @param len how many bytes to generate
|
||||
*/
|
||||
extern "C" {
|
||||
void lt_rand_bytes(uint8_t *buf, size_t len) {
|
||||
int *data = (int *)buf;
|
||||
size_t i;
|
||||
for (i = 0; len >= sizeof(int); len -= sizeof(int)) {
|
||||
data[i++] = rand();
|
||||
}
|
||||
if (len) {
|
||||
int rem = rand();
|
||||
unsigned char *pRem = (unsigned char *)&rem;
|
||||
memcpy(buf + i * sizeof(int), pRem, len);
|
||||
}
|
||||
}
|
||||
|
||||
#undef putchar
|
||||
|
||||
/**
|
||||
* @brief Print data pointed to by buf in hexdump-like format (hex+ASCII).
|
||||
*
|
||||
* @param buf source pointer
|
||||
* @param len how many bytes to print
|
||||
* @param offset increment printed offset by this value
|
||||
* @param width how many bytes on a line
|
||||
*/
|
||||
void hexdump(const uint8_t *buf, size_t len, uint32_t offset, uint8_t width) {
|
||||
uint16_t pos = 0;
|
||||
while (pos < len) {
|
||||
// print hex offset
|
||||
printf("%06x ", offset + pos);
|
||||
// calculate current line width
|
||||
uint8_t lineWidth = min(width, len - pos);
|
||||
// print hexadecimal representation
|
||||
for (uint8_t i = 0; i < lineWidth; i++) {
|
||||
if (i % 8 == 0) {
|
||||
printf(" ");
|
||||
}
|
||||
printf("%02x ", buf[pos + i]);
|
||||
}
|
||||
// print ascii representation
|
||||
printf(" |");
|
||||
for (uint8_t i = 0; i < lineWidth; i++) {
|
||||
char c = buf[pos + i];
|
||||
putchar((c >= 0x20 && c <= 0x7f) ? c : '.');
|
||||
}
|
||||
puts("|\r");
|
||||
pos += lineWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
80
cores/common/base/lt_api.h
Normal file
80
cores/common/base/lt_api.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2022-04-28. */
|
||||
|
||||
#pragma once
|
||||
|
||||
// C standard libraries
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// C++ standard libraries
|
||||
#ifdef __cplusplus
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
using ::round;
|
||||
using std::abs;
|
||||
using std::isinf;
|
||||
using std::isnan;
|
||||
using std::max;
|
||||
using std::min;
|
||||
#endif
|
||||
|
||||
// LibreTuya version macros
|
||||
#ifndef LT_VERSION
|
||||
#define LT_VERSION 1.0.0
|
||||
#endif
|
||||
#ifndef LT_BOARD
|
||||
#define LT_BOARD unknown
|
||||
#endif
|
||||
#define STRINGIFY(x) #x
|
||||
#define STRINGIFY_MACRO(x) STRINGIFY(x)
|
||||
#define LT_VERSION_STR STRINGIFY_MACRO(LT_VERSION)
|
||||
#define LT_BOARD_STR STRINGIFY_MACRO(LT_BOARD)
|
||||
|
||||
// Includes
|
||||
#include "LibreTuyaClass.h" // global LT class
|
||||
#include "LibreTuyaCompat.h" // compatibility methods
|
||||
#include "LibreTuyaConfig.h" // configuration macros
|
||||
#include "LibreTuyaCustom.h" // family-defined methods (Wiring custom)
|
||||
#include <Arduino.h>
|
||||
|
||||
// C includes
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
#include "lt_logger.h"
|
||||
#include "lt_posix_api.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
// Functional macros
|
||||
#define LT_BANNER() \
|
||||
LT_LOG( \
|
||||
LT_LEVEL_INFO, \
|
||||
__FUNCTION__, \
|
||||
__LINE__, \
|
||||
"LibreTuya v" LT_VERSION_STR " on " LT_BOARD_STR ", compiled at " __DATE__ " " __TIME__ \
|
||||
)
|
||||
|
||||
#ifdef __cplusplus
|
||||
String ipToString(const IPAddress &ip);
|
||||
|
||||
extern "C" {
|
||||
void lt_rand_bytes(uint8_t *buf, size_t len);
|
||||
void hexdump(const uint8_t *buf, size_t len, uint32_t offset = 0, uint8_t width = 16);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void lt_rand_bytes(uint8_t *buf, size_t len);
|
||||
void hexdump(const uint8_t *buf, size_t len, uint32_t offset, uint8_t width);
|
||||
|
||||
#endif
|
||||
35
cores/common/base/lt_chip.h
Normal file
35
cores/common/base/lt_chip.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2022-05-28. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#define CHIP_TYPE(family, chip_id) (((family >> 24) << 8) | chip_id)
|
||||
#define CHIP_TYPE_ENUM(family, chip_id) (ChipType) CHIP_TYPE(family, chip_id)
|
||||
|
||||
enum ChipFamily {
|
||||
// used in UF2 Family ID
|
||||
F_RTL8710A = 0x9FFFD543, // Realtek Ameba1
|
||||
F_RTL8710B = 0x22E0D6FC, // Realtek AmebaZ (realtek-ambz)
|
||||
F_RTL8720C = 0xE08F7564, // Realtek AmebaZ2
|
||||
F_RTL8720D = 0x3379CFE2, // Realtek AmebaD
|
||||
F_BK7231U = 0x675A40B0, // Beken 7231U/7231T
|
||||
F_BK7231N = 0x7B3EF230, // Beken 7231N
|
||||
F_BK7251 = 0x6A82CC42, // Beken 7251/7252
|
||||
F_BL60X = 0xDE1270B7, // Boufallo 602
|
||||
};
|
||||
|
||||
enum ChipType {
|
||||
// Realtek AmebaZ
|
||||
// IDs copied from rtl8710b_efuse.h
|
||||
RTL8710BL = CHIP_TYPE(F_RTL8710B, 0xE0), // ???
|
||||
RTL8710BN = CHIP_TYPE(F_RTL8710B, 0xFF), // CHIPID_8710BN / QFN32
|
||||
RTL8710BU = CHIP_TYPE(F_RTL8710B, 0xFE), // CHIPID_8710BU / QFN48
|
||||
RTL8710BX = CHIP_TYPE(F_RTL8710B, 0xF6), // found on an actual RTL8710BX
|
||||
RTL8710L0 = CHIP_TYPE(F_RTL8710B, 0xFB), // CHIPID_8710BN_L0 / QFN32
|
||||
RTL8711BN = CHIP_TYPE(F_RTL8710B, 0xFD), // CHIPID_8711BN / QFN48
|
||||
RTL8711BU = CHIP_TYPE(F_RTL8710B, 0xFC), // CHIPID_8711BG / QFN68
|
||||
// Beken 72XX
|
||||
BK7231T = CHIP_TYPE(F_BK7231U, 0x1A), // *SCTRL_CHIP_ID = 0x7231a
|
||||
BK7231N = CHIP_TYPE(F_BK7231N, 0x1C), // *SCTRL_CHIP_ID = 0x7231c
|
||||
BL2028N = CHIP_TYPE(F_BK7231N, 0x1C), // *SCTRL_CHIP_ID = 0x7231c
|
||||
BK7252 = CHIP_TYPE(F_BK7251, 0x00), // TODO
|
||||
};
|
||||
132
cores/common/base/lt_config.h
Normal file
132
cores/common/base/lt_config.h
Normal file
@@ -0,0 +1,132 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2022-04-28. */
|
||||
|
||||
#pragma once
|
||||
|
||||
// see docs/API Configuration
|
||||
|
||||
// Loglevels
|
||||
#define LT_LEVEL_VERBOSE LT_LEVEL_TRACE
|
||||
#define LT_LEVEL_TRACE 0
|
||||
#define LT_LEVEL_DEBUG 1
|
||||
#define LT_LEVEL_INFO 2
|
||||
#define LT_LEVEL_WARN 3
|
||||
#define LT_LEVEL_ERROR 4
|
||||
#define LT_LEVEL_FATAL 5
|
||||
#define LT_LEVEL_NONE 6
|
||||
|
||||
// Logger enabled/disabled
|
||||
#ifndef LT_LOGGER
|
||||
#define LT_LOGGER 1
|
||||
#endif
|
||||
|
||||
// Logger format options
|
||||
#ifndef LT_LOGGER_TIMESTAMP
|
||||
#define LT_LOGGER_TIMESTAMP 1
|
||||
#endif
|
||||
|
||||
#ifndef LT_LOGGER_CALLER
|
||||
#define LT_LOGGER_CALLER 0
|
||||
#endif
|
||||
|
||||
#ifndef LT_LOGGER_TASK
|
||||
#define LT_LOGGER_TASK 0
|
||||
#endif
|
||||
|
||||
#ifndef LT_LOGGER_COLOR
|
||||
#define LT_LOGGER_COLOR 0
|
||||
#endif
|
||||
|
||||
#ifndef LT_PRINTF_BROKEN
|
||||
#define LT_PRINTF_BROKEN 0
|
||||
#endif
|
||||
|
||||
// Global loglevel
|
||||
#ifndef LT_LOGLEVEL
|
||||
#define LT_LOGLEVEL LT_LEVEL_INFO
|
||||
#endif
|
||||
|
||||
#if !LT_LOGGER
|
||||
#undef LT_LOGLEVEL
|
||||
#define LT_LOGLEVEL LT_LEVEL_NONE
|
||||
#endif
|
||||
|
||||
// Free heap size debugging
|
||||
#ifndef LT_LOG_HEAP
|
||||
#define LT_LOG_HEAP 0
|
||||
#endif
|
||||
|
||||
// Debug errno values using LT_ERRNO()
|
||||
#ifndef LT_LOG_ERRNO
|
||||
#define LT_LOG_ERRNO 0
|
||||
#endif
|
||||
|
||||
// Serial output options
|
||||
#ifndef LT_UART_SILENT_ENABLED
|
||||
#define LT_UART_SILENT_ENABLED 1
|
||||
#endif
|
||||
|
||||
#ifndef LT_UART_SILENT_ALL
|
||||
#define LT_UART_SILENT_ALL 0
|
||||
#endif
|
||||
|
||||
#ifndef LT_UART_DEFAULT_LOGGER
|
||||
#define LT_UART_DEFAULT_LOGGER LT_UART_DEFAULT_PORT
|
||||
#endif
|
||||
|
||||
#ifndef LT_UART_DEFAULT_SERIAL
|
||||
#define LT_UART_DEFAULT_SERIAL LT_UART_DEFAULT_PORT
|
||||
#endif
|
||||
|
||||
// Misc options
|
||||
#ifndef LT_USE_TIME
|
||||
#define LT_USE_TIME 0
|
||||
#endif
|
||||
|
||||
#ifndef LT_MICROS_HIGH_RES // NOTE: this is also defined in fixups/clock_rtos.c
|
||||
#define LT_MICROS_HIGH_RES 1
|
||||
#endif
|
||||
|
||||
#ifndef LT_AUTO_DOWNLOAD_REBOOT
|
||||
#define LT_AUTO_DOWNLOAD_REBOOT 1
|
||||
#endif
|
||||
|
||||
// Per-module logging output - applies to all loglevels
|
||||
#ifndef LT_DEBUG_ALL
|
||||
#define LT_DEBUG_ALL 0
|
||||
#endif
|
||||
|
||||
#ifndef LT_DEBUG_WIFI
|
||||
#define LT_DEBUG_WIFI 1
|
||||
#endif
|
||||
|
||||
#ifndef LT_DEBUG_CLIENT
|
||||
#define LT_DEBUG_CLIENT LT_DEBUG_ALL
|
||||
#endif
|
||||
|
||||
#ifndef LT_DEBUG_SERVER
|
||||
#define LT_DEBUG_SERVER LT_DEBUG_ALL
|
||||
#endif
|
||||
|
||||
#ifndef LT_DEBUG_SSL
|
||||
#define LT_DEBUG_SSL LT_DEBUG_ALL
|
||||
#endif
|
||||
|
||||
#ifndef LT_DEBUG_OTA
|
||||
#define LT_DEBUG_OTA 1
|
||||
#endif
|
||||
|
||||
#ifndef LT_DEBUG_FDB
|
||||
#define LT_DEBUG_FDB 0
|
||||
#endif
|
||||
|
||||
#ifndef LT_DEBUG_MDNS
|
||||
#define LT_DEBUG_MDNS LT_DEBUG_ALL
|
||||
#endif
|
||||
|
||||
#ifndef LT_DEBUG_LWIP
|
||||
#define LT_DEBUG_LWIP 0
|
||||
#endif
|
||||
|
||||
#ifndef LT_DEBUG_LWIP_ASSERT
|
||||
#define LT_DEBUG_LWIP_ASSERT 0
|
||||
#endif
|
||||
145
cores/common/base/lt_logger.c
Normal file
145
cores/common/base/lt_logger.c
Normal file
@@ -0,0 +1,145 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2022-04-28. */
|
||||
|
||||
#include "lt_logger.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <printf/printf.h>
|
||||
|
||||
#if LT_LOGGER_TASK && LT_HAS_FREERTOS
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
#endif
|
||||
|
||||
#define COLOR_FMT "\e[0;30m"
|
||||
#define COLOR_BLACK 0x00
|
||||
#define COLOR_RED 0x01
|
||||
#define COLOR_GREEN 0x02
|
||||
#define COLOR_YELLOW 0x03
|
||||
#define COLOR_BLUE 0x04
|
||||
#define COLOR_MAGENTA 0x05
|
||||
#define COLOR_CYAN 0x06
|
||||
#define COLOR_WHITE 0x07
|
||||
#define COLOR_BRIGHT_BLACK 0x10
|
||||
#define COLOR_BRIGHT_RED 0x11
|
||||
#define COLOR_BRIGHT_GREEN 0x12
|
||||
#define COLOR_BRIGHT_YELLOW 0x13
|
||||
#define COLOR_BRIGHT_BLUE 0x14
|
||||
#define COLOR_BRIGHT_MAGENTA 0x15
|
||||
#define COLOR_BRIGHT_CYAN 0x16
|
||||
#define COLOR_BRIGHT_WHITE 0x17
|
||||
|
||||
static uint32_t uart_port = LT_UART_DEFAULT_LOGGER;
|
||||
static const char levels[] = {'V', 'D', 'I', 'W', 'E', 'F'};
|
||||
|
||||
#if LT_LOGGER_COLOR
|
||||
static const uint8_t colors[] = {
|
||||
COLOR_BRIGHT_CYAN,
|
||||
COLOR_BRIGHT_BLUE,
|
||||
COLOR_BRIGHT_GREEN,
|
||||
COLOR_BRIGHT_YELLOW,
|
||||
COLOR_BRIGHT_RED,
|
||||
COLOR_BRIGHT_MAGENTA,
|
||||
};
|
||||
#endif
|
||||
|
||||
unsigned long millis(void);
|
||||
|
||||
#if LT_LOGGER_CALLER
|
||||
void lt_log(const uint8_t level, const char *caller, const unsigned short line, const char *format, ...) {
|
||||
#else
|
||||
void lt_log(const uint8_t level, const char *format, ...) {
|
||||
#endif
|
||||
|
||||
if (uart_port == 0xFF)
|
||||
return;
|
||||
|
||||
#if LT_LOGGER_TIMESTAMP
|
||||
float seconds = millis() / 1000.0f;
|
||||
#if LT_PRINTF_BROKEN
|
||||
char zero[4] = "\x00\x30\x30";
|
||||
if (seconds == 0.0f)
|
||||
zero[0] = '0';
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if LT_LOGGER_TASK && LT_HAS_FREERTOS
|
||||
char task_colon = ':';
|
||||
TaskHandle_t task = xTaskGetCurrentTaskHandle();
|
||||
char *task_name = pcTaskGetTaskName(task);
|
||||
if (!task) {
|
||||
task_name = "";
|
||||
task_colon = '-';
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LT_LOGGER_COLOR
|
||||
char c_bright = '0' + (colors[level] >> 4);
|
||||
char c_value = '0' + (colors[level] & 0x7);
|
||||
#endif
|
||||
|
||||
fctprintf(
|
||||
(void (*)(char, void *))putchar_p,
|
||||
(void *)uart_port,
|
||||
// format:
|
||||
#if LT_LOGGER_COLOR
|
||||
"\e[%c;3%cm"
|
||||
#endif
|
||||
"%c "
|
||||
#if LT_LOGGER_TIMESTAMP
|
||||
#if LT_PRINTF_BROKEN
|
||||
"[%11.3f%s] "
|
||||
#else
|
||||
"[%11.3f] "
|
||||
#endif
|
||||
#endif
|
||||
#if LT_LOGGER_COLOR
|
||||
"\e[0m"
|
||||
#endif
|
||||
#if LT_LOGGER_CALLER
|
||||
"%s():%hu: "
|
||||
#endif
|
||||
#if LT_LOGGER_TASK && LT_HAS_FREERTOS
|
||||
"%s%c "
|
||||
#endif
|
||||
,
|
||||
// arguments:
|
||||
#if LT_LOGGER_COLOR
|
||||
c_bright, // whether text is bright
|
||||
c_value, // text color
|
||||
#endif
|
||||
levels[level]
|
||||
#if LT_LOGGER_TIMESTAMP
|
||||
,
|
||||
seconds // float
|
||||
#if LT_PRINTF_BROKEN
|
||||
,
|
||||
zero // append missing zeroes if printf "%11.3f" prints "0."
|
||||
#endif
|
||||
#endif
|
||||
#if LT_LOGGER_CALLER
|
||||
,
|
||||
caller,
|
||||
line
|
||||
#endif
|
||||
#if LT_LOGGER_TASK && LT_HAS_FREERTOS
|
||||
,
|
||||
task_name,
|
||||
task_colon // printing outside of tasks
|
||||
#endif
|
||||
);
|
||||
|
||||
va_list va_args;
|
||||
va_start(va_args, format);
|
||||
vfctprintf((void (*)(char, void *))putchar_p, (void *)uart_port, format, va_args);
|
||||
va_end(va_args);
|
||||
putchar_p('\r', uart_port);
|
||||
putchar_p('\n', uart_port);
|
||||
}
|
||||
|
||||
void lt_log_set_port(uint8_t port) {
|
||||
uart_port = port;
|
||||
}
|
||||
|
||||
void lt_log_disable() {
|
||||
uart_port = 0xFF;
|
||||
}
|
||||
170
cores/common/base/lt_logger.h
Normal file
170
cores/common/base/lt_logger.h
Normal file
@@ -0,0 +1,170 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2022-04-28. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "LibreTuyaConfig.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#if LT_LOGGER_CALLER
|
||||
#define LT_LOG(level, caller, line, ...) lt_log(level, caller, line, __VA_ARGS__)
|
||||
#define LT_LOGM(level, module, caller, line, ...) \
|
||||
do { \
|
||||
if (LT_DEBUG_##module) { \
|
||||
lt_log(level, caller, line, #module ": " __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
void lt_log(const uint8_t level, const char *caller, const unsigned short line, const char *format, ...)
|
||||
__attribute__((format(printf, 4, 5)));
|
||||
#else
|
||||
#define LT_LOG(level, caller, line, ...) lt_log(level, __VA_ARGS__)
|
||||
#define LT_LOGM(level, module, caller, line, ...) \
|
||||
do { \
|
||||
if (LT_DEBUG_##module) { \
|
||||
lt_log(level, #module ": " __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
void lt_log(const uint8_t level, const char *format, ...) __attribute__((format(printf, 2, 3)));
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Change log output port.
|
||||
*
|
||||
* @param port UART port index - can be 0, 1 or 2
|
||||
*/
|
||||
void lt_log_set_port(uint8_t port);
|
||||
|
||||
/**
|
||||
* @brief Disable LT logger. Enable it back using lt_log_set_port(LT_UART_DEFAULT_LOGGER).
|
||||
*/
|
||||
void lt_log_disable();
|
||||
|
||||
#if LT_LEVEL_TRACE >= LT_LOGLEVEL
|
||||
#define LT_T(...) LT_LOG(LT_LEVEL_TRACE, __FUNCTION__, __LINE__, __VA_ARGS__)
|
||||
#define LT_V(...) LT_LOG(LT_LEVEL_TRACE, __FUNCTION__, __LINE__, __VA_ARGS__)
|
||||
#define LT_TM(module, ...) LT_LOGM(LT_LEVEL_TRACE, module, __FUNCTION__, __LINE__, __VA_ARGS__)
|
||||
#define LT_VM(module, ...) LT_LOGM(LT_LEVEL_TRACE, module, __FUNCTION__, __LINE__, __VA_ARGS__)
|
||||
#else
|
||||
#define LT_T(...)
|
||||
#define LT_V(...)
|
||||
#define LT_TM(...)
|
||||
#define LT_VM(...)
|
||||
#endif
|
||||
|
||||
#if LT_LEVEL_DEBUG >= LT_LOGLEVEL
|
||||
#define LT_D(...) LT_LOG(LT_LEVEL_DEBUG, __FUNCTION__, __LINE__, __VA_ARGS__)
|
||||
#define LT_DM(module, ...) LT_LOGM(LT_LEVEL_DEBUG, module, __FUNCTION__, __LINE__, __VA_ARGS__)
|
||||
#else
|
||||
#define LT_D(...)
|
||||
#define LT_DM(...)
|
||||
#endif
|
||||
|
||||
#if LT_LEVEL_INFO >= LT_LOGLEVEL
|
||||
#define LT_I(...) LT_LOG(LT_LEVEL_INFO, __FUNCTION__, __LINE__, __VA_ARGS__)
|
||||
#define LT_IM(module, ...) LT_LOGM(LT_LEVEL_INFO, module, __FUNCTION__, __LINE__, __VA_ARGS__)
|
||||
#else
|
||||
#define LT_I(...)
|
||||
#define LT_IM(...)
|
||||
#endif
|
||||
|
||||
#if LT_LEVEL_WARN >= LT_LOGLEVEL
|
||||
#define LT_W(...) LT_LOG(LT_LEVEL_WARN, __FUNCTION__, __LINE__, __VA_ARGS__)
|
||||
#define LT_WM(module, ...) LT_LOGM(LT_LEVEL_WARN, module, __FUNCTION__, __LINE__, __VA_ARGS__)
|
||||
#else
|
||||
#define LT_W(...)
|
||||
#define LT_WM(...)
|
||||
#endif
|
||||
|
||||
#if LT_LEVEL_ERROR >= LT_LOGLEVEL
|
||||
#define LT_E(...) LT_LOG(LT_LEVEL_ERROR, __FUNCTION__, __LINE__, __VA_ARGS__)
|
||||
#define LT_EM(module, ...) LT_LOGM(LT_LEVEL_ERROR, module, __FUNCTION__, __LINE__, __VA_ARGS__)
|
||||
#else
|
||||
#define LT_E(...)
|
||||
#define LT_EM(...)
|
||||
#endif
|
||||
|
||||
#if LT_LEVEL_FATAL >= LT_LOGLEVEL
|
||||
#define LT_F(...) LT_LOG(LT_LEVEL_FATAL, __FUNCTION__, __LINE__, __VA_ARGS__)
|
||||
#define LT_FM(module, ...) LT_LOGM(LT_LEVEL_FATAL, module, __FUNCTION__, __LINE__, __VA_ARGS__)
|
||||
#else
|
||||
#define LT_F(...)
|
||||
#define LT_FM(...)
|
||||
#endif
|
||||
|
||||
#if LT_LOG_HEAP
|
||||
#define LT_HEAP_I() LT_I("Free heap: %u", LT_HEAP_FUNC());
|
||||
#else
|
||||
#define LT_HEAP_I()
|
||||
#endif
|
||||
|
||||
// ESP32 compat
|
||||
#define log_printf(...) LT_I(__VA_ARGS__)
|
||||
#define log_v(...) LT_V(__VA_ARGS__)
|
||||
#define log_d(...) LT_D(__VA_ARGS__)
|
||||
#define log_i(...) LT_I(__VA_ARGS__)
|
||||
#define log_w(...) LT_W(__VA_ARGS__)
|
||||
#define log_e(...) LT_E(__VA_ARGS__)
|
||||
#define log_n(...) LT_E(__VA_ARGS__)
|
||||
#define isr_log_v(...) LT_V(__VA_ARGS__)
|
||||
#define isr_log_d(...) LT_D(__VA_ARGS__)
|
||||
#define isr_log_i(...) LT_I(__VA_ARGS__)
|
||||
#define isr_log_w(...) LT_W(__VA_ARGS__)
|
||||
#define isr_log_e(...) LT_E(__VA_ARGS__)
|
||||
#define isr_log_n(...) LT_E(__VA_ARGS__)
|
||||
#define ESP_LOGV(...) LT_V(__VA_ARGS__)
|
||||
#define ESP_LOGD(...) LT_D(__VA_ARGS__)
|
||||
#define ESP_LOGI(...) LT_I(__VA_ARGS__)
|
||||
#define ESP_LOGW(...) LT_W(__VA_ARGS__)
|
||||
#define ESP_LOGE(...) LT_E(__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGV(...) LT_V(__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGD(...) LT_D(__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGI(...) LT_I(__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGW(...) LT_W(__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGE(...) LT_E(__VA_ARGS__)
|
||||
#define ets_printf(...) LT_I(__VA_ARGS__)
|
||||
#define ETS_PRINTF(...) LT_I(__VA_ARGS__)
|
||||
|
||||
#define LT_RET(ret) \
|
||||
LT_E("ret=%d", ret); \
|
||||
return ret;
|
||||
|
||||
#define LT_RET_NZ(ret) \
|
||||
if (ret) { \
|
||||
LT_E("ret=%d", ret); \
|
||||
return ret; \
|
||||
}
|
||||
#define LT_RET_LZ(ret) \
|
||||
if (ret < 0) { \
|
||||
LT_E("ret=%d", ret); \
|
||||
return ret; \
|
||||
}
|
||||
#define LT_RET_LEZ(ret) \
|
||||
if (ret <= 0) { \
|
||||
LT_E("ret=%d", ret); \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
#define LT_ERRNO_NZ(ret) \
|
||||
if (ret) { \
|
||||
LT_E("errno=%d, ret=%d", errno, ret); \
|
||||
return ret; \
|
||||
}
|
||||
#define LT_ERRNO_LZ(ret) \
|
||||
if (ret < 0) { \
|
||||
LT_E("errno=%d, ret=%d", errno, ret); \
|
||||
return ret; \
|
||||
}
|
||||
#define LT_ERRNO_LEZ(ret) \
|
||||
if (ret <= 0) { \
|
||||
LT_E("errno=%d, ret=%d", errno, ret); \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
#if LT_LOG_ERRNO
|
||||
#define LT_ERRNO() \
|
||||
if (errno) { \
|
||||
LT_E("errno=%d", errno); \
|
||||
errno = 0; \
|
||||
}
|
||||
#else
|
||||
#define LT_ERRNO()
|
||||
#endif
|
||||
74
cores/common/base/lt_main.c
Normal file
74
cores/common/base/lt_main.c
Normal file
@@ -0,0 +1,74 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2022-06-19. */
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <api/HardwareSerial.h>
|
||||
|
||||
using namespace arduino;
|
||||
|
||||
extern "C" {
|
||||
#include <fal.h>
|
||||
fal_partition_t fal_root_part = NULL;
|
||||
}
|
||||
|
||||
// Arduino framework initialization.
|
||||
// May be redefined by family files.
|
||||
void initArduino() __attribute__((weak));
|
||||
|
||||
// Weak empty variant initialization function.
|
||||
// May be redefined by variant files.
|
||||
void initVariant() __attribute__((weak));
|
||||
|
||||
// Initialize C library
|
||||
extern "C" void __libc_init_array(void);
|
||||
|
||||
void mainTask(const void *arg) {
|
||||
setup();
|
||||
|
||||
for (;;) {
|
||||
loop();
|
||||
if (serialEventRun)
|
||||
serialEventRun();
|
||||
yield();
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned long periodicTasks[] = {0, 0};
|
||||
|
||||
void runPeriodicTasks() {
|
||||
#if LT_LOG_HEAP
|
||||
if (millis() - periodicTasks[0] > 1000) {
|
||||
LT_HEAP_I();
|
||||
periodicTasks[0] = millis();
|
||||
}
|
||||
#endif
|
||||
#if LT_USE_TIME
|
||||
if (millis() - periodicTasks[1] > 10000) {
|
||||
gettimeofday(NULL, NULL);
|
||||
periodicTasks[1] = millis();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
// print a startup banner
|
||||
LT_BANNER();
|
||||
// initialize C library
|
||||
__libc_init_array();
|
||||
// inform about the reset reason
|
||||
LT_I("Reset reason: %u", LT.getResetReason());
|
||||
// initialize Arduino framework
|
||||
initArduino();
|
||||
// optionally initialize per-variant code
|
||||
initVariant();
|
||||
// initialize FAL
|
||||
fal_init();
|
||||
// provide root partition
|
||||
fal_root_part = (fal_partition_t)fal_partition_find("root");
|
||||
// start the main task and OS kernel
|
||||
if (!startMainTask()) {
|
||||
LT_F("Couldn't start the main task");
|
||||
}
|
||||
|
||||
while (1) {}
|
||||
return 0;
|
||||
}
|
||||
7
cores/common/base/lt_posix_api.h
Normal file
7
cores/common/base/lt_posix_api.h
Normal file
@@ -0,0 +1,7 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2022-05-16. */
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
extern char *strdup(const char *);
|
||||
extern int strcasecmp(const char *s1, const char *s2);
|
||||
extern int strncasecmp(const char *s1, const char *s2, size_t n);
|
||||
2
cores/common/base/posix/.clang-format
Normal file
2
cores/common/base/posix/.clang-format
Normal file
@@ -0,0 +1,2 @@
|
||||
DisableFormat: true
|
||||
SortIncludes: Never
|
||||
111
cores/common/base/posix/itoa.c
Normal file
111
cores/common/base/posix/itoa.c
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
Copyright (c) 2014 Arduino LLC. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
char *ltoa(long value, char *string, int radix) {
|
||||
char tmp[33];
|
||||
char *tp = tmp;
|
||||
long i;
|
||||
unsigned long v;
|
||||
int sign;
|
||||
char *sp;
|
||||
|
||||
if (string == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (radix > 36 || radix <= 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
sign = (radix == 10 && value < 0);
|
||||
if (sign) {
|
||||
v = -value;
|
||||
} else {
|
||||
v = (unsigned long)value;
|
||||
}
|
||||
|
||||
while (v || tp == tmp) {
|
||||
i = v % radix;
|
||||
v = v / radix;
|
||||
if (i < 10)
|
||||
*tp++ = i + '0';
|
||||
else
|
||||
*tp++ = i + 'a' - 10;
|
||||
}
|
||||
|
||||
sp = string;
|
||||
|
||||
if (sign)
|
||||
*sp++ = '-';
|
||||
while (tp > tmp)
|
||||
*sp++ = *--tp;
|
||||
*sp = 0;
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
char *ultoa(unsigned long value, char *string, int radix) {
|
||||
char tmp[33];
|
||||
char *tp = tmp;
|
||||
long i;
|
||||
unsigned long v = value;
|
||||
char *sp;
|
||||
|
||||
if (string == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (radix > 36 || radix <= 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (v || tp == tmp) {
|
||||
i = v % radix;
|
||||
v = v / radix;
|
||||
if (i < 10)
|
||||
*tp++ = i + '0';
|
||||
else
|
||||
*tp++ = i + 'a' - 10;
|
||||
}
|
||||
|
||||
sp = string;
|
||||
|
||||
while (tp > tmp)
|
||||
*sp++ = *--tp;
|
||||
*sp = 0;
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
char *itoa(int value, char *string, int radix) {
|
||||
return ltoa(value, string, radix);
|
||||
}
|
||||
|
||||
char *utoa(unsigned int value, char *string, int radix) {
|
||||
return ultoa(value, string, radix);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
97
cores/common/base/posix/strcasecmp.c
Normal file
97
cores/common/base/posix/strcasecmp.c
Normal file
@@ -0,0 +1,97 @@
|
||||
/* $OpenBSD: strcasecmp.c,v 1.6 2005/08/08 08:05:37 espie Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1987, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. Neither the name of the University 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 REGENTS 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 THE REGENTS OR CONTRIBUTORS 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 <string.h>
|
||||
typedef unsigned char u_char;
|
||||
/*
|
||||
* This array is designed for mapping upper and lower case letter
|
||||
* together for a case independent comparison. The mappings are
|
||||
* based upon ascii character sequences.
|
||||
*/
|
||||
static const u_char charmap[] = {
|
||||
'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
|
||||
'\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
|
||||
'\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
|
||||
'\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
|
||||
'\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
|
||||
'\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
|
||||
'\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
|
||||
'\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
|
||||
'\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
|
||||
'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
|
||||
'\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
|
||||
'\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
|
||||
'\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
|
||||
'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
|
||||
'\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
|
||||
'\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
|
||||
'\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
|
||||
'\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
|
||||
'\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
|
||||
'\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
|
||||
'\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
|
||||
'\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
|
||||
'\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
|
||||
'\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
|
||||
'\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
|
||||
'\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
|
||||
'\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
|
||||
'\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
|
||||
'\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
|
||||
'\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
|
||||
'\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
|
||||
'\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
|
||||
};
|
||||
int
|
||||
strcasecmp(const char *s1, const char *s2)
|
||||
{
|
||||
const u_char *cm = charmap;
|
||||
const u_char *us1 = (const u_char *)s1;
|
||||
const u_char *us2 = (const u_char *)s2;
|
||||
while (cm[*us1] == cm[*us2++])
|
||||
if (*us1++ == '\0')
|
||||
return (0);
|
||||
return (cm[*us1] - cm[*--us2]);
|
||||
}
|
||||
int
|
||||
strncasecmp(const char *s1, const char *s2, size_t n)
|
||||
{
|
||||
if (n != 0) {
|
||||
const u_char *cm = charmap;
|
||||
const u_char *us1 = (const u_char *)s1;
|
||||
const u_char *us2 = (const u_char *)s2;
|
||||
do {
|
||||
if (cm[*us1] != cm[*us2++])
|
||||
return (cm[*us1] - cm[*--us2]);
|
||||
if (*us1++ == '\0')
|
||||
break;
|
||||
} while (--n != 0);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
12
cores/common/base/posix/strdup.c
Normal file
12
cores/common/base/posix/strdup.c
Normal file
@@ -0,0 +1,12 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2022-05-16. */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <sdk_mem.h>
|
||||
|
||||
__attribute__((weak)) char *strdup(const char *s) {
|
||||
size_t len = strlen(s) + 1;
|
||||
void *newp = malloc(len);
|
||||
if (newp == NULL)
|
||||
return NULL;
|
||||
return (char *)memcpy(newp, s, len);
|
||||
}
|
||||
197
cores/common/base/posix/strptime.c
Normal file
197
cores/common/base/posix/strptime.c
Normal file
@@ -0,0 +1,197 @@
|
||||
#include <stdlib.h>
|
||||
#include <langinfo.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
|
||||
char *strptime(const char *restrict s, const char *restrict f, struct tm *restrict tm)
|
||||
{
|
||||
int i, w, neg, adj, min, range, *dest, dummy;
|
||||
const char *ex;
|
||||
size_t len;
|
||||
int want_century = 0, century = 0;
|
||||
while (*f) {
|
||||
if (*f != '%') {
|
||||
if (isspace(*f)) for (; *s && isspace(*s); s++);
|
||||
else if (*s != *f) return 0;
|
||||
else s++;
|
||||
f++;
|
||||
continue;
|
||||
}
|
||||
f++;
|
||||
if (*f == '+') f++;
|
||||
if (isdigit(*f)) w=strtoul(f, (void *)&f, 10);
|
||||
else w=-1;
|
||||
adj=0;
|
||||
switch (*f++) {
|
||||
case 'a': case 'A':
|
||||
dest = &tm->tm_wday;
|
||||
min = ABDAY_1;
|
||||
range = 7;
|
||||
goto symbolic_range;
|
||||
case 'b': case 'B': case 'h':
|
||||
dest = &tm->tm_mon;
|
||||
min = ABMON_1;
|
||||
range = 12;
|
||||
goto symbolic_range;
|
||||
case 'c':
|
||||
s = strptime(s, nl_langinfo(D_T_FMT), tm);
|
||||
if (!s) return 0;
|
||||
break;
|
||||
case 'C':
|
||||
dest = ¢ury;
|
||||
if (w<0) w=2;
|
||||
want_century |= 2;
|
||||
goto numeric_digits;
|
||||
case 'd': case 'e':
|
||||
dest = &tm->tm_mday;
|
||||
min = 1;
|
||||
range = 31;
|
||||
goto numeric_range;
|
||||
case 'D':
|
||||
s = strptime(s, "%m/%d/%y", tm);
|
||||
if (!s) return 0;
|
||||
break;
|
||||
case 'H':
|
||||
dest = &tm->tm_hour;
|
||||
min = 0;
|
||||
range = 24;
|
||||
goto numeric_range;
|
||||
case 'I':
|
||||
dest = &tm->tm_hour;
|
||||
min = 1;
|
||||
range = 12;
|
||||
goto numeric_range;
|
||||
case 'j':
|
||||
dest = &tm->tm_yday;
|
||||
min = 1;
|
||||
range = 366;
|
||||
goto numeric_range;
|
||||
case 'm':
|
||||
dest = &tm->tm_mon;
|
||||
min = 1;
|
||||
range = 12;
|
||||
adj = 1;
|
||||
goto numeric_range;
|
||||
case 'M':
|
||||
dest = &tm->tm_min;
|
||||
min = 0;
|
||||
range = 60;
|
||||
goto numeric_range;
|
||||
case 'n': case 't':
|
||||
for (; *s && isspace(*s); s++);
|
||||
break;
|
||||
case 'p':
|
||||
ex = nl_langinfo(AM_STR);
|
||||
len = strlen(ex);
|
||||
if (!strncasecmp(s, ex, len)) {
|
||||
tm->tm_hour %= 12;
|
||||
break;
|
||||
}
|
||||
ex = nl_langinfo(PM_STR);
|
||||
len = strlen(ex);
|
||||
if (!strncasecmp(s, ex, len)) {
|
||||
tm->tm_hour %= 12;
|
||||
tm->tm_hour += 12;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
case 'r':
|
||||
s = strptime(s, nl_langinfo(T_FMT_AMPM), tm);
|
||||
if (!s) return 0;
|
||||
break;
|
||||
case 'R':
|
||||
s = strptime(s, "%H:%M", tm);
|
||||
if (!s) return 0;
|
||||
break;
|
||||
case 'S':
|
||||
dest = &tm->tm_sec;
|
||||
min = 0;
|
||||
range = 61;
|
||||
goto numeric_range;
|
||||
case 'T':
|
||||
s = strptime(s, "%H:%M:%S", tm);
|
||||
if (!s) return 0;
|
||||
break;
|
||||
case 'U':
|
||||
case 'W':
|
||||
/* Throw away result, for now. (FIXME?) */
|
||||
dest = &dummy;
|
||||
min = 0;
|
||||
range = 54;
|
||||
goto numeric_range;
|
||||
case 'w':
|
||||
dest = &tm->tm_wday;
|
||||
min = 0;
|
||||
range = 7;
|
||||
goto numeric_range;
|
||||
case 'x':
|
||||
s = strptime(s, nl_langinfo(D_FMT), tm);
|
||||
if (!s) return 0;
|
||||
break;
|
||||
case 'X':
|
||||
s = strptime(s, nl_langinfo(T_FMT), tm);
|
||||
if (!s) return 0;
|
||||
break;
|
||||
case 'y':
|
||||
dest = &tm->tm_year;
|
||||
w = 2;
|
||||
want_century |= 1;
|
||||
goto numeric_digits;
|
||||
case 'Y':
|
||||
dest = &tm->tm_year;
|
||||
if (w<0) w=4;
|
||||
adj = 1900;
|
||||
want_century = 0;
|
||||
goto numeric_digits;
|
||||
case '%':
|
||||
if (*s++ != '%') return 0;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
numeric_range:
|
||||
if (!isdigit(*s)) return 0;
|
||||
*dest = 0;
|
||||
for (i=1; i<=min+range && isdigit(*s); i*=10)
|
||||
*dest = *dest * 10 + *s++ - '0';
|
||||
if (*dest - min >= (unsigned)range) return 0;
|
||||
*dest -= adj;
|
||||
switch((char *)dest - (char *)tm) {
|
||||
case offsetof(struct tm, tm_yday):
|
||||
;
|
||||
}
|
||||
goto update;
|
||||
numeric_digits:
|
||||
neg = 0;
|
||||
if (*s == '+') s++;
|
||||
else if (*s == '-') neg=1, s++;
|
||||
if (!isdigit(*s)) return 0;
|
||||
for (*dest=i=0; i<w && isdigit(*s); i++)
|
||||
*dest = *dest * 10 + *s++ - '0';
|
||||
if (neg) *dest = -*dest;
|
||||
*dest -= adj;
|
||||
goto update;
|
||||
symbolic_range:
|
||||
for (i=2*range-1; i>=0; i--) {
|
||||
ex = nl_langinfo(min+i);
|
||||
len = strlen(ex);
|
||||
if (strncasecmp(s, ex, len)) continue;
|
||||
s += len;
|
||||
*dest = i % range;
|
||||
break;
|
||||
}
|
||||
if (i<0) return 0;
|
||||
goto update;
|
||||
update:
|
||||
//FIXME
|
||||
;
|
||||
}
|
||||
}
|
||||
if (want_century) {
|
||||
if (want_century & 2) tm->tm_year += century * 100 - 1900;
|
||||
else if (tm->tm_year <= 68) tm->tm_year += 100;
|
||||
}
|
||||
return (char *)s;
|
||||
}
|
||||
7
cores/common/base/strptime.h
Normal file
7
cores/common/base/strptime.h
Normal file
@@ -0,0 +1,7 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2022-04-29. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <time.h>
|
||||
|
||||
extern char *strptime(const char *buf, const char *fmt, struct tm *tm);
|
||||
9
cores/common/base/wraps/putchar.c
Normal file
9
cores/common/base/wraps/putchar.c
Normal file
@@ -0,0 +1,9 @@
|
||||
// https://github.com/embeddedartistry/libc/blob/master/src/stdio/putchar.c
|
||||
|
||||
#include <printf/printf.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int __wrap_putchar(int c) {
|
||||
putchar_((char)c);
|
||||
return c;
|
||||
}
|
||||
21
cores/common/base/wraps/puts.c
Normal file
21
cores/common/base/wraps/puts.c
Normal file
@@ -0,0 +1,21 @@
|
||||
// https://github.com/embeddedartistry/libc/blob/master/src/stdio/puts.c
|
||||
|
||||
#include <printf/printf.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int __wrap_puts(const char *str) {
|
||||
int r = 0;
|
||||
|
||||
for (const char *c = str; *c != 0; c++) {
|
||||
putchar_((int)*c);
|
||||
r++;
|
||||
}
|
||||
|
||||
// puts adds a newline
|
||||
if (r) {
|
||||
putchar_('\n');
|
||||
r++;
|
||||
}
|
||||
|
||||
return r ? r : EOF;
|
||||
}
|
||||
Reference in New Issue
Block a user