mirror of
https://github.com/esp8266/Arduino.git
synced 2025-06-13 13:01:55 +03:00
Merge remote-tracking branch 'remotes/esp8266/esp8266' into esp8266
This commit is contained in:
@ -38,9 +38,6 @@ extern "C" {
|
||||
#include "esp8266_peri.h"
|
||||
#include "twi.h"
|
||||
|
||||
void yield(void);
|
||||
void optimistic_yield(void);
|
||||
|
||||
#define HIGH 0x1
|
||||
#define LOW 0x0
|
||||
|
||||
@ -140,8 +137,8 @@ void timer0_detachInterrupt(void);
|
||||
void ets_intr_lock();
|
||||
void ets_intr_unlock();
|
||||
|
||||
// level (0-15),
|
||||
// level 15 will disable ALL interrupts,
|
||||
// level (0-15),
|
||||
// level 15 will disable ALL interrupts,
|
||||
// level 0 will disable most software interrupts
|
||||
//
|
||||
#define xt_disable_interrupts(state, level) __asm__ __volatile__("rsil %0," __STRINGIFY(level) : "=a" (state))
|
||||
@ -207,6 +204,9 @@ void detachInterrupt(uint8_t);
|
||||
void setup(void);
|
||||
void loop(void);
|
||||
|
||||
void yield(void);
|
||||
void optimistic_yield(uint32_t interval_us);
|
||||
|
||||
// Get the bit location within the hardware port of the given virtual pin.
|
||||
// This comes from the pins_*.c file for the active board configuration.
|
||||
#define digitalPinToPort(pin) (0)
|
||||
|
@ -1,9 +1,9 @@
|
||||
/*
|
||||
/*
|
||||
HardwareSerial.cpp - esp8266 UART support
|
||||
|
||||
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
|
||||
This file is part of the esp8266 core for Arduino environment.
|
||||
|
||||
|
||||
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
|
||||
@ -559,7 +559,7 @@ int HardwareSerial::available(void) {
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
optimistic_yield();
|
||||
optimistic_yield(USD(_uart->uart_nr) / 128);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -1,8 +1,8 @@
|
||||
/*
|
||||
/*
|
||||
cont.S - continuations support for Xtensa call0 ABI
|
||||
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
|
||||
This file is part of the esp8266 core for Arduino environment.
|
||||
|
||||
|
||||
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
|
||||
@ -18,106 +18,109 @@
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
.text
|
||||
.align 4
|
||||
.literal_position
|
||||
.global cont_yield
|
||||
.type cont_yield, @function
|
||||
.text
|
||||
.align 4
|
||||
.literal_position
|
||||
.global cont_yield
|
||||
.type cont_yield, @function
|
||||
cont_yield:
|
||||
/* a1: sp */
|
||||
/* a2: void* cont_ctx */
|
||||
/* adjust stack and save registers */
|
||||
addi a1, a1, -24
|
||||
s32i a12, a1, 0
|
||||
s32i a13, a1, 4
|
||||
s32i a14, a1, 8
|
||||
s32i a15, a1, 12
|
||||
s32i a0, a1, 16
|
||||
s32i a2, a1, 20
|
||||
/* a1: sp */
|
||||
/* a2: void* cont_ctx */
|
||||
/* adjust stack and save registers */
|
||||
addi a1, a1, -24
|
||||
s32i a12, a1, 0
|
||||
s32i a13, a1, 4
|
||||
s32i a14, a1, 8
|
||||
s32i a15, a1, 12
|
||||
s32i a0, a1, 16
|
||||
s32i a2, a1, 20
|
||||
|
||||
/* &cont_continue -> cont_ctx.pc_yield */
|
||||
movi a3, cont_continue
|
||||
s32i a3, a2, 8
|
||||
/* sp -> cont_ctx.sp_yield */
|
||||
s32i a1, a2, 12
|
||||
/* &cont_continue -> cont_ctx.pc_yield */
|
||||
movi a3, cont_continue
|
||||
s32i a3, a2, 8
|
||||
/* sp -> cont_ctx.sp_yield */
|
||||
s32i a1, a2, 12
|
||||
|
||||
/* a0 <- cont_ctx.pc_ret */
|
||||
l32i a0, a2, 0
|
||||
/* sp <- cont_ctx.sp_ret */
|
||||
l32i a1, a2, 4
|
||||
jx a0
|
||||
/* a0 <- cont_ctx.pc_ret */
|
||||
l32i a0, a2, 0
|
||||
/* sp <- cont_ctx.sp_ret */
|
||||
l32i a1, a2, 4
|
||||
jx a0
|
||||
|
||||
cont_continue:
|
||||
l32i a12, a1, 0
|
||||
l32i a13, a1, 4
|
||||
l32i a14, a1, 8
|
||||
l32i a15, a1, 12
|
||||
l32i a0, a1, 16
|
||||
l32i a2, a1, 20
|
||||
addi a1, a1, 24
|
||||
ret
|
||||
.size cont_yield, . - cont_yield
|
||||
l32i a12, a1, 0
|
||||
l32i a13, a1, 4
|
||||
l32i a14, a1, 8
|
||||
l32i a15, a1, 12
|
||||
l32i a0, a1, 16
|
||||
l32i a2, a1, 20
|
||||
addi a1, a1, 24
|
||||
ret
|
||||
.size cont_yield, . - cont_yield
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
.text
|
||||
.align 4
|
||||
.literal_position
|
||||
.global cont_run
|
||||
.type cont_run, @function
|
||||
.text
|
||||
.align 4
|
||||
.literal_position
|
||||
.global cont_run
|
||||
.type cont_run, @function
|
||||
cont_run:
|
||||
/* a1: sp */
|
||||
/* a2: void* cont_ctx */
|
||||
/* a3: void (*pfn) */
|
||||
/* a1: sp */
|
||||
/* a2: void* cont_ctx */
|
||||
/* a3: void (*pfn) */
|
||||
|
||||
/* adjust stack and save registers */
|
||||
addi a1, a1, -20
|
||||
s32i a12, a1, 0
|
||||
s32i a13, a1, 4
|
||||
s32i a14, a1, 8
|
||||
s32i a15, a1, 12
|
||||
s32i a0, a1, 16
|
||||
/* adjust stack and save registers */
|
||||
addi a1, a1, -20
|
||||
s32i a12, a1, 0
|
||||
s32i a13, a1, 4
|
||||
s32i a14, a1, 8
|
||||
s32i a15, a1, 12
|
||||
s32i a0, a1, 16
|
||||
|
||||
/* cont_ret -> a4 -> cont_ctx.pc_ret*/
|
||||
movi a4, cont_ret
|
||||
s32i a4, a2, 0
|
||||
/* sp -> cont_ctx.sp_ret */
|
||||
s32i a1, a2, 4
|
||||
/* cont_ret -> a4 -> cont_ctx.pc_ret*/
|
||||
movi a4, cont_ret
|
||||
s32i a4, a2, 0
|
||||
/* sp -> cont_ctx.sp_ret */
|
||||
s32i a1, a2, 4
|
||||
|
||||
/* if cont_ctx.pc_yield != 0, goto cont_resume */
|
||||
l32i a4, a2, 8
|
||||
bnez a4, cont_resume
|
||||
/* else */
|
||||
/* set new stack*/
|
||||
l32i a1, a2, 16;
|
||||
/* goto pfn */
|
||||
movi a0, cont_norm
|
||||
jx a3
|
||||
/* if cont_ctx.pc_yield != 0, goto cont_resume */
|
||||
l32i a4, a2, 8
|
||||
bnez a4, cont_resume
|
||||
/* else */
|
||||
/* set new stack*/
|
||||
l32i a1, a2, 16;
|
||||
/* goto pfn */
|
||||
movi a0, cont_norm
|
||||
jx a3
|
||||
|
||||
cont_resume:
|
||||
/* a1 <- cont_ctx.sp_yield */
|
||||
l32i a1, a2, 12
|
||||
/* reset yield flag, 0 -> cont_ctx.pc_yield */
|
||||
movi a3, 0
|
||||
s32i a3, a2, 8
|
||||
/* jump to saved cont_ctx.pc_yield */
|
||||
movi a0, cont_ret
|
||||
jx a4
|
||||
/* a1 <- cont_ctx.sp_yield */
|
||||
l32i a1, a2, 12
|
||||
/* reset yield flag, 0 -> cont_ctx.pc_yield */
|
||||
movi a3, 0
|
||||
s32i a3, a2, 8
|
||||
/* jump to saved cont_ctx.pc_yield */
|
||||
movi a0, cont_ret
|
||||
jx a4
|
||||
|
||||
cont_norm:
|
||||
/* calculate pointer to cont_ctx.struct_start from sp */
|
||||
l32i a2, a1, 4
|
||||
/* sp <- cont_ctx.sp_ret */
|
||||
l32i a1, a2, 4
|
||||
/* calculate pointer to cont_ctx.struct_start from sp */
|
||||
l32i a2, a1, 4
|
||||
/* sp <- cont_ctx.sp_ret */
|
||||
l32i a1, a2, 4
|
||||
/* 0 -> cont_ctx.pc_ret */
|
||||
movi a4, 0
|
||||
s32i a4, a2, 0
|
||||
|
||||
cont_ret:
|
||||
/* restore registers */
|
||||
l32i a12, a1, 0
|
||||
l32i a13, a1, 4
|
||||
l32i a14, a1, 8
|
||||
l32i a15, a1, 12
|
||||
l32i a0, a1, 16
|
||||
/* adjust stack and return */
|
||||
addi a1, a1, 20
|
||||
ret
|
||||
.size cont_run, . - cont_run
|
||||
/* restore registers */
|
||||
l32i a12, a1, 0
|
||||
l32i a13, a1, 4
|
||||
l32i a14, a1, 8
|
||||
l32i a15, a1, 12
|
||||
l32i a0, a1, 16
|
||||
/* adjust stack and return */
|
||||
addi a1, a1, 20
|
||||
ret
|
||||
.size cont_run, . - cont_run
|
||||
|
@ -1,8 +1,8 @@
|
||||
/*
|
||||
/*
|
||||
cont.h - continuations support for Xtensa call0 ABI
|
||||
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
|
||||
This file is part of the esp8266 core for Arduino environment.
|
||||
|
||||
|
||||
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
|
||||
@ -21,6 +21,8 @@
|
||||
#ifndef CONT_H_
|
||||
#define CONT_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef CONT_STACKSIZE
|
||||
#define CONT_STACKSIZE 4096
|
||||
#endif
|
||||
@ -58,4 +60,8 @@ void cont_yield(cont_t*);
|
||||
// return 1 if guard bytes were overwritten.
|
||||
int cont_check(cont_t* cont);
|
||||
|
||||
// Check if yield() may be called. Returns true if we are running inside
|
||||
// continuation stack
|
||||
bool cont_can_yield(cont_t* cont);
|
||||
|
||||
#endif /* CONT_H_ */
|
||||
|
@ -1,8 +1,8 @@
|
||||
/*
|
||||
/*
|
||||
cont_util.s - continuations support for Xtensa call0 ABI
|
||||
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
|
||||
This file is part of the esp8266 core for Arduino environment.
|
||||
|
||||
|
||||
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
|
||||
@ -19,6 +19,9 @@
|
||||
*/
|
||||
|
||||
#include "cont.h"
|
||||
#include <stddef.h>
|
||||
#include "ets_sys.h"
|
||||
|
||||
|
||||
#define CONT_STACKGUARD 0xfeefeffe
|
||||
|
||||
@ -34,3 +37,8 @@ int cont_check(cont_t* cont) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool cont_can_yield(cont_t* cont) {
|
||||
return !ETS_INTR_WITHINISR() &&
|
||||
cont->pc_ret != 0 && cont->pc_yield == 0;
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
/*
|
||||
/*
|
||||
main.cpp - platform initialization and context switching
|
||||
emulation
|
||||
|
||||
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
|
||||
This file is part of the esp8266 core for Arduino environment.
|
||||
|
||||
|
||||
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
|
||||
@ -64,16 +64,16 @@ extern void (*__init_array_end)(void);
|
||||
cont_t g_cont __attribute__ ((aligned (16)));
|
||||
static os_event_t g_loop_queue[LOOP_QUEUE_SIZE];
|
||||
|
||||
static uint32_t g_micros_at_last_task_yield;
|
||||
static uint32_t g_micros_at_task_start;
|
||||
|
||||
|
||||
extern "C" void abort() {
|
||||
while(1) {
|
||||
}
|
||||
do {
|
||||
*((int*)0) = 0;
|
||||
} while(true);
|
||||
}
|
||||
|
||||
extern "C" void esp_yield() {
|
||||
g_micros_at_last_task_yield = system_get_time();
|
||||
cont_yield(&g_cont);
|
||||
}
|
||||
|
||||
@ -82,16 +82,22 @@ extern "C" void esp_schedule() {
|
||||
}
|
||||
|
||||
extern "C" void __yield() {
|
||||
esp_schedule();
|
||||
esp_yield();
|
||||
if (cont_can_yield(&g_cont)) {
|
||||
esp_schedule();
|
||||
esp_yield();
|
||||
}
|
||||
else {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void yield(void) __attribute__ ((weak, alias("__yield")));
|
||||
|
||||
extern "C" void optimistic_yield(void) {
|
||||
if (!ETS_INTR_WITHINISR() &&
|
||||
(system_get_time() - g_micros_at_last_task_yield) > OPTIMISTIC_YIELD_TIME_US)
|
||||
extern "C" void optimistic_yield(uint32_t interval_us) {
|
||||
if (cont_can_yield(&g_cont) &&
|
||||
(system_get_time() - g_micros_at_task_start) > interval_us)
|
||||
{
|
||||
__yield();
|
||||
yield();
|
||||
}
|
||||
}
|
||||
|
||||
@ -107,10 +113,10 @@ static void loop_wrapper() {
|
||||
}
|
||||
|
||||
static void loop_task(os_event_t *events) {
|
||||
g_micros_at_last_task_yield = system_get_time();
|
||||
g_micros_at_task_start = system_get_time();
|
||||
cont_run(&g_cont, &loop_wrapper);
|
||||
if(cont_check(&g_cont) != 0) {
|
||||
ets_printf("\r\nheap collided with sketch stack\r\n");
|
||||
ets_printf("\r\nsketch stack overflow detected\r\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
@ -127,13 +133,11 @@ void init_done() {
|
||||
esp_schedule();
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
void user_init(void) {
|
||||
|
||||
extern "C" void user_init(void) {
|
||||
struct rst_info *rtc_info_ptr = system_get_rst_info();
|
||||
|
||||
memcpy((void *) &resetInfo, (void *) rtc_info_ptr, sizeof(resetInfo));
|
||||
|
||||
|
||||
uart_div_modify(0, UART_CLK_FREQ / (115200));
|
||||
|
||||
init();
|
||||
@ -143,10 +147,8 @@ void user_init(void) {
|
||||
cont_init(&g_cont);
|
||||
|
||||
system_os_task(loop_task,
|
||||
LOOP_TASK_PRIORITY, g_loop_queue,
|
||||
LOOP_QUEUE_SIZE);
|
||||
LOOP_TASK_PRIORITY, g_loop_queue,
|
||||
LOOP_QUEUE_SIZE);
|
||||
|
||||
system_init_done_cb(&init_done);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,13 +20,13 @@
|
||||
#include <ctype.h>
|
||||
#include "pgmspace.h"
|
||||
|
||||
size_t strnlen_P(const char* s, size_t size) {
|
||||
size_t strnlen_P(PGM_P s, size_t size) {
|
||||
const char* cp;
|
||||
for (cp = s; size != 0 && pgm_read_byte(cp) != '\0'; cp++, size--);
|
||||
return (size_t) (cp - s);
|
||||
}
|
||||
|
||||
void* memcpy_P(void* dest, const void* src, size_t count) {
|
||||
void* memcpy_P(void* dest, PGM_VOID_P src, size_t count) {
|
||||
const uint8_t* read = reinterpret_cast<const uint8_t*>(src);
|
||||
uint8_t* write = reinterpret_cast<uint8_t*>(dest);
|
||||
|
||||
@ -39,7 +39,83 @@ void* memcpy_P(void* dest, const void* src, size_t count) {
|
||||
return dest;
|
||||
}
|
||||
|
||||
char* strncpy_P(char* dest, const char* src, size_t size) {
|
||||
int memcmp_P(const void* buf1, PGM_VOID_P buf2P, size_t size) {
|
||||
int result = 0;
|
||||
const uint8_t* read1 = (const uint8_t*)buf1;
|
||||
const uint8_t* read2 = (const uint8_t*)buf2P;
|
||||
|
||||
while (size > 0) {
|
||||
uint8_t ch2 = pgm_read_byte(read2);
|
||||
uint8_t ch1 = *read1;
|
||||
if (ch1 != ch2) {
|
||||
result = (int)(ch1)-(int)(ch2);
|
||||
break;
|
||||
}
|
||||
|
||||
read1++;
|
||||
read2++;
|
||||
size--;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void* memccpy_P(void* dest, PGM_VOID_P src, int c, size_t count) {
|
||||
uint8_t* read = (uint8_t*)src;
|
||||
uint8_t* write = (uint8_t*)dest;
|
||||
void* result = NULL;
|
||||
|
||||
while (count > 0) {
|
||||
uint8_t ch = pgm_read_byte(read++);
|
||||
*write++ = ch;
|
||||
count--;
|
||||
if (c == ch) {
|
||||
return write; // the value after the found c
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void* memmem_P(const void* buf, size_t bufSize, PGM_VOID_P findP, size_t findPSize) {
|
||||
const uint8_t* read = (const uint8_t*)buf;
|
||||
const uint8_t* find = (uint8_t*)findP;
|
||||
uint8_t first = pgm_read_byte(find++);
|
||||
|
||||
findPSize--;
|
||||
|
||||
while (bufSize > 0) {
|
||||
if (*read == first) {
|
||||
size_t findSize = findPSize;
|
||||
const uint8_t* tag = read + 1;
|
||||
size_t tagBufSize = bufSize - 1;
|
||||
const uint8_t* findTag = find;
|
||||
|
||||
while (tagBufSize > 0 && findSize > 0) {
|
||||
uint8_t ch = pgm_read_byte(findTag++);
|
||||
if (ch != *tag) {
|
||||
bufSize--;
|
||||
read++;
|
||||
break;
|
||||
}
|
||||
findSize--;
|
||||
tagBufSize--;
|
||||
tag++;
|
||||
}
|
||||
if (findSize == 0) {
|
||||
return (void*)read;
|
||||
}
|
||||
}
|
||||
else {
|
||||
bufSize--;
|
||||
read++;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
char* strncpy_P(char* dest, PGM_P src, size_t size) {
|
||||
const char* read = src;
|
||||
char* write = dest;
|
||||
char ch = '.';
|
||||
@ -53,7 +129,7 @@ char* strncpy_P(char* dest, const char* src, size_t size) {
|
||||
return dest;
|
||||
}
|
||||
|
||||
char* strncat_P(char* dest, const char* src, size_t size) {
|
||||
char* strncat_P(char* dest, PGM_P src, size_t size) {
|
||||
char* write = dest;
|
||||
|
||||
while (*write != '\0')
|
||||
@ -80,7 +156,7 @@ char* strncat_P(char* dest, const char* src, size_t size) {
|
||||
return dest;
|
||||
}
|
||||
|
||||
int strncmp_P(const char* str1, const char* str2P, size_t size) {
|
||||
int strncmp_P(const char* str1, PGM_P str2P, size_t size) {
|
||||
int result = 0;
|
||||
|
||||
while (size > 0)
|
||||
@ -99,7 +175,7 @@ int strncmp_P(const char* str1, const char* str2P, size_t size) {
|
||||
return result;
|
||||
}
|
||||
|
||||
int strncasecmp_P(const char* str1, const char* str2P, size_t size) {
|
||||
int strncasecmp_P(const char* str1, PGM_P str2P, size_t size) {
|
||||
int result = 0;
|
||||
|
||||
while (size > 0)
|
||||
@ -118,7 +194,7 @@ int strncasecmp_P(const char* str1, const char* str2P, size_t size) {
|
||||
return result;
|
||||
}
|
||||
|
||||
int printf_P(const char* formatP, ...) {
|
||||
int printf_P(PGM_P formatP, ...) {
|
||||
int ret;
|
||||
va_list arglist;
|
||||
va_start(arglist, formatP);
|
||||
@ -135,7 +211,7 @@ int printf_P(const char* formatP, ...) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sprintf_P(char* str, const char* formatP, ...) {
|
||||
int sprintf_P(char* str, PGM_P formatP, ...) {
|
||||
int ret;
|
||||
va_list arglist;
|
||||
va_start(arglist, formatP);
|
||||
@ -146,7 +222,7 @@ int sprintf_P(char* str, const char* formatP, ...) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int snprintf_P(char* str, size_t strSize, const char* formatP, ...) {
|
||||
int snprintf_P(char* str, size_t strSize, PGM_P formatP, ...) {
|
||||
int ret;
|
||||
va_list arglist;
|
||||
va_start(arglist, formatP);
|
||||
@ -157,7 +233,7 @@ int snprintf_P(char* str, size_t strSize, const char* formatP, ...) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int vsnprintf_P(char* str, size_t strSize, const char* formatP, va_list ap) {
|
||||
int vsnprintf_P(char* str, size_t strSize, PGM_P formatP, va_list ap) {
|
||||
int ret;
|
||||
|
||||
size_t fmtLen = strlen_P(formatP);
|
||||
|
@ -32,27 +32,40 @@ typedef uint32_t prog_uint32_t;
|
||||
|
||||
#define SIZE_IRRELEVANT 0x7fffffff
|
||||
|
||||
void* memcpy_P(void* dest, const void* src, size_t count);
|
||||
// memchr_P and memrchr_P are not implemented due to danger in its use, and
|
||||
// how uninteresting their use is
|
||||
// since its a flash string, you should already know where the char is within it,
|
||||
// further, it could return a pointer into the flash memory that is not 32bit aligned
|
||||
// which could cause an exception if read
|
||||
// PGM_VOID_P memchr_P(PGM_VOID_P bufP, int c, size_t count);
|
||||
// PGM_VOID_P memrchr_P(PGM_VOID_P bufP, int c, size_t count);
|
||||
|
||||
char* strncpy_P(char* dest, const char* src, size_t size);
|
||||
int memcmp_P(const void* buf1, PGM_VOID_P buf2P, size_t size);
|
||||
// memccpy_P is only valid when used with pointers to 8bit data, due to size aligned pointers
|
||||
// and endianess of the values greater than 8bit, matching c may return invalid aligned pointers
|
||||
void* memccpy_P(void* dest, PGM_VOID_P src, int c, size_t count);
|
||||
void* memmem_P(const void* buf, size_t bufSize, PGM_VOID_P findP, size_t findPSize);
|
||||
void* memcpy_P(void* dest, PGM_VOID_P src, size_t count);
|
||||
|
||||
char* strncpy_P(char* dest, PGM_P src, size_t size);
|
||||
#define strcpy_P(dest, src) strncpy_P((dest), (src), SIZE_IRRELEVANT)
|
||||
|
||||
char* strncat_P(char* dest, const char* src, size_t size);
|
||||
char* strncat_P(char* dest, PGM_P src, size_t size);
|
||||
#define strcat_P(dest, src) strncat_P((dest), (src), SIZE_IRRELEVANT)
|
||||
|
||||
int strncmp_P(const char* str1, const char* str2P, size_t size);
|
||||
int strncmp_P(const char* str1, PGM_P str2P, size_t size);
|
||||
#define strcmp_P(str1, str2P) strncmp_P((str1), (str2P), SIZE_IRRELEVANT)
|
||||
|
||||
int strncasecmp_P(const char* str1, const char* str2P, size_t size);
|
||||
int strncasecmp_P(const char* str1, PGM_P str2P, size_t size);
|
||||
#define strcasecmp_P(str1, str2P) strncasecmp_P((str1), (str2P), SIZE_IRRELEVANT)
|
||||
|
||||
size_t strnlen_P(const char *s, size_t size);
|
||||
size_t strnlen_P(PGM_P s, size_t size);
|
||||
#define strlen_P(strP) strnlen_P((strP), SIZE_IRRELEVANT)
|
||||
|
||||
int printf_P(const char *formatP, ...) __attribute__ ((format (printf, 1, 2)));
|
||||
int sprintf_P(char *str, const char *formatP, ...) __attribute__((format(printf, 2, 3)));
|
||||
int snprintf_P(char *str, size_t strSize, const char *formatP, ...) __attribute__((format(printf, 3, 4)));
|
||||
int vsnprintf_P(char *str, size_t strSize, const char *formatP, va_list ap) __attribute__ ((format (printf, 3, 0)));
|
||||
int printf_P(PGM_P formatP, ...) __attribute__((format(printf, 1, 2)));
|
||||
int sprintf_P(char *str, PGM_P formatP, ...) __attribute__((format(printf, 2, 3)));
|
||||
int snprintf_P(char *str, size_t strSize, PGM_P formatP, ...) __attribute__((format(printf, 3, 4)));
|
||||
int vsnprintf_P(char *str, size_t strSize, PGM_P formatP, va_list ap) __attribute__((format(printf, 3, 0)));
|
||||
|
||||
// flash memory must be read using 32 bit aligned addresses else a processor
|
||||
// exception will be triggered
|
||||
|
Reference in New Issue
Block a user