переопределить pinMode, digitalWrite и digitalRead

linker io-expander

Я использую ESP32 Arduino Framework, и у меня есть Расширители GPIO, подключенные через I²C. Они работают нормально, и теперь я хочу сопоставить с ними некоторые неиспользуемые номера контактов, чтобы я мог использовать свои собственные номера контактов в pinMode, digitalRead и digitalWrite. .

К счастью, ядро Arduino слабо связывает эти функции. .

extern void pinMode(uint8_t pin, uint8_t mode) __attribute__ ((weak, alias("__pinMode")));

Я определил свои собственные функции следующим образом:

void pinMode(uint8_t pin, uint8_t mode) {
    if(pin<0x80)
        // вызов обычного обработчика
    else
        // связь с расширителем GPIO через I²C
}

К сожалению, вызов любой из функций не приведет к тому, что компоновщик выберет мою реализацию, но компоновщик выберет реализацию по умолчанию.

Есть идеи, как переопределить слабо связанные pinMode, digitalWrite и digitalRead?

, 👍3

Обсуждение

использовать другой тип параметра. некоторые struct MyPin {int pin;} создают константы, такие как MP0, MP1,.., @Juraj

Раньше он использовал перегрузку, и он работает для моего пользовательского кода. Однако я хочу, чтобы все сторонние библиотеки и ядро Arduino вызывали мои функции. Например, когда библиотека отображения вызывает digitalWrite на некоторых контактах, я хочу, чтобы это работало, даже если этот GPIO находится на моем расширителе GPIO. Перегрузка потребовала бы от меня перезаписи ядра Arduino и сторонних библиотек, чтобы вместо этого использовать мою функцию. Я хочу избежать этого., @Ilka

в ядре очень мало применений этих функций (аналоговая запись, тон, сдвиг). с какими библиотеками вы хотите использовать io Expander?, @Juraj

Например, в [MD_AD9833](https://registry.platformio.org/libraries/majicdesigns/MD_AD9833). К моему проекту будет подключено множество периферийных устройств, поэтому мне придется разветвлять множество разных библиотек. Это было бы нежизнеспособно..., @Ilka

эта библиотека использует SPI. вам нужно запустить вывод CS через расширитель ввода-вывода? большинство библиотек используют SPI, I2C, PWM или прямые манипуляции с регистрами, @Juraj

Вы совершенно правы. Мне нужно запустить вывод CS через расширитель SPI. На самом деле, мой проект имеет пять разных сигналов CS, подключенных к расширителям ввода-вывода в дополнение к родным GPIO ESP32. Другие GPIO на расширителях используются для реле и полевых МОП-транзисторов, поэтому я мог бы обратиться к ним с перегруженной функцией, как вы предложили. Но пять контактов CS адресуются некоторыми сторонними библиотеками, использующими встроенный digitalWrite., @Ilka


1 ответ


Лучший ответ:

3

Я обнаружил проблему: я запустил platformio run --target clean вместо platformio run --target cleanall. Кажется, что только последняя команда очищает все артефакты сборки. В следующий раз, когда я скомпилировал и загрузил, все заработало, как и ожидалось.

Еще одна проблема возникает только с библиотеками Adafruit: некоторые библиотеки используют не uint8_t для портов, а int8_t, и они выполняют такие проверки, как

if(pin_number >=0)  {
    // код, который работает только с номерами выводов от 0x01 до 0x80
}

В качестве примера возьмем библиотеку Adafruit GFX. В качестве обходного пути я сопоставлю свои порты расширения GPIO с 0x40, 0x41, ...

,