CHERTS, А из
этого поста пример собирается? У меня именно с ним проблема.
этого поста пример собирается? У меня именно с ним проблема.
А какие ошибки выдает? Компилятор g++ установлен?
Собирается и работает, через час выложу DevKit 1.0.7, там этот пример включен.
c:/espressif/xtensa-lx106-elf/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/lib\libc.a(lib_a-mallocr.o):(.literal+0x24): undefined reference to `_sbrk_r'
c:/espressif/xtensa-lx106-elf/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/lib\libc.a(lib_a-mallocr.o): In function `malloc_extend_top':
d:\Neo\Project\ESP8266\DevKit\build\compiler\dl\esp-newlib\build\xtensa-lx106-elf\newlib\libc\stdlib/../../../../../newlib/libc/stdlib/mallocr.c:2165: undefined reference to `_sbrk_r'
d:\Neo\Project\ESP8266\DevKit\build\compiler\dl\esp-newlib\build\xtensa-lx106-elf\newlib\libc\stdlib/../../../../../newlib/libc/stdlib/mallocr.c:2202: undefined reference to `_sbrk_r'
c:/espressif/xtensa-lx106-elf/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/lib\libc.a(lib_a-freer.o): In function `_malloc_trim_r':
d:\Neo\Project\ESP8266\DevKit\build\compiler\dl\esp-newlib\build\xtensa-lx106-elf\newlib\libc\stdlib/../../../../../newlib/libc/stdlib/mallocr.c:3325: undefined reference to `_sbrk_r'
d:\Neo\Project\ESP8266\DevKit\build\compiler\dl\esp-newlib\build\xtensa-lx106-elf\newlib\libc\stdlib/../../../../../newlib/libc/stdlib/mallocr.c:3332: undefined reference to `_sbrk_r'
c:/espressif/xtensa-lx106-elf/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/lib\libc.a(lib_a-freer.o):d:\Neo\Project\ESP8266\DevKit\build\compiler\dl\esp-newlib\build\xtensa-lx106-elf\newlib\libc\stdlib/../../../../../newlib/libc/stdlib/mallocr.c:3340: more undefined references to `_sbrk_r' follow
По идее надо заменить реализацию malloc в newlib на вызов os_malloc, а free -- на os_free. Я завтра наверно сделаю.Продолжаем игры. Появились очередные вопросы )
1. При использовании стандартного вектора таки в некоторых случаях не хватает реализации `_sbrk_r':
Можно ли как-то его реализовать или убрать?
Я вот такой способ предложил в своё время: http://www.esp8266.com/viewtopic.php?f=9&t=224&start=80#p13852. Линкер кидает все наши функции в секцию iram1_0_seg, которой всего 32кб. Чтобы положить их в rom, есть аттрибут ICACHE_FLASH_ATTR. Туда же кладутся и все строковые константы.
А есть ли способ класть их в rom по-умолчанию, и использовать их оттуда?
Огромное спасибо, это как раз то чего мне не хватало. А почему нельзя класть код вызываемый из прерывания? У меня вроде работало (или это просто не гарантируется)?Я вот такой способ предложил в своё время: http://www.esp8266.com/viewtopic.php?f=9&t=224&start=80#p1385
Есть минимум одно "но" с кодом во FLASH: туда нельзя класть код, который может быть вызван из прерывания.
Надо уточнить: если программа пишет во FLASH. Потому что при записи мэппинг FLASH в адресное пространство CPU отключается а после включается снова. Если в этот период прийдёт прерывание всё сломается.Огромное спасибо, это как раз то чего мне не хватало. А почему нельзя класть код вызываемый из прерывания? У меня вроде работало (или это просто не гарантируется)?
В смысле, в IRAM? Ну да, идея в том, чтобы поместить код для IRAM и FLASH в разные секции, а в скрипте линковщика положить разные входные секции в разные выходные регионы.Второй вопрос можно ли объявить обратную константу явно кладущую код в ROM? Чтобы полностью исключить всю библиотеку из основной памяти, но некоторые функции оставить там.
Вариант, конечно, но не уверен, что это просто, и вообще хорошо.1. В таком случае, получается можно просто запретить обработку прерываний на время записи данных во флеш?
Например так можно сделать:2. А Вы могли бы подсказать как сделать так, чтобы основной код лег во флеш (тут я думаю достаточно будет примера по ссылке), но определённые функции (требовательные к производительности/вызываемые в прерываниях и т.д.) клались в IRAM? Т.е примерно как встроенный макрос cache flash, но наоборот.
--- eagle.app.v6.ld.orig 2014-12-19 18:07:44.000000000 +0300
+++ eagle.app.v6.ld 2015-02-02 06:13:22.726822114 +0300
@@ -96,11 +96,14 @@
*(.gnu.linkonce.e.*)
*(.gnu.version_r)
*(.eh_frame)
+ . = (. + 3) & ~ 3;
/* C++ constructor and destructor tables, properly ordered: */
+ __init_array_start = ABSOLUTE(.);
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
+ __init_array_end = ABSOLUTE(.);
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
@@ -145,6 +148,14 @@
} >dram0_0_seg :dram0_0_bss_phdr
/* __stack = 0x3ffc8000; */
+ .irom0.text : ALIGN(4)
+ {
+ _irom0_text_start = ABSOLUTE(.);
+ *(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text)
+ build/app_app.a:*_flash.o(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
+ _irom0_text_end = ABSOLUTE(.);
+ } >irom0_0_seg :irom0_0_phdr
+
.text : ALIGN(4)
{
_stext = .;
@@ -153,6 +164,7 @@
*(.init.literal)
*(.init)
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
+ build/app_app.a:*_flash.o(.iram.literal .iram.text.literal .iram.text)
*(.fini.literal)
*(.fini)
*(.gnu.version)
@@ -169,12 +181,6 @@
_lit4_end = ABSOLUTE(.);
} >iram1_0_seg :iram1_0_phdr
- .irom0.text : ALIGN(4)
- {
- _irom0_text_start = ABSOLUTE(.);
- *(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text)
- _irom0_text_end = ABSOLUTE(.);
- } >irom0_0_seg :irom0_0_phdr
}
/* get ROM code address */
LD build/app.out
G:\Proj\ESP8266\WebSensor/user/HTTPClient.cpp:520: undefined reference to `std::string::_Rep::_S_empty_rep_storage'
G:\Proj\ESP8266\WebSensor/user/HTTPClient.cpp:521: undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, unsigned int, std::allocator<char> const&)'
G:\Proj\ESP8266\WebSensor/user/HTTPClient.cpp:521: undefined reference to `std::string::assign(std::string const&)'
G:\Proj\ESP8266\WebSensor/user/HTTPClient.cpp:521: undefined reference to `std::string::_Rep::_M_destroy(std::allocator<char> const&)'
G:\Proj\ESP8266\WebSensor/user/HTTPClient.cpp:527: undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&)'
c:\espressif\xtensa-lx106-elf\xtensa-lx106-elf\include\c++\4.8.2\bits/basic_string.h:539: undefined reference to `std::string::_Rep::_M_destroy(std::allocator<char> const&)'
(.text._ZNSt6vectorI7tHeaderSaIS0_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0_[_ZNSt6vectorI7tHeaderSaIS0_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0_]+0x8): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&)'
build/app_app.a(HTTPClient.o): In function `std::string::_Rep::_M_dispose(std::allocator<char> const&)':
c:\espressif\xtensa-lx106-elf\xtensa-lx106-elf\include\c++\4.8.2\bits/basic_string.h:240: undefined reference to `std::string::_Rep::_M_destroy(std::allocator<char> const&)'
Думаю, что тут счастья не найти.Чем дальше в лес - тем толще партизаны )))
Продолжил игры с stl, попробовал добавить в проект использование типа string. Вроде бы должно быть не особо накладно, и вроде бы реализовано все в виде шаблона.
Но и тут ждут грабли. Шаблон string не работает без либы libstdc++. Подключение этой либы сразу же превосходит все возможности по памяти )))
Вроде бы - реализуй зависимости у себя, и будет счастье.
Проще всего было бы посмотреть в исходниках stl:Из того, что я понял: std::string::_Rep::_S_empty_rep_storage - это место в памяти, на которое ссылается пустая строка, чтобы не выделять для пустой строки память под каждый объект. Но в каком виде ее задать?
template<typename _CharT, typename _Traits, typename _Alloc>
typename basic_string<_CharT, _Traits, _Alloc>::size_type
basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_empty_rep_storage[
(sizeof(_Rep_base) + sizeof(_CharT) + sizeof(size_type) - 1) /
sizeof(size_type)];
Обычно для этого компилируют с флагом -ffunction-sections и -fdata-sections, компилятор при этом заводит для каждой функции отдельную секцию. libstdc++ так и собрана. Потом линкуют с опцией --gc-sections и линкер выкидывает все секции (== функции и переменные) которые не были использованы явно или по зависимостям.И самый интересный вопрос - можно ли как-то сказать линкеру, чтобы он при включении какой-то либы не тянул ее всю, а выдергивал только нужные функции оттуда?
Пробовал, но он все равно запихнул дофига всего (map в аттаче).Обычно для этого компилируют с флагом -ffunction-sections и -fdata-sections, компилятор при этом заводит для каждой функции отдельную секцию. libstdc++ так и собрана. Потом линкуют с опцией --gc-sections и линкер выкидывает все секции (== функции и переменные) которые не были использованы явно или по зависимостям.
# libraries used in this project, mainly provided by the SDK
LIBS = c gcc hal phy pp net80211 lwip wpa main stdc++
# compiler flags using during compilation of source files
CFLAGS = -Os -g -O2 -Wpointer-arith -Wundef -Werror -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -D__ets__ -DICACHE_FLASH -ffunction-sections -fdata-sections
CXXFLAGS = $(CFLAGS) -fno-rtti -fno-exceptions
# linker flags used to generate the main object file
LDFLAGS = -nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static -Wl,--gc-sections -Wl,-Map d:\map.txt
Если исключения пролезли -- пиши пропалоПробовал, но он все равно запихнул дофига всего (map в аттаче).
как видим - там есть и исключения, и маллок, и еще куча прочего..
Есть ли способ как-то уменьшить итоговый размер, выкинув лишнее?
Я почти уверен что все вполне можно уместить, если грамотно все раскидать по разделам памяти. Но с этими разделами памяти просто какой-то ад. Вчера я честно достаточно упорно курил ман https://access.redhat.com/documenta..._GNU_Linker/sections.html#OUTPUT-SECTION-FILL но мало того что оно не делает того что нужно, там даже некоторые стандартные примеры собираться не хотят Может быть кто-нибудь посоветует что лучше почитать по этой теме?Но и тут ждут грабли. Шаблон string не работает без либы libstdc++. Подключение этой либы сразу же превосходит все возможности по памяти )))
Проще всего это сделать при сборке компилятора, но по идее можно и просто отдельно собрать эту либу. Типичным процессом кросс-компиляции: configure - make - make install. configure надо дать опцию --host=xtensa-lx106-elf, а в качестве кросс-компилятора указать xtensa-lx106-elf-g++. configure конечно захочет шелл и другие плюшки...А сконфигурировать либу под силу обычному человеку? Под виндой это можно сделать?