feat(newlib): Add newlib platform function

This commit is contained in:
Dong Heng
2018-05-11 17:27:54 +08:00
parent 58a66a3d39
commit 30de450816
11 changed files with 330 additions and 13 deletions

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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.
*

View 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;
}

View File

@ -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

View 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;
}

View 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);
}

View 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

View 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);
}

View File

@ -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;