Скрыть объявление
Управляйте вашими ESP8266 и другими устройствами прямо с телефона из любой точки мира, где есть интернет!
Подробности и обсуждение IoT Manager в этой теме. Официальный сайт приложения и документация IoTmanager.ru
Скрыть объявление
На нашем форуме недоступен просмотр изображений для неавторизованных пользователей. Если Вы уже зарегистрированы на нашем форуме, то можете войти. Если у Вас еще нет аккаунта, мы будем рады, если Вы к нам присоединитесь. Зарегистрироваться Вы можете здесь.

Где взять описание отсутствующих в офф.доках функций?

Тема в разделе "SDK и создание собственных прошивок", создана пользователем JustACat, 25 мар 2015.

  1. JustACat

    JustACat Moderator Команда форума

    Сообщения:
    568
    Симпатии:
    121
    Пришло время и мне задать нубский вопрос, и пусть те, кто уже прошел по граблям, похахают надо мной, но все же, желательно, помогут.

    Итак, пытаюсь въехать в код. Если конкретно, то код из Sming. Хотя вроде это не имеет значения. SDK v 1.0.0
    Ковыряю функцию:
    Код (C):
    1. Serial.systemDebugOutput();
    Пытаюсь найти ее вызов, мне eclipse вроде бы показывает: class HardwareSerial который тут:
    C:\Sming\Sming\SmingCore\HardwareSerial.h
    (чтобы скопировать путь, пришлось открыть его в Notepad++ там так удобно, правой кнопкой по закладке и там все есть, в эклипсе такое не нашел)
    Ок, значит реализация там же рядом в HardwareSerial.cpp Хорошо, нашли:
    Код (C):
    1. void HardwareSerial::systemDebugOutput(bool enabled)
    2. {
    3.     if (uart == UART_ID_0)
    4.         os_install_putc1(enabled ? (void *)uart_tx_one_char : NULL);
    5.     //else
    6.     //    os_install_putc1(enabled ? (void *)uart1_tx_one_char : NULL); //TODO: Debug serial
    7. }
    Но дальше-то затык... Что такое os_install_putc1?
    Эклипс мне уже не смог ответить на этот вопрос (может я не так чего нажимаю?)...
    Хорошо, воспользуемся поиском по файлам в Notepad++.
    Ага, нашли единственное место:
    C:\Espressif\ESP8266_SDK\include\osapi.h
    Код (C):
    1. #define os_install_putc1 ets_install_putc1
    Круто... Теперь ищем ets_install_putc1 и находим его вот тут:
    C:\Sming\Sming\system\include\esp_systemapi.h
    Код (C):
    1. extern void ets_install_putc1(void *routine);
    И еще вот тут:
    C:\Espressif\ESP8266_SDK\ld\eagle.rom.addr.v6.ld
    Код (C):
    1. PROVIDE ( ets_install_putc1 = 0x4000242c );
    Могу ошибаться, но из этого я делаю вывод, что это некая функция, которая скрывается где-то в закомпиленных уже либах и исходников к ней нет.

    Чтож, но вопрос не в этом, вопрос в том: как понять дальше, что эта хреновина делает?

    Попытки найти в pdf'ках от Espressif описание этих функций - ничего не дают.
    Не, я понимаю, что дальше умные люди вооружаются дизассемблерами, либо еще чем-то и...
    Но мой вопрос стоит именно так: простые смертные могут где-то найти информацию, хотя бы общую, что делает и/или как работает та или иная функция, которая не описана в доках от Espressif?
    То есть может где-то собран этот кладезь знаний уже? Может я не туда куда-то смотрю?

    Пните меня в нужном направлении, и я как ежик, с удовольствием туда полечу! Спасибо! :)

    PS: и да, мне не нужно объяснять конкретно эту вот строчку:
    os_install_putc1(enabled ? (void *)uart_tx_one_char : NULL);
    Я логикой ее понимаю, что-то вроде: прописываем куда-то в системе указатель на колбек-функцию, которую система будет вызывать каждый раз, когда захочет вывести 1 символ дебажной информации, а в этой функции мы уже этот символ выводим туда, куда нам надо, например, в UART0. Либо прописываем NULL, и тогда система не вызывает никокой функции и дебаг не выводится.
    Но мне, например, не понятно, почему эта функция называется os_install_putc1/ets_install_putc1, то есть не может ли быть так, что она не только дебажную информацию выводит, но и что-то еще?
    Почему не os_install_debug_putc какой-нибудь?// В общем, беда-беда, огорчение :)

    Сейчас подумалось еще, что эта функция выставляет коллбек для другой функции, типа ets_putc.
    Которая в свою очередь и вызывается для вывода каждого символа. Но как это все именно с дебагом связано, то есть именно с отладочной информацией?
     
    Victor нравится это.
  2. pvvx

    pvvx Активный участник сообщества

    Сообщения:
    7.227
    Симпатии:
    1.168
    Найдете только в своем компе, если сами положили её туда :)
    Частично собран, но находится на тысячах носителей, которые не желают объединяться.

    os_install_putc1(enabled ? (void *)uart_tx_one_char : NULL); - это если enabled != 0, то будет включена функция вывода для printf и т.д. uart_tx_one_char(). А если enabled == 0, то вывода у системных функций типа printf не будет. Всё это обращается к кодам в BIOS-ROM и её системе ввода-вывода и т.д.
    Код (Text):
    1.  
    2. ROM:40001CB0 off_40001CB0    .int dword_3FFFDD3C     ; DATA XREF: ROM:eprintf_init_bufr
    3. ROM:40001CB0                                         ; ROM:40001CDFr ...
    4. ....
    5. ROM:4000242C ets_install_putc1:                      ; CODE XREF: ROM:40002441j
    6. ROM:4000242C                                         ; DATA XREF: default_exception_handler:a_ets_install_putc1o
    7. ROM:4000242C                 l32r            a3, off_40001CB0
    8. ROM:4000242F                 s32i.n          a2, a3, 0xC
    9. ROM:40002431                 ret.n
    10. ROM:40002431 ; ---------------------------------------------------------------------------
    11. ROM:40002433                 .byte 0
    12. ROM:40002434 a_putc1         .int uart1_write_char   ; DATA XREF: ROM:ets_install_uart_printfr
    13. ROM:40002434                                         ; ROM:40002566r
    14. ROM:40002438 ; ---------------------------------------------------------------------------
    15. ROM:40002438
    16. ROM:40002438 ets_install_uart_printf:                ; CODE XREF: ROM:40000FFEj
    17. ROM:40002438                 l32r            a2, a_putc1
    18. ROM:4000243B                 addi            a1, a1, 0xF0
    19. ROM:4000243E                 s32i            a0, a1, 0
    20. ROM:40002441                 call0           ets_install_putc1
    21. ROM:40002444                 l32i.n          a0, a1, 0
    22. ROM:40002446                 addi            a1, a1, 0x10
    23. ROM:40002449                 ret.n
    24. ROM:40002449 ; ---------------------------------------------------------------------------
    25.  
     
    Последнее редактирование: 25 мар 2015
  3. JustACat

    JustACat Moderator Команда форума

    Сообщения:
    568
    Симпатии:
    121
    Вот я и говорю, что по логике-то я это понимаю. Но хотелось бы некое подтверждение иметь.

    Мне вот, например, непонятно, почему я вызываю один раз эту штуку - разрешаю этот самый отладочный вывод, и он остается включенным, даже если вызов этой строчки уберу из прошивки.
    Опять же по логике получается, что оно где-то в системе прописывается и сохраняется во флеш, так?
    Но если это так, то не получится ли так, что, если, допустим, я в своей программе поставлю в начале строчку, отключающую этот самый вывод, то она каждый раз при старте программы будет это куда-то во флеш записывать и протрет там дырку?..
     
  4. JustACat

    JustACat Moderator Команда форума

    Сообщения:
    568
    Симпатии:
    121
    А нет, наврал, не сохраняется... По умолчанию дебаг включен, и если не вызвать Serial.systemDebugOutput(false); (которая в Sming и вызывает дальше отключение), то отладка появляется в терминале...
    Значит тогда получается, что я так и не могу толком разобраться со всеми этими Target'ами в этом eclipse... Да еще и в купе с запутанной памятью в ESP.
    Чего и как компилить и шить правильно, чтобы программа работала так, как написано?
    Конечно можно каждый раз делать clean - all - flash , но это долго, особенно в Sming там билдится куча библиотек каждый раз...
    А если только all - flash , не всегда оно корректно и происходит...

    pvvx, за дамп из рома спасибо конечно, но, боюсь, вы меня переоцениваете. Нет, я ассемблер знаю немного конечно, но не на столько, чтобы глядя в эту штуку все сразу прояснилось :)
     
  5. d946

    d946 Новичок

    Сообщения:
    16
    Симпатии:
    0
    типичная реализация связки printf и putchar (в нашем случае os_install_putc1)

    Код (Text):
    1. void * func_putchar = NULL;
    2.  
    3. void os_install_putc1( (void *)putchar_cb){
    4.      func_putchar= putchar_cb;
    5. }
    6.  
    7. void os_printf(void *str, ...){
    8.   char buf[1024];
    9.   os_sprintf((char *)buf, str, ...);
    10.   if (func_putchar!=NULL){
    11.     while(*buf){
    12.        func_putchar(*buf);
    13.        buf++;
    14.     }
    15.   }
    Дополнительная информация http://we.easyelectronics.ru/Soft/formatnyy-vyvod-na-si-dlya-mikrokontrollerov.html
     
  6. JustACat

    JustACat Moderator Команда форума

    Сообщения:
    568
    Симпатии:
    121
    d946, спасибо за инфу, но как я уже и говорил, меня интересует не конкретно данная строчка, а вообще принцип добывания информации по функциям SDK.
    То есть, если мне, к примеру, нужно понять, что за функция и как работает на php, я знаю, что надо идти на php.net, там просто ввести эту функцию в строку поиска и получить по ней зачастую исчерпывающие данные... Вот то же самое меня интересует и тут. А os_install_putc1 я привел лишь как частный пример такого поиска...
    Но вам в любом случае спасибо!
     
  7. pvvx

    pvvx Активный участник сообщества

    Сообщения:
    7.227
    Симпатии:
    1.168
    Этот вопрос может разрешить только Espressif, путем создания полного SDK, а не огрызка.
    А пока на их форуме присутствует единственная правильная рекомендация - использовать реверс :), т.е. дизасм.
    Часть, того, что я смотрел по своим нуждам и было время и возможность как-то перевести дизасм на язык СИ вложено в исходники к моей веб свалке в папке "Хлам" :) Это всего малая часть кусков из общего бардака по дизасму, которые не совсем страшные ...
     
    Последнее редактирование: 29 мар 2015
  8. Victor

    Victor Administrator Команда форума

    Сообщения:
    2.189
    Симпатии:
    373
    Здравствуйте, pvvx!
    Раз уж вы не спите, не подскажете можно ли реверснуть бут и пропатчить NOP там, где вывод мусора в UART0. Или переключить его на UART1, или еще какие варианты есть.
     
  9. pvvx

    pvvx Активный участник сообщества

    Сообщения:
    7.227
    Симпатии:
    1.168
    Не выйдет - основные сообщения при старте в оба UART дает ROM-BIOS и от этого не избавится. Надо новую ревизию чипа.
    Или речь о сообщениях при старте boot_vX.X.bin от Espressif?
     
    Последнее редактирование: 29 мар 2015
  10. Victor

    Victor Administrator Команда форума

    Сообщения:
    2.189
    Симпатии:
    373
    получается что отключить можно только вторую часть (где jump to run user...) и то только в AT прошивке
     
  11. pvvx

    pvvx Активный участник сообщества

    Сообщения:
    7.227
    Симпатии:
    1.168
    Код (C):
    1.  
    2. void call_user_start(void)
    3. {
    4.     init_sflash_start();
    5.     ets_run();
    6. }
    7.  
    Так стартует SDK в app_main.c.
    А далее в SDK 1.0.0 приписали ненужную и глючную разборку по заголовку в flash и всякие выводы времени компиляции и т.д.
    В библиотеке libmain.a они спецом смешали всю ненужную белиберду в один модуль app_main.o, чтобы это простой перепаковкой либы и заменой малого obj было не решить.
     
  12. Victor

    Victor Administrator Команда форума

    Сообщения:
    2.189
    Симпатии:
    373
    ну мы ведь и не ждали от них ничего лучшего. а жаль.
     
  13. pvvx

    pvvx Активный участник сообщества

    Сообщения:
    7.227
    Симпатии:
    1.168
    Там главное, что при старте у них везде опять стоит:
    Код (C):
    1.  
    2.     while(READ_PERI_REG(UART_STATUS(0))  & (UART_TXFIFO_CNT<<UART_TXFIFO_CNT_S));
    3.     while(READ_PERI_REG(UART_STATUS(1))  & (UART_TXFIFO_CNT<<UART_TXFIFO_CNT_S));
    4.  
    и тем самым увеличивает время до старта рабочих процедур и не позволяет уменьшить потребление чипа при просыпаниях в deep_sleep c отключенным WiFi для опроса датчиков...
    Но их не интересует ничего кроме Iot SDK для работы со своим сайтом. AT прошивка - это второстепенное и случайное образование :)
     
  14. Victor

    Victor Administrator Команда форума

    Сообщения:
    2.189
    Симпатии:
    373
    оффтоп (раскрыть)
    @pvvx, посмотрели уже это https://github.com/esp8266/Arduino/ ? лучше продолжить в другой теме или в личной переписке
     
  15. pvvx

    pvvx Активный участник сообщества

    Сообщения:
    7.227
    Симпатии:
    1.168
    Ещё по поводу старта:
    Если при настройке параметров WiFi (конкретнее при сохранении параметров в flash) выключить или пропадет питание модуля, то при следующем старте вполне получите дамп памяти:
    Код (C):
    1.  
    2. struct ets_FlashHeader { // заголовок flash (использует загрузчик BIOS)
    3.     uint8 id; // = 0xE9
    4.     uint8 number_segs; // Number of segments
    5.     uint8 spi_interface; // SPI Flash Interface (0 = QIO, 1 = QOUT, 2 = DIO, 0x3 = DOUT)
    6.     struct esp_flash_hsz hsz; // options
    7. }  __attribute__((packed));
    8.  
    9. struct ets_store_wifi_hdr { // 0x4027F000 (пишется в последний сектор)
    10.     uint8 bank;     // +00 = 0, 1 // используется первый или второй сектор настроек WiFi
    11.     uint32 flag;    // +04 = 0x55AA55AA
    12.     uint32 x;         // +08 = 0x00000119
    13.     uint32 xx[2];    // +12 = 28, 28
    14.     uint32 chk[2];    // +20 = 0x91, 0x91
    15. };
    16. void hex_damp_sec_blk_flash(uint32 fsec, uint32 len)
    17. {
    18.     uint8* buf = pvPortMalloc(len+3);
    19.     if(spi_flash_read(fsec << 12, (uint32_t *)buf, len & 0xfffc) == SPI_FLASH_RESULT_OK) {
    20.         uint8* ptr = buf;
    21.         uint32 i = 0;
    22.         while(len--) {
    23.             os_printf_plus("%08x ", *ptr++);
    24.             if((++i & 0x1F) == 0) os_printf_plus("\n");
    25.         }
    26.     }
    27.     os_printf_plus("\n");
    28.     vPortFree(buf);
    29. }
    30. void system_param_error(uint32 fsec)
    31. {
    32.     os_printf_plus("system param error\n");
    33.     hex_damp_sec_blk_flash(fsec + 1, 0x370 ); // первый сектор сохранения параметров WiFi и размер структуры
    34.     hex_damp_sec_blk_flash(fsec + 2, 0x370 ); // второй сектор сохранения параметров WiFi и размер структуры
    35.     hex_damp_sec_blk_flash(fsec + 3, 28 ); // третий сектор заголовка сохранения параметров WiFi и размер это структуры
    36. }
    37.  
    38. static void init_sflash_start(void)
    39. {
    40.     struct ets_FlashHeader fhead;
    41.     uint8 wifi_cfg[0x370];
    42.     struct ets_store_wifi_hdr buf;
    43.     uint8 macaddr[6];
    44.  
    45.     read_macaddr_from_otp(&macaddr);
    46.  
    47.     SET_PERI_REG_MASK(SPI_USER(0), SPI_CS_SETUP); // +1 такт перед CS
    48.     SPIRead(0, (uint32_t *)fhead, sizeof(fhead));
    49.  
    50.     uint8_t speed = fhead.hsz.spi_freg;
    51.     if (speed >= 3) {
    52.         speed = (speed == 0x15) ? 1 : 2;
    53.     } else {
    54.         speed += 2;
    55.     }
    56.  
    57.     uint32 fsize = 0x80000;
    58.     switch(fhead.hsz.flash_size)
    59.     {
    60.         case 1:
    61.             fsize = 0x40000;
    62.             break;
    63.         case 2:
    64.             fsize = 0x100000;
    65.             break;
    66.         case 3:
    67.             fsize = 0x200000;
    68.             break;
    69.         case 4:
    70.             fsize = 0x400000;
    71.             break;
    72.     }
    73.     flashchip->chip_size = fsize;
    74.     sflash_something(speed);
    75.  
    76.     uint32 fsector = flashchip->chip_size >> 12;
    77.     fsector -= 4;
    78.  
    79.     SPIRead(flashchip->chip_size - 0x1000,(uint32_t *)buf, sizeof(buf));
    80.  
    81.     uint32 store_cfg_addr = flashchip->chip_size - 0x3000 + ((buf.bank)? 0x1000 : 0);
    82.  
    83.     SPIRead(store_cfg_addr, &wifi_cfg, sizeof(wifi_cfg));
    84.  
    85.     Cache_Read_Enable(0,0,1);
    86.     mem_clr_bss();
    87.     ets_install_putc1(uart1_write_char_ram);
    88.     if(buf.flag != 0x55AA55AA){
    89.         if(buf.flag != 0xFFFFFFFF) {
    90.             system_param_error(fsector);
    91.         }
    92.     }
    93.     if(buf.chk[(buf.bank)? 1 : 0] != system_get_checksum((uint8 *)&wifi_cfg, sizeof(wifi_cfg)){
    94.         system_param_error(fsector);
    95.     }
    96. ....
    97. }
    98.  
    Аналогично и при нестандартных размерах flash :) Но об этом уже писал и давал что выводится в UART этот дамп с "system param error\n"...
     

Поделиться этой страницей