• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

8710 странности с GPIO

pvvx

Активный участник сообщества
Разбирался с IP пинами, и получилась таблица
IP получал: HAL_GPIO_GetIPPinName_8195a(PA_0) - исходный код закрыт
Port и Pin: HAL_GPIO_GET_PORT_BY_NAME(), HAL_GPIO_GET_PIN_BY_NAME() - простое смещение
Что-то вообще не понятно - какой ещё IP ? Нафиг вам он? У вас RTL8195AM?

ROM-BIOS (перевод в код си из asm, для справки, могут быть неточности):
Код:
uint32_t HAL_GPIO_GetIPPinName_8195a(uint32_t chip_pin)
{
  return GPIO_GetIPPinName_8195a(chip_pin);
}
unsigned char GPIO_PinMap_Chip2IP_8195a[] = {...... };
uint32_t GPIO_GetIPPinName_8195a(uint32_t result)
{
  unsigned char *ptr = &GPIO_PinMap_Chip2IP_8195a[2];
  if(result) {
   while(*ptr != 255) {
    if(*ptr == (unsigned char) result) return result;
    ptr += 2;
   }
   DBG_GPIO_WARN("Cannot find pin for GPIO %d\n", result);
   result = 255;
  }
  return result;
}
Как видим - запрос по нулю (PA_0) всегда = 0.
Какого смысла тратить время и код на бесполезное сравнение готового номера в этот-же номер?
Посмотреть вложение 3705
Сложил с распиновкой чипа, однако ничего интересного не вышло
А что это за раскраска?
Код пина в SDK = (((код буквы порта)-'A')<<4) | (номер пина в порту): RTL00MP3/PinNames.h at master · pvvx/RTL00MP3 · GitHub

Тест в RtlDuino RtlDuino/Test_GPIO_out.ino at master · pvvx/RtlDuino · GitHub
В Arduino для доступа к пинам используется другая нумерация.
 
Последнее редактирование:

pvvx

Активный участник сообщества
В таблице PullUp указаны адреса регистров + 0x40000000
Таблицы находятся в ROM-BIOS, адреса указаны в *.ld файле. Код, исполняемый в ROM-BIOS и TCM RAM работает без дополнительных циклов ожидания, в SRAM и SDRAM с доп. тактами ожидания. Т.ч. нет смысла писать свой перевод номеров пинов или обращения к ним в своем коде - используйте процедуры ROM-BIOS.
Обращение к пинам идет через GPIO_LockV02() и GPIO_UnLockV02() (в ROM-BIOS) используются флаги _pHAL_Gpio_Adapter->Locked/_pHAL_Gpio_Adapter->Gpio_Func_En
 
Последнее редактирование:

Seeker

New member
GPIO_PinMap_Chip2IP_8195a есть часть того что я попытался описать.
Не спорю, что PC_0 = (2<<4|0) = 0x20
Работа с ногами из примеров:
Код:
void gpio_mode (gpio_t *obj, PinMode mode);
void gpio_dir  (gpio_t *obj, PinDirection direction);
void gpio_init(gpio_t *obj, PinName pin);
В gpio_init в конце есть функция, которая принимает структуру _HAL_GPIO_PIN_
[inline]HAL_GPIO_Init(&obj->hal_pin);[/inline]
где hal_pin.pin_name= HAL_GPIO_GetIPPinName_8195a(PC_0 ); // = 42 для PC_0
Внутри HAL_GPIO_Init есть следующая функция
[inline]HAL_GPIO_Init_8195a(_HAL_GPIO_PIN_); // что делает неизвестно, кода нет[/inline]
Также gpio_write(gpio_t *obj, int value)
Ипользует:
Код:
pin_num = obj->hal_pin_num;       // = HAL_GPIO_GET_PORT_BY_NAME(hal_pin.pin_name ); // = 10 для hal_pin.pin_name = 42 , расчитывается по смещению
port_num = obj->hal_port_num;    // = HAL_GPIO_GET_PIN_BY_NAME(hal_pin.pin_name );    // = 1 по смещению
Код:
reg_value =  HAL_READ32(GPIO_REG_BASE, GPIO_SWPORT_DR_TBL[port_num]);
reg_value &= ~(1 << pin_num);
reg_value |= ((value&0x01)<< pin_num);
HAL_WRITE32(GPIO_REG_BASE, GPIO_SWPORT_DR_TBL[port_num], reg_value);
Вот и пришел я к заключению, что порты A, B,C ,E которые написаны на модуле и в даташите просто фантик. А внутри они сидят на двух портах.
Но из предоставленного Вами массива GPIO_PinMap_Chip2IP_8195a, видно что портов три.
Данное исследование предводит к надобности переписать gpio исходники полностью.
 
Последнее редактирование:
  • Like
Реакции: KomX

pvvx

Активный участник сообщества
Вот и пришел я к заключению, что порты A, B,C ,E которые написаны на модуле и в даташите просто фантик. А внутри они сидят на двух портах.
Но из предоставленного Вами массива GPIO_PinMap_Chip2IP_8195a, видно что портов три.
Данное исследование предводит к надобности переписать gpio исходники полностью.
Зачем переписывать ROM? И как? :)
Физически быти управления пинами раскиданы, можно так выразиться по группам в 3 32-х битных регистров SoC. И то регистры подтяжек и прочего управления пинов находятся в других полях и занимают не 3 ристра :) Какого смысла делать свою таблицу? Придется переписывать весь HAL на все устройства, с целью получить другие таблицы и переписать всю документацию, включая рисунки чипов? Что это меняет?
Описания адресов управления пинами даны в хидерах, таблицы соответствия пинов к ним в ROM и все процедуры уже есть. Нет никакого смысла это переписывать, кроме как увеличить размер кода в RAM.
И зачем в исходниках SDK исходники ROM? Её всё равно не поменять.

@Seeker - с чем боритесь? Получить линейную адресацию всех устройств и пинов всё равно не удастся - будут другие таблицы с другими именами пинов и ничего не измениться, кроме большего объема кода в RAM.
Обращаться напрямую к регистрам в многозадачной (RTOS) среде нельзя. Пока вы будите работать со считанным значением регистра, его может изменить другая задача и будут конфликты. Подход, как это применялось в 8-ми битных простых MCU тут не применим.
Чтобы изменить бит пина вашей задаче надо запросить и взять флаг у RTOS что она занимает устройство i/o и другие задачи пока будут ждать окончания работы вашей. Когда ваша задача изменит значение пина, то должна отдать флаг системе - освободить устройство i/o. После этого ожидающие задачи смогут тоже изменить i/o. Для пользователя и существует уровень api работы с пинами, где это всё уже исполняется.
HAL уровень не имеет связи с RTOS, а описывает только абстракцию аппаратного уровня.
Api уровень строится над HAL и связывает работу с системой (RTOS).
Напрямую в регистры в пользовательской части кода никто не лезет.
Если пишите специальный драйвер для работы с i/o, то придется учесть работу других устройств и их структуры. Сложного там ничего нет.
Обращение к пинам идет через GPIO_LockV02() и GPIO_UnLockV02() (в ROM-BIOS) используются флаги _pHAL_Gpio_Adapter->Locked/_pHAL_Gpio_Adapter->Gpio_Func_En
Получить физический адрес бита так-же не сложно - используйте уже имеющиеся процедуры в ROM, переводящие виртуальный адрес порта и пина в физический для каждого типа доступа - чтения значения, или изменения направления i/o, или изменения бита прерывания, или изменения битов PullUp. Они могут быть разными в разных позициях физических регистров SoC. По этому линейного понятия - это регистр порта 'A' - нет. Есть только виртуальные.
 
Последнее редактирование:

Seeker

New member
Вот так люблю работать с ножками
Пример Stm'a
Код:
SysReg(GPIO_PC + GPIO_BRR)=PIN_14;
где:
#define SysReg(x) *((volatile u32*)(x))
#define GPIO_PC  (u32)(0x40011000)
#define GPIO_BRR  (u32)(0x14)
#define PIN_14  ((u32)0x4000)
На RTL'е сейчас тьма мусора, преобразования туда сюда. Меня такой код не устраивает. А в многопоточности надобности до сих пор не было.
 

Seeker

New member
Та таблица которую вычислял оказалась
const u8 Default_Port_PinDef[GPIO_PORT_NUM][GPIO_PORT_WIDTH+1]
из common\mbed\targets\hal\rtl8195a\port_api.c
Там повторно реализованы методы работы с gpio.
Копирайт древний "Copyright (c) 2006-2013 ARM Limited".
 

pvvx

Активный участник сообщества
Последнее редактирование:

pvvx

Активный участник сообщества
Код:
#ifndef _BITBAND_IO_H_
#define _BITBAND_IO_H_

#include "hal_platform.h"
#include "hal_api.h"
#include "hal_gpio.h"
#include "rtl8195a_gpio.h"

#define BITBAND_PERI_REF    0x40000000
#define BITBAND_PERI_BASE    0x42000000
#define BITBAND_PERI(a,b)    (BITBAND_PERI_BASE + (a-BITBAND_PERI_REF)*32 + (b*4))    // Convert PERI address
#define ucBITBAND_PERI(a,b)    *((volatile unsigned char *)BITBAND_PERI(a,b))
#define uiBITBAND_PERI(a,b) *((volatile unsigned int *)BITBAND_PERI(a,b))

#define GPIO_A0 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,0)    //Port = 0, bit = 0, A0
#define GPIO_A1 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,1)    //Port = 0, bit = 1, A1
#define GPIO_A2 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,0)    //Port = 1, bit = 0, A2
#define GPIO_A3 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,1)    //Port = 1, bit = 1, A3
#define GPIO_A4 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,2)    //Port = 1, bit = 2, A4
#define GPIO_A5 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,3)    //Port = 1, bit = 3, A5
#define GPIO_A6 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,4)    //Port = 1, bit = 4, A6
#define GPIO_A7 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,5)    //Port = 1, bit = 5, A7

#define GPIO_B0 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,6)    //Port = 1, bit = 6, B0
#define GPIO_B1 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,7)    //Port = 1, bit = 7, B1
#define GPIO_B2 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,8)    //Port = 1, bit = 8, B2
#define GPIO_B3 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,2)    //Port = 0, bit = 2, B3
#define GPIO_B4 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,3)    //Port = 0, bit = 3, B4
#define GPIO_B5 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,9)    //Port = 1, bit = 9, B5
#define GPIO_B6 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,4)    //Port = 0, bit = 4, B6
#define GPIO_B7 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,5)    //Port = 0, bit = 5, B7

#define GPIO_C0 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,10)    //Port = 1, bit = 10, C0
#define GPIO_C1 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,6)     //Port = 0, bit = 6,  C1
#define GPIO_C2 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,11)    //Port = 1, bit = 11, C2
#define GPIO_C3 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,7)     //Port = 0, bit = 7,  C3
#define GPIO_C4 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,8)    //Port = 0, bit = 8,  C4
#define GPIO_C5 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,9)    //Port = 0, bit = 9,  C5
#define GPIO_C6 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,10)   //Port = 0, bit = 10, C6
#define GPIO_C7 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,11)    //Port = 0, bit = 11, C7
#define GPIO_C8 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,12)    //Port = 0, bit = 12, C8
#define GPIO_C9 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,13)    //Port = 0, bit = 13, C9

#define GPIO_D0 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,12)  //Port = 1, bit = 12, D0
#define GPIO_D1 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,14)  //Port = 0, bit = 14, D1
#define GPIO_D2 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,13)  //Port = 1, bit = 13, D2
#define GPIO_D3 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,15)  //Port = 0, bit = 15, D3
#define GPIO_D4 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,16)  //Port = 0, bit = 16, D4
#define GPIO_D5 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,17)  //Port = 0, bit = 17, D5
#define GPIO_D6 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,18)  //Port = 0, bit = 18, D6
#define GPIO_D7 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,19)  //Port = 0, bit = 19, D7
#define GPIO_D8 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,14)  //Port = 1, bit = 14, D8
#define GPIO_D9 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,20)  //Port = 0, bit = 20, D9

#define GPIO_E0 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,15)  //Port = 2, bit = 15, E0
#define GPIO_E1 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,21)  //Port = 0, bit = 21, E1
#define GPIO_E2 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,22)  //Port = 0, bit = 22, E2
#define GPIO_E3 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,23)  //Port = 0, bit = 23, E3
#define GPIO_E4 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,16)  //Port = 1, bit = 16, E4
#define GPIO_E5 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,24)  //Port = 0, bit = 24, E5
#define GPIO_E6 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,25)  //Port = 0, bit = 25, E6
#define GPIO_E7 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,26)  //Port = 0, bit = 26, E7
#define GPIO_E8 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,27)  //Port = 0, bit = 27, E8
#define GPIO_E9 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,17)  //Port = 1, bit = 17, E9
#define GPIO_E10 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,18) //Port = 1, bit = 17, E10

#define GPIO_F0 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,19)  //Port = 1, bit = 19, F0
#define GPIO_F1 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,20)  //Port = 1, bit = 20, F1
#define GPIO_F2 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,21)  //Port = 1, bit = 21, F2
#define GPIO_F3 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,22)  //Port = 1, bit = 22, F3
#define GPIO_F4 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,23)  //Port = 1, bit = 23, F4
#define GPIO_F5 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,24)  //Port = 1, bit = 24, F5

#define GPIO_G0 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,25)  //Port = 1, bit = 25, G0
#define GPIO_G1 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,26)  //Port = 1, bit = 26, G1
#define GPIO_G2 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,27)  //Port = 1, bit = 27, G2
#define GPIO_G3 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,28)  //Port = 0, bit = 28, G3
#define GPIO_G4 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,28)  //Port = 1, bit = 28, G4
#define GPIO_G5 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,29)  //Port = 1, bit = 29, G5
#define GPIO_G6 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,30)  //Port = 1, bit = 30, G6
#define GPIO_G7 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,31)  //Port = 1, bit = 31, G7

#define GPIO_H0 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,0)   //Port = 2, bit = 0,  H0
#define GPIO_H1 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,29)  //Port = 0, bit = 29, H1
#define GPIO_H2 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,1)   //Port = 2, bit = 1,  H2
#define GPIO_H3 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,30)  //Port = 0, bit = 30, H3
#define GPIO_H4 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,2)   //Port = 2, bit = 2,  H4
#define GPIO_H5 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,31)  //Port = 0, bit = 31, H5
#define GPIO_H6 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,3)   //Port = 2, bit = 3,  H6
#define GPIO_H7 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,4)   //Port = 2, bit = 4,  H7

#define GPIO_I0 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,5)   //Port = 2, bit = 5,  I0
#define GPIO_I1 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,6)   //Port = 2, bit = 6,  I1
#define GPIO_I2 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,7)   //Port = 2, bit = 7,  I2
#define GPIO_I3 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,8)   //Port = 2, bit = 8,  I3
#define GPIO_I4 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,9)   //Port = 2, bit = 9,  I4
#define GPIO_I5 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,10)  //Port = 2, bit = 10, I5
#define GPIO_I6 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,11)  //Port = 2, bit = 11, I6
#define GPIO_I7 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,12)  //Port = 2, bit = 12, I7

#define GPIO_J0 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,13)  //Port = 2, bit = 13, J0
#define GPIO_J1 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,14)  //Port = 2, bit = 14, J1
#define GPIO_J2 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,15)  //Port = 2, bit = 15, J2
#define GPIO_J3 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,16)  //Port = 2, bit = 16, J3
#define GPIO_J4 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,17)  //Port = 2, bit = 17, J4
#define GPIO_J5 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,18)  //Port = 2, bit = 18, J5
#define GPIO_J6 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,19)  //Port = 2, bit = 19, J6

#define GPIO_K0 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,20)  //Port = 2, bit = 20, K0
#define GPIO_K1 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,21)  //Port = 2, bit = 21, K1
#define GPIO_K2 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,22)  //Port = 2, bit = 22, K2
#define GPIO_K3 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,23)  //Port = 2, bit = 23, K3
#define GPIO_K4 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,24)  //Port = 2, bit = 24, K4
#define GPIO_K5 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,25)  //Port = 2, bit = 25, K5
#define GPIO_K6 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,26)  //Port = 2, bit = 26, K6

#endif // _BITBAND_IO_H_
ARM Information Center
 
Последнее редактирование:

Geniuser

New member
При старте устройства требуется определить состояние кнопки (пина), если это делать в функции main.c, то задержка полсекунды, состояние кнопки уже не актуально. По дизассемблеру определил, что первая редактируемая функция до вызова main.с в SDK это DiagPrintf в файле low_level_io.c , добавил туда в начало функции код с user_init_func

low_level_io.c

Код:
extern void (*user_init_func) (void);

u32
DiagPrintf(
    IN  const char *fmt, ...
)
{
        if (user_init_func != NULL) (*user_init_func)();

    if(disablePrintf == TRUE)    return _TRUE;
 
    (void)VSprintf(0, fmt, ((const int *)&fmt)+1);
    return _TRUE;
}
main.c

Код:
void (*user_init_func)(void) = work_start;
__no_init volatile uint32_t btn;

void work_start(void)
{
    taskDISABLE_INTERRUPTS();
    user_init_func = NULL;
    disablePrintf = TRUE;  
    // Init button   
    gpio_init(&gpio_btn, GPIO_nBTN);
    gpio_dir(&gpio_btn, PIN_INPUT);    // Direction: Input
    gpio_mode(&gpio_btn, PullUp);     // PullUp
    btn = gpio_read(&gpio_btn);
    gpio_deinit(&gpio_btn, GPIO_nBTN);
    disablePrintf = FALSE;
    taskENABLE_INTERRUPTS();
}

void main(void)
{
// Init button
    gpio_init(&gpio_btn, GPIO_nBTN);
    gpio_dir(&gpio_btn, PIN_INPUT);    // Direction: Input
    gpio_mode(&gpio_btn, PullUp);     // PullUp

 
     if (btn == 1)
     {
            // Если кнопка (не) нажата при старте
     }

}

Вместе с Jtag работает, как только запускаю код без отладки - выдает Хард Фолт.

Код:
ROM Version: 0.3

Build ToolChain Version: gcc version 4.8.3 (Realtek ASDK-4.8.3p1 Build 2003)

=========================================================
Check boot type form eFuse
SPI Initial
Image1 length: 0x3a18, Image Addr: 0x10000bc8
Image1 Validate OK, Going jump to Image1
BOOT from Flash:YES
SPI calibration
Find the avaiable window
Baud:2; auto_length:0; Delay start:0; Delay end:63
[SPIF Err]SpicNVMCalStore: The flash memory(@0x9088 = 0x1310002) is not able to
===== Enter Image 1 ====!!
SPI calibration
Find the avaiable window
Baud:1; auto_length:11; Delay start:0; Delay end:63
[SPIF Err]SpicNVMCalStore: The flash memory(@0x90b8 = 0x1311101) is not able to
be write, Erase it first!!
load NEW fw 0
Flash Image2:Addr 0xb000, Len 263860, Load to SRAM 0x10006000
No Image3
Img2 Sign: RTKWin, InfaStart @ 0x10006051
RTL8195A[HAL]: Hard Fault Error!!!!
RTL8195A[HAL]: R0 = 0x0
RTL8195A[HAL]: R1 = 0x0
RTL8195A[HAL]: R2 = 0xe
RTL8195A[HAL]: R3 = 0x10047a60
RTL8195A[HAL]: R12 = 0x1c
RTL8195A[HAL]: LR = 0xd87d
RTL8195A[HAL]: PC = 0xe
RTL8195A[HAL]: PSR = 0x40000200
RTL8195A[HAL]: BFAR = 0x8
RTL8195A[HAL]: CFSR = 0x20000
RTL8195A[HAL]: HFSR = 0x40000000
RTL8195A[HAL]: DFSR = 0x0
RTL8195A[HAL]: AFSR = 0x0
RTL8195A[HAL]: PriMask 0x1
RTL8195A[HAL]: BasePri 0x0
RTL8195A[HAL]: SVC priority: 0x00
RTL8195A[HAL]: PendSVC priority: 0x00
RTL8195A[HAL]: Systick priority: 0x00
Опытным путём обнаружил, что если проинициализировать глобальную переменную, то её значение изменённое до main в work_start не сохраняется, поэтому пришлось делать __no_init btn и повторять gpio_init(&gpio_btn). Ворос как сделать правильно, чтобы SDK не рассыпалось?
 
Последнее редактирование:

pvvx

Активный участник сообщества
Ворос как сделать правильно, чтобы SDK не рассыпалось?
Включить функцию опроса что там вам надо в bootloader. Его исходники даны. Как один из множества возможных вариантов: Вставляете в BootLoader свою функцию, которая определяет и записывает какие-то нужные значения (хоть килобайты) по абсолютному адресу в области данных BootLoader-a до границы __ram_heap1_start__. Описываете эти переменные в *.ld и по загрузке любого выбранного приложения с SDK работаете с ними.
Вариантов ещё много, но всё зависит от того, что вам надо получить, как и для чего...
Кнопки и пины, ответственные за всякие Wake UP из разных режимов sleep имеют свои регистры статусов и событий - флагов и причин просыпания... Часть устройств, ответственных за просыпание из разных режимов sleep имеют и прерывания... как и назначаемые пины просыпания из DeepSleep().
Никто, кроме вас не знает, что вы там пытаетесь определить - может хотите фиксировать причину подачи питания на чип?
С удержанным RESET проц жрет больше чем в DeepSleep() или ожидания активации по уровню на пине... та и в текущих версиях BootLoader грузит разные прошивки на выбор по уровню на пинах...
 
Последнее редактирование:

Geniuser

New member
Здравствуйте,
столкнулся с такой проблемой
в разных местах программы делаю выключение по кнопке (если устройство при этом заряжается, то вместо выключения применяется рестарт. Пробовал 2-мя способами sys_reset() и watchdog, поведение одинаковое - рестарт происходит. Однако в разных местах программы он происходит по-разному:
либо так

Код:
=========================================================

ROM Version: 0.3

Build ToolChain Version: gcc version 4.8.3 (Realtek ASDK-4.8.3p1 Build 2003)

=========================================================
Check boot type form eFuse
SPI Initial
Image1 length: 0x3a18, Image Addr: 0x10000bc8
Image1 Validate OK, Going jump to Image1
BOOT from Flash:YES
===== Enter Image 1 ====

load NEW fw 0
Flash Image2:Addr 0xb000, Len 308036, Load to SRAM 0x10006000
No Image3
Img2 Sign: RTKWin, InfaStart @ 0x10006051
===== Enter Image 2 ====
либо вот так
Код:
=========================================================

ROM Version: 0.3

Build ToolChain Version: gcc version 4.8.3 (Realtek ASDK-4.8.3p1 Build 2003)

=========================================================
Check boot type form eFuse
SPI Initial
Image1 length: 0x3a18, Image Addr: 0x10000bc8
Image1 Validate OK, Going jump to Image1
BOOT from Flash:YES
===== Enter Image 1 ====

load OLD fw 1
Flash Image2:Addr 0x80000, Len 305844, Load to SRAM 0x10006000
No Image3
Img2 Sign: RTKWin, InfaStart @ 0x10006051
===== Enter Image 2 ====
Во втором случае грузится предыдущая версия прошивки OTA.
Раскопал по этому вопросу такую информацию:
First RTL-00 module tests - RTL8710 Community Forum
PINE64 - Firmware Recovery
Прошиваю через JTAG и несколько раз было по OTA.

Там упоминается некая ножка FLASH и механизм отката прошивки. В документации ничего не описано по этой теме. Предполагаю, что столкнулся с этой проблемой. Какая-то ножка при старте заставляет грузится старую прошивку. Как узнать какая ножка? И как механизм работает, как можно отключить, чтобы всегда грузилась новая прошивка?
 

sharikov

Active member
Там упоминается некая ножка FLASH и механизм отката прошивки. В документации ничего не описано по этой теме. Предполагаю, что столкнулся с этой проблемой. Какая-то ножка при старте заставляет грузится старую прошивку. Как узнать какая ножка? И как механизм работает, как можно отключить, чтобы всегда грузилась новая прошивка?
Это уже обсуждалось.
Номера ножек записаны в секторе system data
https://esp8266.ru/forum/threads/rtl871x-flash-memory-map.2117/#post-30627
Какую прошивку грузить выбирается в rtl_boot.c
 

Geniuser

New member
Это уже обсуждалось.
Номера ножек записаны в секторе system data
https://esp8266.ru/forum/threads/rtl871x-flash-memory-map.2117/#post-30627
Какую прошивку грузить выбирается в rtl_boot.c
Огромное спасибо, а не подскажете какие настройки ножек FLASH, отвечающих за загрузку old и new image по умолчанию?
 

Geniuser

New member
Выполнил в коде программы:

Код:
unsigned int tmp = HAL_READ32(SPI_FLASH_BASE, FLASH_SYSTEM_DATA_ADDR + 0x08); // config data + 8
    DiagPrintf("\r\nFLASH_KEY: 0x%08X\r\n", tmp);
Получил значение FLASH_KEY: 0x00000000

Получается по-умолчанию FLASH ножка GA0? Но у меня состояние этой ножки не меняется при перезагрузке, однако грузятся разные прошивки.
Эту ножку я использую как SPI1_MISO, есть подозрение, что если SPI инициализирован, перед рестартом, то грузится одна прошивка, а если не инициализирован (деинициализирован), то другая.
Причем от процедуры рестарта это не зависит (watch_dog, sys_reset, ota_platform_reset). Пока нет ясности в этом вопросе.
 
Сверху Снизу