Скрыть объявление
На нашем форуме недоступен просмотр изображений для неавторизованных пользователей. Если Вы уже зарегистрированы на нашем форуме, то можете войти. Если у Вас еще нет аккаунта, мы будем рады, если Вы к нам присоединитесь. Зарегистрироваться Вы можете здесь.

'Реверс' SDK Espressif и ROM-BIOS для создания открытого SDK.

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

  1. pvvx

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

    Сообщения:
    9.441
    Симпатии:
    1.320
    На сегодня частичная сборка переведенных исходников SDK, для запуска моего Web, тут:
    https://github.com/pvvx/esp8266web
    Загрузчик SDK составлен из переписанных кусков libmain.a
    Перевод BIOS и интересовавших кусков SDK в info/libs (это не подлежит трансляции - чисто для инфы)
    Открытый LwIP использован v1.4.0
    Стыковка его с SDK 1.1.2 в файле eagle_lwip_if.c
    Заголовки процедур ROM-BIOS тут , по самому чипу тут
    Начал вырезать лишний код из libphy.a . Но там связи по переменным и для трансляции необходимо сразу всё из неё переработать.
    C новым патчем для SDK 1.1.2 есть и беда с WDT - китайцы вписали переустановку своего таймера по изменению режима sleep для WiFi и он отключает другие варианты обработки... Тоже надо доделывать до конца libmain.a:user_interface.o, но он такой кривой, что для OpenSDK из него взять нечего и пока необходим только для поддержки китай-глюка-SDK.
    ---
    Загрузчик+SDK без WiFi:
    https://github.com/pvvx/SDKnoWiFi
    Полностью открытая система на ESP8266.
    Создается в основном для обработки датчиков в режиме deep_sleep и других малопотребляющих режимах с последующим запуском обычной SDK для передачи набранных данных.
    Может использовать ESP8266 в качестве обычного микроконтроллера* с загрузкой Arduino и прочих систем, таких как интерпретатор Lua с целью получения максимальной RAM и т.д..
    *как второй ESP8266 в системе для унификации, вместо всяких "АрДурин".
    ---
    Все данные, включая указанные git не имеют никаких лицензий в отличии от других. Ограничение в использовании и копировании одно - как можно менее упоминать меня, а замещать своими (с) :)
     
    Последнее редактирование: 17 июн 2015
    pet, Victor, anakod и ещё 1-му нравится это.
  2. pvvx

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

    Сообщения:
    9.441
    Симпатии:
    1.320
    Начало тему раскидано по форуму и будет продолжаться тут.
    Данное сообщение пока зарезервировано для дальнейшего изменения в соответствии с темой.
    Предыстория вопроса:
    http://esp8266.ru/forum/threads/smi...abotki-proshivok-esp8266.167/page-4#post-4909
    Просьба модераторам перенести сообщения сюда...
     
  3. pvvx

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

    Сообщения:
    9.441
    Симпатии:
    1.320
    Первым делом предполагается создание отдельной системы 'хидеров' для СИ с полным описанием заголовков процедур и форматов ROM-BIOS, а так-же и оборудования чипа (что возможно) без "вкрапления" процедур и данных из SDK Espressif. Это требуется для создания загрузчиков и альтернативных систем на модуле и возможности загружать разные готовые "прошивки" с большой flash на ходу.
    У меня данное дело пока встало на изменении PLL CLK CPU, т.к. ROM-BIOS считает, что у неё кварц на 40 MHz, а не как на большинстве модулей (26 MHz). В итоге и скорость UART 74880 Baud, а не 115200 (115200*26/40=74880)...
    Интересно, что время загрузки первого блока из flash и его старта напрямую зависит от кол-ва блоков в заголовке flash. Происходит тормоз на выводе в UART с 74880 Baud сообщений по каждому загружаемому блоку. Их у нас по "стандарту" имеющихся сборщиков и программаторов всегда 3 шт. Но если указать 0 - то ROM-BIOS грузит один первый блок и не выводит сообщений, что значительно ускоряет процесс старта до исполнения первых пользовательских команд в загруженном куске. Итог около 30 ms и уже можно включить "кеширование" flash и использовать процедуры из неё...
    Весь код "загрузчика" до старта "кеширования":
    Код (C):
    1.  
    2. //=============================================================================
    3. // IRAM code
    4. //=============================================================================
    5. // call_user_start() - вызов из заголовка, загрузчиком
    6. // ENTRY(call_user_start) in eagle.app.v6.ld
    7. //-----------------------------------------------------------------------------
    8. void call_user_start(void)
    9. {
    10.        // Загрзука заголовка flash
    11.        struct SPIFlashHead fhead;
    12.         SPI0_USER |= SPI_CS_SETUP; // +1 такт перед CS
    13.         SPIRead(0, (uint32_t *)&fhead, sizeof(fhead));
    14.         // Установка размера Flash от 256Kbytes до 32Mbytes
    15.         // High four bits fhead.hsz.flash_size: 0 = 512K, 1 = 256K, 2 = 1M, 3 = 2M, 4 = 4M, ... 7 = 32M
    16.        uint32 fsize = fhead.hsz.flash_size & 7;
    17.         if(fsize < 2) flashchip->chip_size = (8 >> fsize) << 16;
    18.         else flashchip->chip_size = (4 << fsize) << 16;
    19.        uint32 fspeed = fhead.hsz.spi_freg;
    20.         // Установка:
    21.         // SPI Flash Interface (0 = QIO, 1 = QOUT, 2 = DIO, 0x3 = DOUT)
    22.         // and Speed QSPI: 0 = 40MHz, 1= 26MHz, 2 = 20MHz, ... = 80MHz
    23.         sflash_something(fspeed);
    24.         // SPIFlashCnfig(fhead.spi_interface & 3, (speed > 2)? 1 : speed + 2);
    25.         // SPIReadModeCnfig(5); // in ROM
    26.         // Всё - включаем кеширование, далее можно вызывать процедуры из flash
    27.         Cache_Read_Enable(0,0,1);
    28.         // Инициализация
    29.         startup(); // <-- там уже исполняются программы из Flash
    30.         // Передача управления ROM-BIOS
    31.         ets_run();
    32. }
    33. //-----------------------------------------------------------------------------
    34. // Установка скорости QSPI
    35. //  0 = 40MHz, 1 = 26MHz, 2 = 20MHz, >2 = 80MHz
    36. //-----------------------------------------------------------------------------
    37. void sflash_something(uint32 flash_speed)
    38. {
    39.     //    Flash QIO80:
    40.     //  SPI_CTRL = 0x16ab000 : QIO_MODE | TWO_BYTE_STATUS_EN | WP_REG | SHARE_BUS | ENABLE_AHB | RESANDRES | FASTRD_MODE | BIT12
    41.     //    IOMUX_BASE = 0x305
    42.     //  Flash QIO40:
    43.     //    SPI_CTRL = 0x16aa101
    44.     //    IOMUX_BASE = 0x205
    45.     uint32 xreg = (SPI0_CTRL >> 12) << 12; //  & 0xFFFFF000
    46.     uint32 value;
    47.     if (flash_speed > 2) { // 80 MHz
    48.         value = BIT(12); // 0x60000208 |= 0x1000
    49.         GPIO_MUX_CFG |= (1<< MUX_SPI0_CLK_BIT); // HWREG(IOMUX_BASE, 0) |= BIT(8);  // 80 MHz
    50.     }
    51.     else { // 0:40, 1:26, 2:20 MHz // 0x101, 0x202, 0x313
    52.         value = 1 + flash_speed + ((flash_speed + 1) << 8) + ((flash_speed >> 1)<< 4);
    53.         xreg &= ~BIT(12);  // 0x60000208 &= 0xffffefff
    54.         GPIO_MUX_CFG &= MUX_CFG_MASK & (~(1<< MUX_SPI0_CLK_BIT)); // HWREG(IOMUX_BASE, 0) &= ~(BIT(8));  // 0x60000800 &=  0xeff
    55.     }
    56.     SPI0_CTRL = xreg | value;
    57. }
    В заголовке flash ставится кол-во блоков загрузки = 0. Тогда нет сообщения ROM-BIOS о всяких контрольках и загрузках, на что уходит очень много времени на вывод их в UART на скорости 74880 Baud *. Итого от включения (reset или deep-sleep), до startup() проходит всего ~30 ms.
    Заголовки пока можно найти в Разработка ‘библиотеки’ малого webсервера на esp8266.
    * ROM-BIOS выводи сообщения в UART без fifo. Т.е. каждый новый символ перед выводом ожидает полного опустошения TX fifo UART:
    Код (C):
    1. // ROM:40003B30
    2. int uart_tx_one_char(uint8 ch)
    3. {
    4.     volatile uint32_t *uartregs = REG_UART_BASE(UartDev.buff_uart_no);
    5.     while(uartregs[IDX_UART_STATUS] & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S));
    6.     uartregs[IDX_UART_FIFO] = ch;
    7.     return 0;
    8. }
     
    Последнее редактирование: 7 май 2015
  4. Sonic

    Sonic Новичок

    Сообщения:
    1
    Симпатии:
    0
    Предполагается сделать полное описание функций из eagle.rom.addr.v6.ld c описанием аргументов, назначением адресов и логикой работы? По возможности с примерным кодом C тела функций?
     
  5. pvvx

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

    Сообщения:
    9.441
    Симпатии:
    1.320
    Хотя-бы заголовки, а то вообще ничего нет.
    Вместо описания, я обычно включаю IDA и смотрю, что они делают.
    Ещё не организовано "место и система сбора" где эти заголовки будут собираться. Т.е. пока этим озабочен я один, а мне легче это делать в своей "свалке".
     
  6. anakod

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

    Сообщения:
    314
    Симпатии:
    100
    pvvx, давайте подготовим краткий список ссылок по базовому введению в структуру SDK и процесс декомопиляции - какие плагины ставить, какие инструменты использовать. Это будет хорошей отправной точкой для всех кто будет готов помочь. Вы вроде уже писали по этой теме, можно здесь просто собрать подборку ссылок.
     
  7. pvvx

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

    Сообщения:
    9.441
    Симпатии:
    1.320
    anakod -
    Дело в том, что путей дизассемблирования несколько, и каждый случай имеет свои варианты.

    Для реверса ROM-BIOS ещё возможно что-то указать, но для совместного дизассемблирования некой прошивки+ ROM-BIOS необходимо создавать специальные скрипты и вариантов и предпочтений бесчисленное множество.

    Как итог, можно описать базовый вариант дизассемблирования только ROM-BIOS и только ELF файла прошивки с SDK. Совмещать их сложно и требуется (очень желательно) считывание всей памяти и регистров из чипа в базу IDA. Без этого очень сложно понять, что за данные и зачем туда обращается некий код. А при видимом содержимом разбор десятикратно упрощается. Для считывания всех данных надо писать специальную программу в сам чип. Тем более версий SDK множество и они обновляются – на всё дать готовые скрипты для IDA не выйдет.
    Базы IDA выходят большими и выкладывать их в сеть нет смысла.

    ELF файл просто грузится в IDA и она сама там всё разберет, но данных не будет. Смотрите описание хоть тут:
    Цикл статей Reverse Engineering ESP8266 на хабре
    Часть 1: http://habrahabr.ru/post/255135/
    Часть 2: http://habrahabr.ru/post/255153/

    Но надо учесть, что там много ошибок по описанию самого чипа...

    И главное - в данном деле разбираются и принимают участие обычно (по опыту других больших народных проектов за последние 25 лет, а тут проект не "большой") не более 2..5 человек. Остальные - ничего не дают, а только требуют.
     
    Последнее редактирование: 22 апр 2015
  8. pvvx

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

    Сообщения:
    9.441
    Симпатии:
    1.320
    В итоге проще выкладывать так, к примеру текущий вариант по SPI в ROM-BIOS:
    Код (C):
    1.  
    2. /******************************************************************************
    3. * FileName: SpiFlash.c
    4. * Description: SPI FLASH funcs in ROM-BIOS
    5. * Alternate SDK ver 0.0.0 (b0)
    6. * Author: PV`
    7. * (c) PV` 2015
    8. *******************************************************************************/
    9. #include "c_types.h"
    10. #include "bios/spiflash.h"
    11. #include "esp8266.h"
    12. #include "driver/spi_register.h"
    13.  
    14. // ROM:4000448C
    15. SpiFlashOpResult Wait_SPI_Idle(SpiFlashChip *sflashchip)
    16. {
    17.     uint32_t status;
    18.     While(HWREG(INTC_BASE, 0x0C) & BIT9);
    19.     return SPI_read_status(sflashchip, &status);
    20. }
    21.  
    22. // ROM:4000443C
    23. SpiFlashOpResult SPI_write_enable(SpiFlashChip *sflashchip)
    24. {
    25.     uint32_t status = 0;
    26.     Wait_SPI_Idle();
    27.     IOREG(SPI_CMD(0)) = SPI_WREN;
    28.     while(IOREG(SPI_CMD(0)));
    29.     while((status & BIT1) == 0) SPI_read_status(sflashchip,&status);
    30.     return SPI_FLASH_RESULT_OK;
    31. }
    32.  
    33. // ROM:40004400
    34. SpiFlashOpResult SPI_write_status(SpiFlashChip *sflashchip, uint32_t sta)
    35. {
    36.     Wait_SPI_Idle(sflashchip);
    37.     IOREG(SPI_RD_STATUS(0)) = sta;
    38.     IOREG(SPI_CMD(0)) = SPI_WREN;
    39.     while(IOREG(SPI_CMD(0)));
    40.     return SPI_FLASH_RESULT_OK;
    41. }
    42.  
    43. SpiFlashOpResult SPI_read_status(SpiFlashChip *sflashchip, uint32_t *sta)
    44. {
    45.     uint32_t status;
    46.     do {
    47.         IOREG(SPI_RD_STATUS(0)) = sta;
    48.         IOREG(SPI_CMD(0)) = SPI_READ;
    49.         while(IOREG(SPI_CMD(0)));
    50.         status = IOREG(SPI_RD_STATUS(0)) & sflashchip->status_mask;
    51.     } while(status & BIT0);
    52.     *sta = status;
    53.     return SPI_FLASH_RESULT_OK;
    54. }
    55.  
    56. // ROM:40004644
    57. SpiFlashOpResult spi_flash_attach(void){
    58.     SelectSpiFunction();
    59.     SPIFlashCnfig(5,4);
    60.     return SPIReadModeCnfig(5);
    61. }
    62.  
    63. // ROM:40004B44
    64. // ВНИМАНИЕ! имеет внутренную ошибку. Не используйте SPIEraseArea() функцию ROM-BIOS!
    65. SpiFlashOpResult SPIEraseArea (uint32 start_addr, uint32 lenght)
    66. {
    67.     uint32 num_sec_in_block;    // *(a1 + 0xC) = SP + 0xC
    68.     uint32 var_st_1;             // *(a1 + 4) = SP + 0x4
    69.     uint32 num_sec_erase;         // *(a1 + 0) = SP + 0x0
    70.     uint32 var_r_13;             // a13
    71.     uint32 first_sec_erase;     // a12
    72.     uint32 var_r_3;                // a3
    73.     uint32 var_r_0;                // a0
    74.  
    75.     SPIReadModeCnfig (5);
    76.     if (flashchip.chip_size >= (start_addr + lenght))
    77.     {
    78.         if ((start_addr % flashchip.sector_size) == 0)
    79.         {
    80.             if (SPIUnlock (flashchip) == 0)
    81.             {
    82.                 first_sec_erase = start_addr / flashchip.sector_size;             // First sector to erase
    83.                 num_sec_in_block = flashchip.block_size / flashchip.sector_size;     // Number of sectors in block
    84.                 num_sec_erase = lenght / flashchip.sector_size;                // Number of sectors to erase
    85.                 // Округляем количество секторов для стирания в большую сторону.
    86.                 if ((lenght % flashchip.sector_size) != 0) num_sec_erase ++; //
    87.                 var_r_13 = num_sec_erase;  // 9
    88.                 // Стираем посекторно до адреса кратного блочному стиранию.
    89.                 var_r_0 = num_sec_in_block - (first_sec_erase % num_sec_in_block); // кол-во секторов до адреса кратного блочному стиранию.
    90.                 if (var_r_0 < num_sec_erase) var_r_13 = var_r_0; // запомнить кол-во секторов до стирания
    91.  
    92.                 for ( ; var_r_13 != 0; first_sec_erase++, var_r_13--)
    93.                     if (SPIEraseSector (first_sec_erase) != 0) return 1;
    94.                 // Если оставшеестя количество секторов для стирания помещается в n-блоков,
    95.                 // то стираем n-блоков.
    96.                 var_r_13 = num_sec_erase - var_r_13; // var_r_13 = num_sec_erase - 0
    97.                 for ( ; num_sec_in_block < var_r_13; first_sec_erase += num_sec_in_block, var_r_13 -= num_sec_in_block)
    98.                     if (SPIEraseBlock(first_sec_erase / num_sec_in_block) != 0) return 1;
    99.                 // Стираем оставшиеся сектора в конце.
    100.                 for ( ; var_r_13 != 0; first_sec_erase ++,  var_r_13 --)
    101.                     if (SPIEraseSector (first_sec_erase) != 0) return 1;
    102.                 return SPI_FLASH_RESULT_OK;
    103.             }
    104.         }
    105.     }
    106.     return SPI_FLASH_RESULT_ERR;
    107. }
    108.  
    109. // ROM:40004C2C
    110. SpiFlashOpResult SPIParamCfg(uint32_t deviceId, uint32_t chip_size, uint32_t block_size, uint32_t sector_size, uint32_t page_size, uint32_t status_mask)
    111. {
    112.     flashchip->deviceId = deviceId;
    113.     flashchip->chip_size = chip_size;
    114.     flashchip->block_size = block_size;
    115.     flashchip->sector_size = sector_size;
    116.     flashchip->page_size = page_size;
    117.     flashchip->status_mask = status_mask;
    118.     return SPI_FLASH_RESULT_OK;
    119. }
    120.  
    121. // ROM:400048A8
    122. SpiFlashOpResult SPILock(void)
    123. {
    124.     if(SPI_write_enable(flashchip) != SPI_FLASH_RESULT_OK) return SPI_FLASH_RESULT_ERR;
    125.     return SPI_write_status(flashchip, 0x1C);
    126. }
    127.  
    128. // ROM:40004878
    129. SpiFlashOpResult SPIUnlock(void)
    130. {
    131.     if(SPI_write_enable(flashchip) != SPI_FLASH_RESULT_OK) return SPI_FLASH_RESULT_ERR;
    132.     return SPI_write_status(flashchip, 0);
    133. }
    134.  
    135.  
    136. // ROM:40004120
    137. SpiFlashOpResult spi_erase_block(SpiFlashChip *fchip, uint32_t addr)
    138. {
    139.     Wait_SPI_Idle(fchip);
    140.     IOREG(SPI_ADDR(0)) =  addr & 0xFFFFFF;
    141.     IOREG(SPI_CMD(0)) = SPI_BE;
    142.     while(IOREG(SPI_CMD(0)));
    143.     Wait_SPI_Idle(fchip);
    144.     return SPI_FLASH_RESULT_OK;
    145. }
    146.  
    147. // ROM:400049B4
    148. SpiFlashOpResult SPIEraseBlock(uint32_t blocknum)
    149. {
    150.     SpiFlashChip *fchip = flashchip;
    151.     if(blocknum > fchip->chip_size / fchip->block_size) return SPI_FLASH_RESULT_ERR;
    152.     if(SPI_write_enable(fchip) != SPI_FLASH_RESULT_OK) return SPI_FLASH_RESULT_ERR;
    153.     if(spi_erase_block(fchip, fchip->block_size * blocknum) != SPI_FLASH_RESULT_OK) return SPI_FLASH_RESULT_ERR;
    154.     return SPI_FLASH_RESULT_OK;
    155. }
    156.  
    157. // ROM:400040C0
    158. SpiFlashOpResult spi_erase_sector(SpiFlashChip *fchip, uint32_t addr)
    159. {
    160.     if(addr*0xFFF) return SPI_FLASH_RESULT_ERR;
    161.     Wait_SPI_Idle(fchip);
    162.     IOREG(SPI_ADDR(0)) =  addr & 0xFFFFFF;
    163.     IOREG(SPI_CMD(0)) = SPI_SE;
    164.     while(IOREG(SPI_CMD(0)));
    165.     Wait_SPI_Idle(fchip);
    166.     return SPI_FLASH_RESULT_OK;
    167. }
    168.  
    169. // ROM:40004A00
    170. SpiFlashOpResult SPIEraseSector(uint32_t sectornum)
    171. {
    172.     SpiFlashChip *fchip = flashchip;
    173.     if(sectornum > fchip->chip_size / fchip->sector_size) return SPI_FLASH_RESULT_ERR;
    174.     if(SPI_write_enable(fchip) != SPI_FLASH_RESULT_OK) return SPI_FLASH_RESULT_ERR;
    175.     if(spi_erase_sector(fchip, fchip->sector_size * sectornum) != SPI_FLASH_RESULT_OK) return SPI_FLASH_RESULT_ERR;
    176.     return SPI_FLASH_RESULT_OK;
    177. }
    178.  
    179. // ROM:40004080
    180. SpiFlashOpResult spi_erase_chip(SpiFlashChip *fchip)
    181. {
    182.     Wait_SPI_Idle(fchip);
    183.     IOREG(SPI_CMD(0)) = SPI_CE;
    184.     while(IOREG(SPI_CMD(0)));
    185.     Wait_SPI_Idle(fchip);
    186.     return SPI_FLASH_RESULT_OK;
    187. }
    188.  
    189. // ROM:40004984
    190. SpiFlashOpResult SPIEraseChip(void)
    191. {
    192.     if(SPI_write_enable(flashchip) != SPI_FLASH_RESULT_OK) return SPI_FLASH_RESULT_ERR;
    193.     if(spi_erase_chip(flashchip) != SPI_FLASH_RESULT_OK) return SPI_FLASH_RESULT_ERR;
    194.     return SPI_FLASH_RESULT_OK;
    195. }
    196.  
    197. // ROM:40004568
    198. void SPIFlashCnfig(uint32_t spi_interface, uint32_t spi_freg)
    199. {
    200.     //    Flash QIO80:
    201.     //  SPI_CTRL = 0x16ab000 - QIO_MODE | TWO_BYTE_STATUS_EN | WP_REG | SHARE_BUS | ENABLE_AHB | RESANDRES | FASTRD_MODE | BIT12
    202.     //    IOMUX_BASE = 0x305
    203.     //  Flash QIO40:
    204.     //    SPI_CTRL = 0x16aa101
    205.     //    IOMUX_BASE = 0x205
    206.     uint32 a6 = 0; // spi_interface > 4
    207.     uint32 a2;
    208.     HWREG(SPI0_BASE,0x1C) |= 4;
    209.     if(spi_interface == 0) a6 = 1<<24; // SPI_QIO_MODE
    210.     else if(spi_interface == 1) a6 = 1<<20; // SPI_QOUT_MODE
    211.     else if(spi_interface == 2) a6 = 1<<23; // SPI_DIO_MODE
    212.     else if(spi_interface == 3) a6 = 1<<14; // SPI_DOUT_MODE
    213.     else if(spi_interface == 4) a6 = 1<<13; // SPI_FASTRD_MODE
    214.     if(spi_freg < 2) {
    215.         a2 = 0x100;
    216.         HWREG(SPI0_BASE,0x08) |= 0x1000; // ???
    217.         HWREG(IOMUX_BASE,0) |= a2;
    218.     }
    219.     else {
    220.         a2 = (((spi_freg - 1) << 8) + spi_freg + (((spi_freg >> 1) - 1) << 4) - 1);
    221.         HWREG(SPI0_BASE,0x08) &= 0xFFFFEFFF;
    222.         HWREG(IOMUX_BASE,0) &= 0xEFF;
    223.     }
    224.     a2 |= a6;
    225.     a2 |= 0x288000; // SPI_RESANDRES | SPI_SHARE_BUS | SPI_WP_REG
    226.     HWREG(SPI0_BASE,0x08) |= a2;
    227.     HWREG(SPI0_BASE,0) = 0x100000;
    228.     while(HWREG(SPI0_BASE,0) != 0);
    229.     // [0x60000208] = 0x016aa101;
    230.     //                 0x00288000
    231.     //                 0x00411000 // BIT12 BIT16 BIT22
    232. }
    233.  
    234. // ROM:400042AC
    235. SpiFlashOpResult spi_flash_read(SpiFlashChip *fchip, uint32_t faddr, uint32_t *dst, size_t size)
    236. {
    237.     if(faddr + size > fchip->chip_size) return SPI_FLASH_RESULT_ERR;
    238.     Wait_SPI_Idle(fchip);
    239.     while(size >= 1) {
    240.         if(size < 32) {
    241.             IOREG(SPI_ADDR(0)) = faddr | (size << 24);
    242.             IOREG(SPI_CMD(0)) = SPI_READ;
    243.             while(IOREG(SPI_CMD(0)));
    244.         }
    245.         else {
    246.             IOREG(SPI_ADDR(0)) = faddr | BIT29; // 0x20000000 = 32 << 24
    247.             IOREG(SPI_CMD(0)) = SPI_READ;
    248.             while(IOREG(SPI_CMD(0)));
    249.         }
    250. //        move dst, SPI0_W0+...
    251. //        size -= read
    252.     }
    253.     return SPI_FLASH_RESULT_OK;
    254. }
    255.  
    256. // ROM:40004B1C
    257. SpiFlashOpResult SPIRead(uint32_t faddr, uint32_t *dst, size_t size)
    258. {
    259.     return spi_flash_read(flashchip, faddr, dst, size);
    260. }
    Но уже в окончательном варианте.
     
  9. pvvx

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

    Сообщения:
    9.441
    Симпатии:
    1.320
    Но и этого "описания функции" в Eclipse:
    Sampl23.gif
    большинству не нравится. Им требуется полный Help, да "с пивом и девками надом". :)
    Вы хотите слишком много – чтобы я стал и литературным писателем и описал всё имеющееся и как-то связанное ПО с проектами на ESP8266, да ещё “разреверсил” всю SDK, да описал, как это использовать... Один человек это будет делать очень долго. Надо распределять задачи. Наброски как и что – даны и лежат уже месяцами на форуме. Где желающие потратить своё время на разбор и выложить всем? Нема :p Пока только одни "дом советов" и портировщики чужого.
    ------
    Мы не закончили разговор где и как сделать “базу” на гитхабе. Я её обслуживать не смогу, но добавлять и исправлять – смогу (научите).
     
    Последнее редактирование: 22 апр 2015
  10. anakod

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

    Сообщения:
    314
    Симпатии:
    100
    pvvx, с описанием\структурированием я вероятно смогу помочь. Статьи на хабре прочитал, в целом все понятно, первоочередной вопрос - есть ли возможность автоматической частичной декомпиляции в Си код или только ассемблерный код и ручками?

    По гитхабу все очень просто, через веб интерфейс создаете проект, затем синхронизируете его к себе на компьютер и добавляете все файлы локально. Я использую SourceTree, но как понимаю, Github for Windows должен быть еще проще\удобнее. После того как у Вас есть локальная копия Вы в один клик можете пушить актуальные измениеия на сервер, очень большое удобство в том что ничего никогда не потеряется и все изменения на виду - ясно что добавилось и изменилось, пользователям и другим разработчикам проще следить за развитием, помогать выявлять баги. Если кто-то делает какую-нибдь часть работы, он присылает Вам pull request, Вы его принимаете или запрашиваете дополнительные доработки перед принятием. Изменения автоматически сливаются, т.к. Git умеет сливать код самостоятельно (конфликты возможно но бывают крайне редко).

    Я бы предложил завести отдельный простой проект содержащий только разобранную часть SDK без всего лишнего. Этот проект может собираться в библиотеку (или несколько библиотек), которая(ые) будет линковаться к любому проекту (всем Вашим веб разработкам, моему Sming и т.д.) и будет заменять стандартный прожорливый SDK Espressif.

    Если есть какие-нибудь вопросы - готов подсказать\помочь. Направление это на мой взгляд сейчас одно из самых важных.
     
  11. pvvx

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

    Сообщения:
    9.441
    Симпатии:
    1.320
    Ручками. IDA и имеющийся к ней плагин и так с ошибками, тем более он ничего не понимает в передаче параметров функциям через регистры у данного CPU.
    Ещё раз: По началу надо отделить полностью "мух от котлет" - нужны отдельные описания ROM-BIOS без всяких SDK. Это будет базой, на которую уже можно писать загрузчики и будут опираться ссылки из SDK. Иначе опять бардак с 'инклудами'. На этом всё и висит. К данной теме можно сделать и проект, пока без WiFi, но обработкой датчиков и прочего. Загрузить SDK и сейчас можно.
     
    Последнее редактирование: 22 апр 2015
  12. anakod

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

    Сообщения:
    314
    Симпатии:
    100
    Очень жаль если честно. А где можно почитать про данный Assembler?

    А насколько много еще работы по ROM-BIOS и какие части надо доразобрать? Делать SDK можно как сейчас постепенно замещая закрытые библиотеки Espressif, но насчет разделения на слои (описания ROM-BIOS и отдельно SDK) - полностью согласен. По идее это может быть и два проекта на гитхабе (один затем может использоваться как подмодуль в другом).

    Касательно SDK - не обязательно делать его "толстым", вполне подойдет минимальный необходимый набор от которого уже можно будет двигаться к следующему новому функционалу (типа динамической загрузки и т.п.).
     
  13. pvvx

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

    Сообщения:
    9.441
    Симпатии:
    1.320
    В Xtensa® Instruction Set Architecture (ISA) Reference Manual (4.8 MB)
    Только основные, которые можно использовать. Загрузчик с его процедурами не нужен, а c WiFi там тоже "темный лес". Так что не так много ещё - под 80% заголовков уже есть. Описания нет, т.е. мало.
    Счас закончил с UART процедурами (типа исходники всех процедур, что можно запользовать в ROM-BIOS)...
    Код (C):
    1. /******************************************************************************
    2.  * FileName: UartDev.c
    3.  * Description: UART funcs in ROM-BIOS
    4.  * Alternate SDK ver 0.0.0 (b0)
    5.  * Author: PV`
    6.  * (c) PV` 2015
    7. *******************************************************************************/
    8. #include "bios/uartdev.h"
    9. #include "esp8266.h"
    10.  
    11. //uint8 RcvBuff[256];
    12. //uint8 TrxBuff[100];
    13. #define RcvBuff  ((uint8 *)0x3fffde60)
    14. #define TrxBuff  (&RcvBuff[0x100]) // ((uint8 *)0x3fffdf60)
    15.  
    16. // ROM:40003BBC
    17. void uart_rx_intr_handler(void *par)
    18. {
    19.     volatile uint32_t *uartregs = REG_UART_BASE(UartDev.buff_uart_no);
    20.     if((uartregs[2] & UART_RXFIFO_FULL_INT_ST) == 0) return; // UART_INT_ST(x) & UART_RXFIFO_FULL_INT_ST
    21.     uartregs[4] = 1; // UART_INT_CLR
    22.     while(uartregs[7] & UART_RXFIFO_CNT) { // UART_STATUS(x) & UART_RXFIFO_CNT
    23.         RcvMsgBuff * rcvmsg = (RcvMsgBuff *)par;
    24.         register uint8 c = uartregs[0]; // UART_FIFO(x)
    25.         if(c == '\n') rcvmsg->BuffState = WRITE_OVER;
    26.         *rcvmsg->pWritePos++ = c;
    27.         if(rcvmsg->pWritePos >= rcvmsg->pRcvMsgBuff + rcvmsg->RcvBuffSize) {
    28.             rcvmsg->pWritePos = rcvmsg->pRcvMsgBuff;
    29.         }
    30.     }
    31. }
    32.  
    33. // ROM:4000383C
    34. void uartAttach(void)
    35. {
    36.     // &UartDev.RcvMsgBuff;
    37.     UartDev.baut_rate = BIT_RATE_115200;
    38.     UartDev.data_bits = EIGHT_BITS;
    39.     UartDev.exist_parity = STICK_PARITY_DIS;
    40.     UartDev.parity = NONE_BITS;
    41.     UartDev.stop_bits = ONE_STOP_BIT;
    42.     UartDev.flow_ctrl = NONE_CTRL;
    43.     UartDev.rcv_buff.RcvBuffSize = RX_BUFF_SIZE;
    44.     UartDev.rcv_buff.pRcvMsgBuff = RcvBuff; //    &UartDev + 0x50
    45.     UartDev.rcv_buff.pWritePos = RcvBuff;
    46.     UartDev.rcv_buff.pReadPos = RcvBuff;
    47.     UartDev.rcv_buff.TrigLvl = 1;
    48.     UartDev.rcv_buff.BuffState = EMPTY;
    49.     UartDev.trx_buff.TrxBuffSize = TX_BUFF_SIZE;
    50.     UartDev.trx_buff.pTrxBuff =    TrxBuff;
    51.     UartDev.rcv_state = BAUD_RATE_DET;
    52.     UartDev.received = 0;
    53.     UartDev.buff_uart_no = UART0;
    54.  
    55.     ets_isr_mask(1 << ETS_UART_INUM);
    56.     ets_isr_attach(ETS_UART_INUM, uart_rx_intr_handler, &UartDev.rcv_buff);
    57. }
    58.  
    59. // ROM:40003B8C
    60. int uart_rx_one_char(uint8 *ch)
    61. {
    62.     volatile uint32_t *uartregs = REG_UART_BASE(UartDev.buff_uart_no);
    63.     if(uartregs[7] & UART_RXFIFO_CNT) {
    64.         *ch = uartregs[0];
    65.         return 0;
    66.     }
    67.     return 1;
    68. }
    69.  
    70. // ROM:40003B64
    71. uint8 uart_rx_one_char_block(void)
    72. {
    73.     volatile uint32_t *uartregs = REG_UART_BASE(UartDev.buff_uart_no);
    74.     while((uartregs[7] & UART_RXFIFO_CNT)==0);
    75.     return uartregs[0];
    76. }
    77.  
    78. // ROM:40003EC8
    79. int uart_rx_readbuff(RcvMsgBuff * rcvmsg, uint8 *dst)
    80. {
    81.     if(rcvmsg->pReadPos == rcvmsg->pWritePos) return 1;
    82.     *dst = *rcvmsg->pReadPos++;
    83.     if(rcvmsg->pReadPos >= rcvmsg->pRcvMsgBuff + rcvmsg->RcvBuffSize) {
    84.                 rcvmsg->pReadPos = rcvmsg->pRcvMsgBuff;
    85.     }
    86.     return 0;
    87. }
    88.  
    89. // ROM:40003B30
    90. int uart_tx_one_char(uint8 ch)
    91. {
    92.     volatile uint32_t *uartregs = REG_UART_BASE(UartDev.buff_uart_no);
    93.     while(uartregs[7] & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S));
    94.     uartregs[0] = ch;
    95.     return 0;
    96. }
    97.  
    98. // ROM:400038A4
    99. void uart_buff_switch(uint8 uartnum)
    100. {
    101.     if(uartnum) {
    102.         UartDev.buff_uart_no = uartnum;
    103.         return;
    104.     }
    105.     volatile uint32_t *uartregs = REG_UART_BASE(UartDev.buff_uart_no);
    106.     uartregs[4] = 0xFFFF; // UART_INT_CLR(UartDev.buff_uart_no)
    107.     uartregs[3] &= 0xE00;
    108.     uint8 ch;
    109.     while(uart_rx_one_char(&ch) == 0 &&    uart_rx_readbuff(&UartDev.rcv_buff, &ch));
    110.     UartDev.rcv_buff.BuffState = EMPTY;
    111. }
    112.  
    113. // ROM:400039D8
    114. void uart_div_modify(uint32 uart_num, uint32 div_baud)
    115. {
    116.     volatile uint32_t *uartregs = REG_UART_BASE(uart_num);
    117.     register uint32 x = uartregs[6];
    118.     uartregs[6] = x | UART_TXFIFO_RST | UART_RXFIFO_RST;
    119.     uartregs[5] = div_baud; // UART_CLKDIV(uart_num) = div_baud
    120.     uartregs[8] = x  & (~(UART_TXFIFO_RST | UART_RXFIFO_RST));
    121. }
    122.  
    123. // ROM:40003924
    124. uint32 uart_baudrate_detect(uint32 uart_num, uint32 flg)
    125. {
    126.     volatile uint32_t *uartregs = REG_UART_BASE(uart_num);
    127.     if(UartDev.rcv_state != BAUD_RATE_DET) {
    128.         uartregs[6] &= 0x7E; // UART_AUTOBAUD(uart_num)
    129.         uartregs[6] = 0x801; // UART_AUTOBAUD(uart_num)
    130.         UartDev.rcv_state = WAIT_SYNC_FRM;
    131.     }
    132.     while(uartregs[12] >= 29) { // UART_PULSE_NUM(uart_num)
    133.         if(flg) return 0;
    134.         ets_delay_us(1000);
    135.     }
    136.     uint32 ret = (((uartregs[10] & 0xFFFFF) + (uartregs[11] & 0xFFFFF)) >> 1) + 12;  // UART_LOWPULSE(uart_num) + UART_HIGHPULSE(uart_num)
    137.     uartregs[6] &= 0x7E; // UART_AUTOBAUD(uart_num)
    138.     return ret;
    139. }
    140.  
    141. // ROM:40003EF4
    142. int UartGetCmdLn(uint8 *buf)
    143. {
    144.     if(UartDev.rcv_buff.BuffState == WRITE_OVER) {
    145.         uint8 ch;
    146.         if(uart_rx_readbuff(&UartDev.rcv_buff, &ch) == 0) {
    147.             do {
    148.                 *buf++ = ch;
    149.             } while(uart_rx_readbuff(&UartDev.rcv_buff, &ch)==0);
    150.             *buf = '\0';
    151.             UartDev.rcv_buff.BuffState = EMPTY;
    152.             return 0;
    153.         }
    154.     }
    155.     return 1;
    156. }
     
    Последнее редактирование: 23 апр 2015
  14. pvvx

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

    Сообщения:
    9.441
    Симпатии:
    1.320
    Значит что у нас на сегодня c функциями ROM-BIOS?
    Использовать это нельзя:
    /* WARNING !!! mem_xxx use size < 4096 !!! */
    extern void mem_init(void * start_addr); // uint8 *
    extern void * mem_malloc(uint16 size); // size < 4096
    extern void * mem_calloc(uint16 n, uint16 count); // n*count < 4096
    extern void * mem_zalloc(uint16 size); // size < 4096, = mem_calloc(1, size);
    extern void * mem_realloc(void * p, uint16 size);
    extern void * mem_trim(void * p, uint16 size);
    extern void mem_free(uint8 * x);

    Они ограничены 4 килобайтами - это песочница в ram для bios и даже в нем не используется....
    void rtc_enter_sleep(void);
    Работает без SDK, но потребление у модуля падает до порядков в 5..9 mA (измерено с включенной внешней FT2232C на 2UART TX/RX/RTS.. и т.д. чтобы смотреть логи и поведение). UART и прочее тактирование тухнет на время sleep...
    Для теста можно задать dtm_params_init(NULL, NULL) + dtm_set_params(0, time, 0, 0, 0) и вызвать rtc_enter_sleep().
    void dtm_params_init(void * sleep_func, void * int_func);
    void dtm_set_params(int a2, int time_ms, int a4, int a5, int a6);
     
  15. anakod

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

    Сообщения:
    314
    Симпатии:
    100
    nikolz, наиболее полные исходники реверса SDK находятся здесь: http://esp8266.ru/forum/threads/razrabotka-biblioteki-malogo-webservera-na-esp8266.56/

    В первую очередь смотрите:
    • app/include
    • app/main
    • app/phy
    - это разобранные исходники соответствующих библиотек из комплекта SDK и инклуды описывающие множество встроенных функций.

    Отдельного github репозитория под SDK к сожалению пока еще нет..

    Прикольно, я когда их в первый раз заметил, подумал почему бы не взять их вместо portMalloc... :)
     
  16. pvvx

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

    Сообщения:
    9.441
    Симпатии:
    1.320
    И не будет, пока не соберется что-то значительное. Т.е. в нем нет смысла, т.к. всё меняется постоянно в исходниках и они пока представляют из себя киш-миш :)
     
  17. pvvx

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

    Сообщения:
    9.441
    Симпатии:
    1.320
    Их можно использовать, задав базовый адрес песочницы:
    Код (C):
    1. void call_user_start(void)
    2. {
    3.     ets_update_cpu_frequency(52);
    4.     ets_printf("\nStart RAM porg\n");
    5.     mem_init((uint8 *)0x3fff0000);
    6.       ets_uart_printf("--------\n");
    7.  
    8.       uint32 x = 32;
    9.       dtm_params_init(NULL, NULL);
    10.       dtm_set_params(0,3000*26/40,0,0,0);
    11.       while(x) {
    12.             uint8 *addr1 = mem_malloc(x);
    13.             ets_uart_printf("mem_malloc(%u) = %p # ", x, addr1);
    14.          ets_delay_us(3000); // чтобы прошли UART символы, иначе залипнет прямо на выводе бита и будет светить светодиодом на GPIO1 (который используется как прерывание sleep и при настроенном как выход TX не пашет :) )
    15.             rtc_enter_sleep();
    16.          ets_delay_us(3000); // а тут чтобы восстановилась pll была нормальная скорость UART для следующих soo...
    17.             uint8 *addr2 = mem_malloc(x-32);
    18.             ets_uart_printf("mem_malloc(%u) = %p\n", x-32, addr2);
    19.             mem_free(addr1);
    20.             mem_free(addr2);
    21.             x <<= 1;
    22.       }
    23.       ets_uart_printf("--------\n");
    24.     ets_run();
    25. }
    Загружается в IRAM для теста. Make примерно так
    loadram: $(APP).elf
    $(ESPTOOL) -p $(ESPPORT) load_ram $(APP)-0x00000.bin

    Скорость вывода UART будет та, с которой загружался код в ESPTOOL.
    Получаем лог:
    Код (Text):
    1. Start RAM porg
    2. --------
    3. mem_malloc(32) = 0x3fff0008 # mem_malloc(0) = 0x00000000
    4. mem_malloc(64) = 0x3fff0008 # mem_malloc(32) = 0x3fff0050
    5. mem_malloc(128) = 0x3fff0008 # mem_malloc(96) = 0x3fff0090
    6. mem_malloc(256) = 0x3fff0008 # mem_malloc(224) = 0x3fff0110
    7. mem_malloc(512) = 0x3fff0008 # mem_malloc(480) = 0x3fff0210
    8. mem_malloc(1024) = 0x3fff0008 # mem_malloc(992) = 0x3fff0410
    9. mem_malloc(2048) = 0x3fff0008 # mem_malloc(2016) = 0x3fff0810
    10. mem_malloc(4096) = 0x00000000 # mem_malloc(4064) = 0x3fff0008
    11. mem_malloc(8192) = 0x00000000 # mem_malloc(8160) = 0x00000000
    12. mem_malloc(16384) = 0x00000000 # mem_malloc(16352) = 0x00000000
    13. mem_malloc(32768) = 0x00000000 # mem_malloc(32736) = 0x00000000
    14. mem_malloc(65536) = 0x00000000 # mem_malloc(65504) = 0x00000000
    15. mem_malloc(131072) = 0x00000000 # mem_malloc(131040) = 0x00000000
    16. mem_malloc(262144) = 0x00000000 # mem_malloc(262112) = 0x00000000
    17. mem_malloc(524288) = 0x00000000 # mem_malloc(524256) = 0x00000000
    18. mem_malloc(1048576) = 0x00000000 # mem_malloc(1048544) = 0x00000000
    19. mem_malloc(2097152) = 0x00000000 # mem_malloc(2097120) = 0x00000000
    20. mem_malloc(4194304) = 0x00000000 # mem_malloc(4194272) = 0x00000000
    21. mem_malloc(8388608) = 0x00000000 # mem_malloc(8388576) = 0x00000000
    22. mem_malloc(16777216) = 0x00000000 # mem_malloc(16777184) = 0x00000000
    23. mem_malloc(33554432) = 0x00000000 # mem_malloc(33554400) = 0x00000000
    24. mem_malloc(67108864) = 0x00000000 # mem_malloc(67108832) = 0x00000000
    25. mem_malloc(134217728) = 0x00000000 # mem_malloc(134217696) = 0x00000000
    26. mem_malloc(268435456) = 0x00000000 # mem_malloc(268435424) = 0x00000000
    27. mem_malloc(536870912) = 0x00000000 # mem_malloc(536870880) = 0x00000000
    28. mem_malloc(1073741824) = 0x00000000 # mem_malloc(1073741792) = 0x00000000
    29. mem_malloc(2147483648) = 0x00000000 # mem_malloc(2147483616) = 0x00000000
    30. --------
    и видим - максимальный удовлетворенный запрос = 4064 байта :)
    В большинстве функций mem_xxx стоит входная проверка > 4096 ничего незя.
     
    Последнее редактирование: 14 май 2015
  18. pvvx

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

    Сообщения:
    9.441
    Симпатии:
    1.320
    Вышла новая версия SDK 1.1.0.
    В IRAM перенесены вектора прерываний CPU с отладкой kernel-vector, nmi-vector....
    l32r a2, _stext ; 0x40100000
    wsr.vecbase a2

    В основные библиотеки (libmain.a) добавлены коды драйверов, таких как программный pwm и подобное (пухнут с каждым новым SDK)...
    Введена поддержка второй flash и флаг по которому происходит переключение, по тому добавлены разные вызовы Cache_Read_Enable(0, 0, 1) и Cache_Read_Enable(1, 0, 1)...
    Объем доступной пользователю памяти "heap" ещё уменьшился, но не сильно до сотни байт в сравнении с прошлым SDK (если использовать основные огрызки от библиотек Espressif). Объем iram уменьшился катастрофически (примерно ещё на пару кило).
     
    Последнее редактирование: 23 май 2015
  19. waskez

    waskez Новичок

    Сообщения:
    18
    Симпатии:
    3
    Будь проклят тот день, когда я ...
     
  20. anakod

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

    Сообщения:
    314
    Симпатии:
    100
    Да вроде и так давно уже ясно что все это идёт не туда..
     

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