mirror of
https://github.com/espressif/ESP8266_RTOS_SDK.git
synced 2025-06-03 11:29:42 +08:00
feat(newlib): Add newlib platform function
This commit is contained in:
@ -7,7 +7,7 @@ COMPONENT_SRCDIRS := driver source
|
||||
|
||||
LIBS ?=
|
||||
ifndef CONFIG_NO_BLOBS
|
||||
LIBS += airkiss cirom crypto espnow gcc hal core mirom net80211 \
|
||||
LIBS += airkiss crypto espnow gcc hal core net80211 \
|
||||
phy pp pwm smartconfig ssc wpa wps
|
||||
endif
|
||||
|
||||
|
@ -86,7 +86,6 @@ typedef enum {
|
||||
#define REG_SET_BIT(_r, _b) (*(volatile uint32 *)(_r) |= (_b))
|
||||
#define REG_CLR_BIT(_r, _b) (*(volatile uint32 *)(_r) &= ~(_b))
|
||||
|
||||
#define __packed __attribute__((packed))
|
||||
#define STORE_ATTR __attribute__((aligned(4)))
|
||||
|
||||
#define SHMEM_ATTR
|
||||
|
@ -21,6 +21,10 @@
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/timers.h"
|
||||
|
||||
#if defined(CONFIG_NEWLIB_LIBRARY_LEVEL_NORMAL) || defined(CONFIG_NEWLIB_LIBRARY_LEVEL_NANO)
|
||||
#include "esp_newlib.h"
|
||||
#endif
|
||||
|
||||
static uint32_t enter_critical_wrapper(void)
|
||||
{
|
||||
taskENTER_CRITICAL();
|
||||
@ -90,7 +94,9 @@ static void task_resume_all_wrapper(void)
|
||||
|
||||
static void os_init_wrapper(void)
|
||||
{
|
||||
/* empty function */
|
||||
#if defined(CONFIG_NEWLIB_LIBRARY_LEVEL_NORMAL) || defined(CONFIG_NEWLIB_LIBRARY_LEVEL_NANO)
|
||||
esp_newlib_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void os_start_wrapper(void)
|
||||
|
@ -77,6 +77,17 @@ extern "C" {
|
||||
#include <xtensa/xtruntime.h>
|
||||
#include "xtensa_rtos.h"
|
||||
|
||||
#if defined(configUSE_NEWLIB_REENTRANT) && configUSE_NEWLIB_REENTRANT == 1
|
||||
#if defined(CONFIG_NEWLIB_LIBRARY_LEVEL_NORMAL) || defined(CONFIG_NEWLIB_LIBRARY_LEVEL_NANO)
|
||||
#include "esp_newlib.h"
|
||||
|
||||
#define _impure_ptr _global_impure_ptr
|
||||
|
||||
#undef _REENT_INIT_PTR
|
||||
#define _REENT_INIT_PTR(p) esp_reent_init(p)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
|
44
components/freertos/port/impure.c
Normal file
44
components/freertos/port/impure.c
Normal file
@ -0,0 +1,44 @@
|
||||
// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
static struct _reent impure_data;
|
||||
struct _reent *_global_impure_ptr = &impure_data;
|
||||
|
||||
struct _reent *__getreent()
|
||||
{
|
||||
extern char _xt_isr_status;
|
||||
|
||||
/*
|
||||
* Locking mutex(only mutex, not ISR mutex) at the following three
|
||||
* state may cause OS death. So we use a extra _reent data instead
|
||||
* of task private reent data.
|
||||
*
|
||||
* But although at the state none of "taskSCHEDULER_RUNNING", exception
|
||||
* can cause CPU swicth context, then Locking mutex may cause OS death.
|
||||
* So we command that use ets_printf(ROM function) instead of "printf"
|
||||
* at exception and system kernal critical state.
|
||||
*/
|
||||
if (_xt_isr_status
|
||||
|| !xTaskGetCurrentTaskHandle()
|
||||
|| xTaskGetSchedulerState() != taskSCHEDULER_RUNNING)
|
||||
return &impure_data;
|
||||
|
||||
/*
|
||||
* When scheduler starts, _global_impure_ptr = pxCurrentTCB->xNewLib_reent.
|
||||
*/
|
||||
return _global_impure_ptr;
|
||||
}
|
@ -12,7 +12,7 @@ LIBC_PATH := $(COMPONENT_PATH)/newlib/lib/libc.a
|
||||
LIBM_PATH := $(COMPONENT_PATH)/newlib/lib/libm.a
|
||||
ADD_NEW_NEWLIB := 1
|
||||
else
|
||||
ifdef NEWLIB_LIBRARY_LEVEL_NANO
|
||||
ifdef CONFIG_NEWLIB_LIBRARY_LEVEL_NANO
|
||||
LIBC_PATH := $(COMPONENT_PATH)/newlib/lib/libc_nano.a
|
||||
LIBM_PATH := $(COMPONENT_PATH)/newlib/lib/libm.a
|
||||
ADD_NEW_NEWLIB := 1
|
||||
@ -20,7 +20,8 @@ endif
|
||||
endif
|
||||
|
||||
ifeq ($(ADD_NEW_NEWLIB),1)
|
||||
COMPONENT_ADD_INCLUDEDIRS += newlib/include
|
||||
COMPONENT_ADD_INCLUDEDIRS += newlib/include newlib/port/include
|
||||
COMPONENT_SRCDIRS += newlib/port
|
||||
COMPONENT_ADD_LDFLAGS := $(LIBC_PATH) $(LIBM_PATH) -lnewlib
|
||||
COMPONENT_ADD_LINKER_DEPS := $(LIBC_PATH) $(LIBM_PATH)
|
||||
endif
|
||||
|
68
components/newlib/newlib/port/esp_newlib.c
Normal file
68
components/newlib/newlib/port/esp_newlib.c
Normal file
@ -0,0 +1,68 @@
|
||||
// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <reent.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* @brief Initialize global and thread's private reent object data. We add this instead of
|
||||
* newlib's initialization function to avoid some unnecessary cost and unused function.
|
||||
*/
|
||||
void esp_reent_init(struct _reent* r)
|
||||
{
|
||||
extern void _cleanup(struct _reent *r);
|
||||
|
||||
memset(r, 0, sizeof(*r));
|
||||
|
||||
r->_stdout = _GLOBAL_REENT->_stdout;
|
||||
r->_stderr = _GLOBAL_REENT->_stderr;
|
||||
r->_stdin = _GLOBAL_REENT->_stdin;
|
||||
|
||||
r->__cleanup = _cleanup;
|
||||
r->__sglue._next = NULL;
|
||||
r->__sglue._niobs = 0;
|
||||
r->__sglue._iobs = NULL;
|
||||
r->_current_locale = "C";
|
||||
r->__sdidinit = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Initialize newlib's platform object data
|
||||
*/
|
||||
int esp_newlib_init(void)
|
||||
{
|
||||
esp_reent_init(_global_impure_ptr);
|
||||
|
||||
_GLOBAL_REENT->_stdout = fopen("uart/0", "w");
|
||||
if (!_GLOBAL_REENT->_stdout)
|
||||
goto err;
|
||||
|
||||
_GLOBAL_REENT->_stderr = fopen("uart/0", "w");
|
||||
if (!_GLOBAL_REENT->_stderr)
|
||||
goto err_fail;
|
||||
|
||||
_GLOBAL_REENT->_stdin = fopen("uart/0", "r");
|
||||
if (!_GLOBAL_REENT->_stdin)
|
||||
goto err_in;
|
||||
|
||||
return 0;
|
||||
|
||||
err_in:
|
||||
fclose(_GLOBAL_REENT->_stderr);
|
||||
err_fail:
|
||||
fclose(_GLOBAL_REENT->_stdout);
|
||||
err:
|
||||
return -1;
|
||||
}
|
26
components/newlib/newlib/port/fputc.c
Normal file
26
components/newlib/newlib/port/fputc.c
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <_ansi.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int _fputc_r(struct _reent *ptr, int ch, FILE *fp)
|
||||
{
|
||||
return fp->_write(ptr, fp->_cookie, (char *)&ch, 1);
|
||||
}
|
||||
|
||||
int fputc(int ch, FILE *fp)
|
||||
{
|
||||
return _fputc_r (_REENT, ch, fp);
|
||||
}
|
39
components/newlib/newlib/port/include/esp_newlib.h
Normal file
39
components/newlib/newlib/port/include/esp_newlib.h
Normal file
@ -0,0 +1,39 @@
|
||||
// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _ESP_NEWLIB_H
|
||||
#define _ESP_NEWLIB_H
|
||||
|
||||
#include <reent.h>
|
||||
|
||||
/*
|
||||
* @brief Initialize global and thread's private reent object data. We add this instead of
|
||||
* newlib's initialization function to avoid some unnecessary cost and unused function.
|
||||
*
|
||||
* @param r reent pointer
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void esp_reent_init(struct _reent* r);
|
||||
|
||||
/*
|
||||
* @brief Initialize newlib's platform object data
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @return 0 if successful or -1 if failed
|
||||
*/
|
||||
int esp_newlib_init(void);
|
||||
|
||||
#endif
|
123
components/newlib/newlib/port/syscall.c
Normal file
123
components/newlib/newlib/port/syscall.c
Normal file
@ -0,0 +1,123 @@
|
||||
// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "c_types.h"
|
||||
|
||||
#include "esp8266/ets_sys.h"
|
||||
#include "esp8266/eagle_soc.h"
|
||||
#include "esp8266/uart_register.h"
|
||||
|
||||
#define PANIC_UART 0
|
||||
|
||||
static inline void panit_putc(char c)
|
||||
{
|
||||
while (1) {
|
||||
uint32_t fifo_cnt = READ_PERI_REG(UART_STATUS(PANIC_UART)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S);
|
||||
|
||||
if ((fifo_cnt >> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) < 126)
|
||||
break;
|
||||
}
|
||||
|
||||
WRITE_PERI_REG(UART_FIFO(PANIC_UART) , c);
|
||||
}
|
||||
|
||||
int _open_r(struct _reent *r, const char *filename, int flags, int mode)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _read_r(struct _reent *r, int fd, void *buf, int len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _write_r(struct _reent *r, int fd, void *buf, int len)
|
||||
{
|
||||
int i;
|
||||
const char *cbuf = buf;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
panit_putc(cbuf[i]);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
_off_t _lseek_r(struct _reent *r, int fd, _off_t where, int whence)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _close_r(struct _reent *r, int fd)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _rename_r(struct _reent *r, const char *from, const char *to)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _unlink_r(struct _reent *r, const char *filename)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _fstat_r(struct _reent *r, int fd, struct stat *s)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _sbrk_r(void *ptr, int incr)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
void *_malloc_r(struct _reent *r, size_t n)
|
||||
{
|
||||
return pvPortMalloc(n);
|
||||
}
|
||||
|
||||
void *_realloc_r(struct _reent *r, void *old_ptr, size_t n)
|
||||
{
|
||||
void *p = pvPortMalloc(n);
|
||||
if (p && old_ptr) {
|
||||
memcpy(p, old_ptr, n);
|
||||
vPortFree(old_ptr);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void *_calloc_r(struct _reent *r, size_t c, size_t s)
|
||||
{
|
||||
char *p = pvPortMalloc(c * s);
|
||||
if (p)
|
||||
memset(p, 0, c * s);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void *_free_r(struct _reent *r, void *ptr)
|
||||
{
|
||||
vPortFree(ptr);
|
||||
}
|
||||
|
||||
void _exit(int status)
|
||||
{
|
||||
while (1);
|
||||
}
|
@ -162,7 +162,7 @@ void esp_spiffs_deinit(u8_t format)
|
||||
}
|
||||
}
|
||||
|
||||
int _open_r(struct _reent *r, const char *filename, int flags, int mode)
|
||||
int _spiffs_open_r(struct _reent *r, const char *filename, int flags, int mode)
|
||||
{
|
||||
spiffs_mode sm = 0;
|
||||
int res;
|
||||
@ -201,7 +201,7 @@ int _open_r(struct _reent *r, const char *filename, int flags, int mode)
|
||||
return res;
|
||||
}
|
||||
|
||||
_ssize_t _read_r(struct _reent *r, int fd, void *buf, size_t len)
|
||||
_ssize_t _spiffs_read_r(struct _reent *r, int fd, void *buf, size_t len)
|
||||
{
|
||||
|
||||
ssize_t res;
|
||||
@ -215,7 +215,7 @@ _ssize_t _read_r(struct _reent *r, int fd, void *buf, size_t len)
|
||||
return res;
|
||||
}
|
||||
|
||||
_ssize_t _write_r(struct _reent *r, int fd, void *buf, size_t len)
|
||||
_ssize_t _spiffs_write_r(struct _reent *r, int fd, void *buf, size_t len)
|
||||
{
|
||||
|
||||
if (fd < NUM_SYS_FD) {
|
||||
@ -226,7 +226,7 @@ _ssize_t _write_r(struct _reent *r, int fd, void *buf, size_t len)
|
||||
return res;
|
||||
}
|
||||
|
||||
_off_t _lseek_r(struct _reent *r, int fd, _off_t where, int whence)
|
||||
_off_t _spiffs_lseek_r(struct _reent *r, int fd, _off_t where, int whence)
|
||||
{
|
||||
|
||||
ssize_t res;
|
||||
@ -240,7 +240,7 @@ _off_t _lseek_r(struct _reent *r, int fd, _off_t where, int whence)
|
||||
return res;
|
||||
}
|
||||
|
||||
int _close_r(struct _reent *r, int fd)
|
||||
int _spiffs_close_r(struct _reent *r, int fd)
|
||||
{
|
||||
|
||||
if (fd < NUM_SYS_FD) {
|
||||
@ -251,21 +251,21 @@ int _close_r(struct _reent *r, int fd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _rename_r(struct _reent *r, const char *from, const char *to)
|
||||
int _spiffs_rename_r(struct _reent *r, const char *from, const char *to)
|
||||
{
|
||||
|
||||
int res = SPIFFS_rename(&fs, (char *) from, (char *) to);
|
||||
return res;
|
||||
}
|
||||
|
||||
int _unlink_r(struct _reent *r, const char *filename)
|
||||
int _spiffs_unlink_r(struct _reent *r, const char *filename)
|
||||
{
|
||||
|
||||
int res = SPIFFS_remove(&fs, (char *) filename);
|
||||
return res;
|
||||
}
|
||||
|
||||
int _fstat_r(struct _reent *r, int fd, struct stat *s)
|
||||
int _spiffs_fstat_r(struct _reent *r, int fd, struct stat *s)
|
||||
{
|
||||
|
||||
int res;
|
||||
|
Reference in New Issue
Block a user