Еще одна обертка над GPIO

Расшевелю блог такой многократно жеваной темой как настройка GPIO на примере STM32. Посмотрел разные варианты макросов и не впечатлился, написал свое. Не буду расходовать зря слова, когда проще показать код и результаты компиляции.

Решил втащить побольше информации в описание пинов, может пригодиться при настройке каналов АЦП например. Причины почему получилось именно так, язык только C, и требование разделения HAL от прикладного кода.

#define XGPIO_DEF(PORT,N,CH)		(((PORT) - 'A') << 4 | ((N) & 0xF) | ((CH) & 0x1F) << 8)

#define XGPIO_GET_PORT(XGPIO)		(((XGPIO) >> 4) & 0xF)
#define XGPIO_GET_N(XGPIO)		((XGPIO) & 0xF)
#define XGPIO_GET_CH(XGPIO)		(((XGPIO) >> 8 & 0x1F)

#define GPIO_BOOST_CONVERTER		XGPIO_DEF('B', 2, -1)
#define GPIO_LED			XGPIO_DEF('B', 5, -1)
#define GPIO_HALL_A			XGPIO_DEF('C', 6, -1)
#define GPIO_HALL_B			XGPIO_DEF('C', 7, -1)
#define GPIO_HALL_C			XGPIO_DEF('C', 8, -1)

void GPIO_set_mode_INPUT(int xGPIO);
void GPIO_set_mode_OUTPUT(int xGPIO);
void GPIO_set_mode_ANALOG(int xGPIO);
void GPIO_set_HIGH(int xGPIO);
void GPIO_set_LOW(int xGPIO);
int GPIO_get_VALUE(int xGPIO);


Внутри вот так.

#define XGPIO_DECODE(xGPIO)	\
	GPIO_TypeDef	*GPIO = (GPIO_TypeDef *) (GPIOA_BASE + 0x0400 * XGPIO_GET_PORT(xGPIO)); \
	int		N = XGPIO_GET_N(xGPIO);

void GPIO_set_mode_OUTPUT(int xGPIO)
{
	XGPIO_DECODE(xGPIO);

	MODIFY_REG(GPIO->MODER, 3UL << (N * 2), 1UL << (N * 2));
}

void GPIO_set_HIGH(int xGPIO)
{
	XGPIO_DECODE(xGPIO);

	GPIO->BSRRL = (1UL << N);
}



Пример использования. Можно передавать дескрипторы пинов как int переменные.

int main()
{
	int	gpio_boost = GPIO_BOOST_CONVERTER;

	GPIO_set_mode_OUTPUT(gpio_boost);
	GPIO_set_HIGH(gpio_boost);

	return 0;
}


А вот что получается при компиляции gcc -O3.

08000024 <GPIO_set_mode_OUTPUT>:
 8000024:       f3c0 1303       ubfx    r3, r0, #4, #4
 8000028:       029b            lsls    r3, r3, #10
 800002a:       f103 4380       add.w   r3, r3, #1073741824     ; 0x40000000
 800002e:       f503 3300       add.w   r3, r3, #131072 ; 0x20000
 8000032:       f000 000f       and.w   r0, r0, #15
 8000036:       b410            push    {r4}
 8000038:       0040            lsls    r0, r0, #1
 800003a:       681a            ldr     r2, [r3, #0]
 800003c:       2403            movs    r4, #3
 800003e:       4084            lsls    r4, r0
 8000040:       2101            movs    r1, #1
 8000042:       ea22 0204       bic.w   r2, r2, r4
 8000046:       fa01 f000       lsl.w   r0, r1, r0
 800004a:       4310            orrs    r0, r2
 800004c:       6018            str     r0, [r3, #0]
 800004e:       f85d 4b04       ldr.w   r4, [sp], #4
 8000052:       4770            bx      lr

08000078 <GPIO_set_HIGH>:
 8000078:       f3c0 1303       ubfx    r3, r0, #4, #4
 800007c:       029b            lsls    r3, r3, #10
 800007e:       f000 020f       and.w   r2, r0, #15
 8000082:       f103 4380       add.w   r3, r3, #1073741824     ; 0x40000000
 8000086:       2001            movs    r0, #1
 8000088:       f503 3300       add.w   r3, r3, #131072 ; 0x20000
 800008c:       4090            lsls    r0, r2
 800008e:       b280            uxth    r0, r0
 8000090:       8318            strh    r0, [r3, #24]
 8000092:       4770            bx      lr

080000d0 <main>:
 80000d0:       b508            push    {r3, lr}
 80000d2:       f641 7012       movw    r0, #7954       ; 0x1f12
 80000d6:       f7ff ffa5       bl      8000024 <GPIO_set_mode_OUTPUT>
 80000da:       f641 7012       movw    r0, #7954       ; 0x1f12
 80000de:       f7ff ffcb       bl      8000078 <GPIO_set_HIGH>
 80000e2:       2000            movs    r0, #0
 80000e4:       bd08            pop     {r3, pc}
 80000e6:       bf00            nop


А теперь gcc -O3 -flto.

08000000 <main>:
 8000000:       4a05            ldr     r2, [pc, #20]   ; (8000018 <main+0x18>)
 8000002:       6813            ldr     r3, [r2, #0]
 8000004:       f023 0330       bic.w   r3, r3, #48     ; 0x30
 8000008:       f043 0310       orr.w   r3, r3, #16
 800000c:       2104            movs    r1, #4
 800000e:       6013            str     r3, [r2, #0]
 8000010:       2000            movs    r0, #0
 8000012:       8311            strh    r1, [r2, #24]
 8000014:       4770            bx      lr
 8000016:       bf00            nop
 8000018:       40020400        andmi   r0, r2, r0, lsl #8


К скорости ногодрыга у меня требований нет, но получилось что оптимизируется оно до уровня прямой записи в регистры.
  • +2
  • 04 апреля 2018, 20:52
  • amaora

Комментарии (31)

RSS свернуть / развернуть
язык только C
С чем связано такое требования? Для ARM проще найти компилятор с поддержкой плюсов, чем без оной…
0
  • avatar
  • Vga
  • 05 апреля 2018, 19:07
Боязнь увязнуть в бесконечном редизайне кода, который я и на C слишком часто делаю, а ++ даст еще больше возможностей для этого.
0
Мне кажется, язык на это не сильно повлияет) Ну разве что «а теперь пора переписать все это на плюсы!».
0
Написать на плюсах и красиво, так что бы самому нравилось. На этом переделки закончатся.
0
На этом переделки закончатся.
«Если ваш вчерашний код не вызывает желания переписать его — значит вы перестали развиваться как программист» :)
0
Я не согласен. В некоторых (чаще относительно небольших) проектах удается дойти до стадии, когда код начинает нравится.
0
Возможно, ты просто перестал развиваться?
0
У всякого кода есть предел, проще которого написать имеющимися срествами невозможно. Такой код не имеет смысла переделывать пока нет другого архитектурного решения. А после появления такого другого решения, код, зачастую, проще переписать с нуля. По мере накопления опыта новые архитектурные решения появляются все реже и реже. Но это не значит, что развитие остановилось, просто применимого к конкретной задаче нового становится все меньше и меньше.

На мой взгляд, развитие проявляется в готовности браться за более сложные задачи. Вот это действительно никогда не заканчивается. А желание изменить что-то в существующем коде часто представляет собой замаскированное желание попробовать на практике свежеузнанные новинки, даже если код от этого, по факту, не станет лучше.
0
Если у вас есть время копаться во вчерашнем коде — вам уж точно больше нечем заняться. Лучше начать новый поект и усилия переложить на него. К старому коду возвращаются в случае фиксов выявленных в процессе эксплуатации багов или появления новых идей его развития.
Мне это напомнило историю из 80-х. Работал я тогда на совковом заводе электронщиком. И там же работал один мужичек, назовем его Петрович. Напомню, что в те времена жизнь была скучна и однообразна, поэтому большинство народа после работы тупо бухало. Были и исключения (очень маленький процент) — те у кого было хобби. Петрович был радиолюбителем — коротковолновиком. Петрович все время переделывал свой трансивер. То есть полностью. Как только он был собран и отлажен, Петрович его полностью разбирал и начинал процесс с начала. В эфир со своего детища он так и не вышел.
Не будьте как Петрович — не зацикливайтесь. Двигайтесь вперед.
0
Это называется перфекционизм :)
0
Ты неправильно интерпретируешь фразу. Она не о том, что старый код надо переписать. Она о том, что если старый код не вызывает отвращения — то ты за прошедшее время ничему не научился.
0
Почему он должен вызывать отвращение? Второй раз так бы не написал — да. Написал бы сейчас иначе — тоже да. Но почему именно отвращение? В конце-концов, это обратная связь, которая показывает тебе насколько изменился твой уровень. С какого перепугу вместо положительных эмоций (удовлетворение) нужно испытывать отрицательные (отвращение)? Только потому, что кто-то для красного словца это так сформулировал?
0
То есть кроме формулировки тебе придраться не к чему? ОК, она неудачная, ты прав. Более корректная — «если старый код не выглядит плохим».
0
P.S. Я и сам видел таких Петровичей. Но конкретно в этом случае — может, его вообще не интересовал эфир, а весь интерес был именно в разработке трансивера?
0
Думаю тут скорее психологический барьер или какой-то страх. А вдруг мне уже не к чему стремиться?
Что же касается кода — то он мне бывает еще во время написания противен. но компилятор мне жалуется ;) А перфекционизм — это скорее недостаток, чем достоинство. Поиски идеала — пустая трата времени. Надеюсь все понимают, что я говорю о коде а не об алгоритме и что код и алгоритм — не одно и то же.
0
На плюсах это было бы красивее и удобнее.
0
  • avatar
  • evsi
  • 05 апреля 2018, 20:43
И ЧТО? Очередные изыскания недоучившегося в свое время, но доучивающегося ЗДЕСЯ (т.е. дома в деревне) доктора_електронно_кодерных_наук? А чем это отличается (если и отличается) от поделий других (тема не раскрыта)? Или смысл в том, что, компиляторы (РОБОТЫ, сделанные О-О-ОЧЕНЬ ВУМНЫМИ людьми) сожрали обычных говнокодеров (gcc -O3 -flto)?
-2
Костыли и велосипеды, как же без этого,
суть человеческой натуры, молодой натуры!
:)
-1
-1
А вы кто такой?
-1
чёт мало минусов,
:)
бандеро-бараны уже в ящик сыграли шоль?
-3
бандеро-бараны уже в ящик сыграли шоль?
Вы неуклюже пытаетесь сказать, что вы с того света пишете?
-1
упс, великое открытие,
:)
младшие братья замутили майдаун и оказалось,
что кастрюлям нечего было положить в кастрюли
и они одели их на голову от безысходности!
-4
Забавно смотреть, как вы пытаетесь начать хохлосрач. Вбросы у вас и раньше не грешили оригинальностью, а сейчас и совсем как-то слабенько. Это у вас, случайно, не от ваших тамошних продуктов? Говорят качество — дрянь полная.
-3
Конфеты хорошие с липецкого комбината.
-1
На месте Парашенко надо было бы выпустить липецкие конфеты с названием «Крым наш» с жевто-блакитным фантиком!
:)
-3
Это который год как закрыт?
-2
Глядя на порошенко, я бы не был так уверен.
-2
Глядя на порошенко, я бы не был так уверен.
Ну да, ну да. Закрыл пуйло, а глядите вы на Поршенко и он у вас вызывает сомнения. Как знакомо…
-2
Парашенко в шоколаде, богатеет так же быстро как Мавроди в своё время,
жрёт в три горла и начихать ему, что на Украине устроен очередной голодомор пенсионерам.
-1
Это у вас в ольгино такие методички сейчас? Откуда тебе знать как себя чувствуют пенсионеры в Украине?
P.S. Поздравляю, на России таки забанили Телеграм.
-1
Автор топика запретил добавлять комментарии