avr-gcc проблемы при обращении к структуре пинов в цикле

Apr 10, 2023 12:02

Имеем компилятор AVR-GCC в AVR-студии, оптимизация отключена, от слова совсем. Для обращения к группам устройств, разбросанных на разных пинах разных портов, сделал такую структуру.

typedef struct {
uint16_t port;
uint16_t ddr;
uint8_t mask;
} power_control;

Пример, инициализации такой структуры:

#define V5_SIZE 5 ( Read more... )

си, Вопрос, avr, Программирование

Leave a comment

Comments 16

minimumlaw April 10 2023, 09:30:33 UTC
во-первых неплохо бы добавить volatile в структуру, ко всем полям которые по сути адрес. Во вторых а зачем такие пляски с приведением типов: * (uint8_t *) power_5v[i]? что мешает прямо в структуре обьявить его указателем на io?

А в целом, раз уж задаете такие вопросы то неплохо бы вывод промежуточного ассемблера... Глядишь если туда заглянуть, то и спрашивать не придется.

Reply

minimumlaw April 10 2023, 09:42:06 UTC
В целом нужен вывод ассемблера. Или в настройках студии сожранять промежуточное, или загрузить в симуляторе и посмотреть в дизассемблере. В целом, пока сомнения вызывает именно шаманство с приведением типов * (uint8_t *) . Почему-то хочется как минимум сделать * (volatile uint8_t *) ... Хотя на -Onone это особенно влиять не должно... Но надо смотреть на промежуточный ассемблер... Ответы там....

Reply

dlinyj April 10 2023, 09:48:41 UTC

Поясните, чем поможет volatile? У вас явно нет понимания ключевого слово volatile и где его применять. Поэтому, часто его пихают туда, где оно совсем не нужно. Обратите внимание на структуру:

const power_control PROGMEM power_5v [V5_SIZE]

А тут мы просто получаем адрес порта. И я буду узнать вашу версию, для чего там слово volatile и на что оно повлияет?

Reply

nicka_startcev April 10 2023, 10:04:51 UTC
>Поясните, чем поможет volatile?

код без побочных эффектов компилятор имеет право выкинуть. ну и про насильную перетипизацию уже сказали - лучше оставить как есть, то есть, PORT и DDR в структуре иметь тех же типов что и в родном заголовке ио_что-то-там.аш

Reply


bigmaxx April 10 2023, 16:54:22 UTC

Может, глупость скажу, но система команд AVR вообще поддерживает адресацию ввода/вывода по вычисляемому/загружаемому адресу? UPD: глянул: поддерживает, если работать с ними как с SRAM, но физические адреса в адресном пространстве SRAM отличаются от адресов IO. Кстати, тут может быть некая загвоздка.

Reply


aleonty April 10 2023, 18:16:23 UTC
Смотрите, это всё макросы и они разворачиваются на этапе компиляции. Например, макрос DDRB разворачивается в итоге (глянул в первом попавшемся своем проекте для avr tiny) в:
#define DDRB _SFR_IO8(0x01)
#define _SFR_IO8(io_addr) _MMIO_BYTE((io_addr) + __SFR_OFFSET)
#define __SFR_OFFSET 0x00
#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))

то есть получаем код инициализации структуры как:
&(*(volatile uint8_t *)(0x01))
то есть значение 0x01 преобразуется в указатель на байт в пространстве на которое отображены регистры, указатель разыменовывается и получаем значение конкретного регистра (0x01). Затем это значение сохраняется в оперативке/стеке (чтобы можно было взять его адрес) и берётся адрес этого значения, которое помещается в член структуры. Очевидно, это не то, что вы хотели.

Reply


Leave a comment

Up