Страница 10 из 15
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вс дек 13, 2020 03:44:07
VladislavS
[uquote="AVI-crak",url="/forum/viewtopic.php?p=3940800#p3940800"]Это там
https://github.com/AVI-crak/gpio_one
Материалы для создания таблиц не включены в проект, не хватало чтобы меня ещё и за них пинали.[/uquote]Глянул краем глаза. Попинаю.
1. Вот это вот совсем плохо.
Код: Выделить всё
zap_GPIO_TypeDef* GPIOx = (void*)0x40020000 + init.port;
Это магическое число запросто может быть 0x50000000 у некоторых контроллеров. Она же определена в заголовочном файле контроллера, надо пользоваться. Ну и с приведение типов надо что-то делать.
2. Состояние пина в PushPull режиме это тоже часть конфигурации. Почему на него забито? Должно быть три опции: 0, 1 и "не трогать".
3. RM говорит, что lock() это
Код: Выделить всё
GPIOx->LCKR = (1 << 16) | (1 << init.pin);
GPIOx->LCKR = 1 << init.pin;
GPIOx->LCKR = (1 << 16) | (1 << init.pin);
GPIOx->LCKR;
ЗЫ: А с народным f103 что будем делать?
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вс дек 13, 2020 13:55:53
AVI-crak
Reflector писал(а):Вот это вот совсем плохо.
Это плохо споткнулось на stm32l552xx - там вообще всё переделано. Ну даа, нужно подключать внешнее, чтобы работало везде и всегда (кроме F1). Но на данный момент до этого далеко.
Народный f103 оптимизировать нет смысла: это намного сложнее - и практически с нуля, накопилась критическая масса публикаций в инете - которую невозможно пробить. Даже победив дракона - героя никто не заметит, а может даже затопают в суматохе.
Reflector писал(а):Состояние пина в PushPull
Ну дык к это относится к работе выхлопа на верхнем и нижнем транзисторе, но в любом случае это выхлоп. А вот не выхлоп - обозначен для выбора.
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вс дек 13, 2020 15:56:54
VladislavS
Ну не знаю, раз уж взялись за пин, то лучше полностью состояние задать, чем лочить его. И какая может быть трудность у F1 с его 4 битами конфигурации на пин в одном регистре?
Залочить, кстати, если есть список пинов, это одна команда.
Спойлер
Код: Выделить всё
using PINS = PinList<PB4, PB3, PA1, PA4, PA7, PB1, PB8, PB15>;
PINS::lock();
LDR.N R1,??main_0 ;; 0x4800001c
LDR.N R0,??main_0+0x4 ;; 0x10092
STR R0,[R1, #+0]
MOVS R2,#+146
STR R2,[R1, #+0]
STR R0,[R1, #+0]
MOVW R2,#+33050
LDR R0,[R1, #+0]
LDR.N R0,??main_0+0x8 ;; 0x1811a
STR R0,[R1, #+1024]
STR R2,[R1, #+1024]
STR R0,[R1, #+1024]
LDR R0,[R1, #+1024]
Или вот так, сразу три порта лочим, легко и непринуждённо.
Спойлер
Код: Выделить всё
PinList<GpioA<>,GpioB<>,GpioC<>>::lock();
LDR.N R1,??main_0 ;; 0x4800001c
LDR.N R0,??main_0+0x4 ;; 0x1ffff
STR R0,[R1, #+0]
MOVW R2,#+65535
STR R2,[R1, #+0]
STR R0,[R1, #+0]
LDR R3,[R1, #+0]
STR R0,[R1, #+1024]
STR R2,[R1, #+1024]
STR R0,[R1, #+1024]
LDR R3,[R1, #+1024]
STR R0,[R1, #+2048]
STR R2,[R1, #+2048]
STR R0,[R1, #+2048]
LDR R0,[R1, #+2048]
Вот тут цикл просится в оптимизацию 
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Пн дек 14, 2020 10:31:01
AVI-crak
Трудность с F1 в том что кубик не даёт полноценный рапорт, а вводить всё это дело руками - рехнуться можно. (это я про своё решение)
Лок нужен по другим причинам, не связанных с безопасностью. Точнее это даже почти правило, всё сто статично - должно лочится.
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Пн дек 14, 2020 22:21:20
Dimon456
VladislavS, еще вопрос.
И так ваш метод:
Код: Выделить всё
PinList<PC7, PC6, PC5, PC4, PC3, PA0, PA1, PA5> pins1;
PinList<PB1, PB2, PB3, PB4, PB5, PD5> pins2;
Теперь, плиз, в цикле, будем записывать, ни знаю как у вас правильно, но
Код: Выделить всё
a = 0;
b = 0;
while (1)
{
pins1 = a++;
pins2 = b++;
}
При объявлении pins1 и pins2 у вас создается таблица, массив, соответственно будет два массива.
На текущий момент нет способа узнать длину массива, соответственно будет две функции записи.
Покажите получившийся ассемблер?
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Пн дек 14, 2020 22:49:00
Reflector
[uquote="Dimon456",url="/forum/viewtopic.php?p=3941691#p3941691"]При объявлении pins1 и pins2 у вас создается таблица, массив, соответственно будет два массива.[/uquote]
Нет там никаких массивов, они есть у меня, но только для инициализации и как один из вариантов, потому что иногда скорость важнее размера. Для присваивания скорость важнее гораздо чаще, потому обходимся без массивов, хотя добавить можно, даже с автоматической подстановкой более компактного варианта.
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Пн дек 14, 2020 23:03:50
VladislavS
[uquote="Dimon456",url="/forum/viewtopic.php?p=3941691#p3941691"]Теперь, плиз, в цикле,[/uquote]Зачем тут две переменных-счётчика?
[uquote="Dimon456",url="/forum/viewtopic.php?p=3941691#p3941691"]При объявлении pins1 и pins2 у вас создается таблица, массив, соответственно будет два массива.[/uquote]Ничего не создастся. Вообще. Совсем. Только код записи в порты.
[uquote="Dimon456",url="/forum/viewtopic.php?p=3941691#p3941691"]На текущий момент нет способа узнать длину массива, соответственно будет две функции записи.[/uquote]Какого массива? О чём вы?
[uquote="Dimon456",url="/forum/viewtopic.php?p=3941691#p3941691"]Покажите получившийся ассемблер?[/uquote]Завтра, компьютер на работе оставил.
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вт дек 15, 2020 00:12:34
Reflector
[uquote="VladislavS",url="/forum/viewtopic.php?p=3941705#p3941705"]Завтра, компьютер на работе оставил.[/uquote]
Покажу пока как это может быть с массивами и циклами, набросал буквально за 20 мин:
Код: Выделить всё
ldr r5, [pc, #168]
add.w r6, r5, #12
mov r1, r4
mov r0, r5
bl 0x24000214
mov r1, r4
mov r0, r6
adds r4, #1
bl 0x24000214
b.n 0x240015f6
Два массива выглядят так:
Код: Выделить всё
05 01 00 23 24 25 26 27 FF
35 15 14 13 12 11 FF
Ну и сама функция существующая в единственном экземпляре которая получает на вход такой массив и записываемое значение:
Спойлер
Код: Выделить всё
push {r4, r5, lr}
subs r0, #1
mov.w r4, #65536
ldrb.w r3, [r0, #1]!
cmp r3, #255
beq.n 0x24000242
and.w r5, r3, #15
lsrs r3, r3, #4
and.w r2, r1, #1
lsrs r1, r1, #1
lsls r3, r3, #10
orrs r2, r4
add.w r3, r3, #1476395008
lsls r2, r5
add.w r3, r3, #131072
str r2, [r3, #24]
b.n 0x2400021c
pop {r4, r5, pc}
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вт дек 15, 2020 08:58:36
VladislavS
Для F3 оптимизация по скорости
Спойлер
Код: Выделить всё
PinList<PC7, PC6, PC5, PC4, PC3, PA0, PA1, PA5> pins1;
PinList<PB1, PB2, PB3, PB4, PB5, PD5> pins2;
for(auto i=0;;i++)
MOVS R0,#+0
LDR.N R1,??DataTable1_4 ;; 0x48000018
{
// pins1=i;
??main_0:
AND R2,R0,#0xF8
ORR R2,R2,#0xF80000
STR R2,[R1, #+2048]
AND R3,R0,#0x2
LSLS R2,R0,#+5
AND R2,R2,#0x20
ORRS R3,R3,R2
UBFX R4,R0,#+2,#+1
ORRS R3,R4,R3
ORR R3,R3,#0x230000
STR R3,[R1, #+0]
// pins2=i;
ORR R2,R2,#0x200000
AND R3,R0,#0x3E
RBIT R3,R3
LSRS R3,R3,#+25
AND R3,R3,#0x3E
ORR R3,R3,#0x3E0000
STR R3,[R1, #+1024]
STR R2,[R1, #+3072]
//}
ADDS R0,R0,#+1
B.N ??main_0
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вт дек 15, 2020 09:03:45
Dimon456
VladislavS писал(а):Зачем тут две переменных-счётчика?
Я считаю что если одна переменная, то будет оптимизация.
Еще раз, плиз, две переменные в цикле while.
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вт дек 15, 2020 10:37:49
VladislavS
[uquote="Dimon456",url="/forum/viewtopic.php?p=3941792#p3941792"]Я считаю что если одна переменная, то будет оптимизация.[/uquote]Не будет никакой разницы, кроме глупого расхода одного РОН.
[uquote="Dimon456",url="/forum/viewtopic.php?p=3941792#p3941792"]Еще раз, плиз, две переменные в цикле while.[/uquote]
Спойлер
Код: Выделить всё
//auto a=0;
MOVS R0,#+0
//auto b=0;
MOVS R1,#+0
LDR.N R2,??DataTable1_4 ;; 0x48000018
//while(1)
//{
// pins1=a++;
??main_0:
MOV R3,R0
AND R4,R3,#0xF8
ORR R4,R4,#0xF80000
STR R4,[R2, #+2048]
LSLS R5,R3,#+5
AND R5,R5,#0x20
AND R4,R3,#0x2
ORRS R5,R4,R5
UBFX R3,R3,#+2,#+1
ORRS R5,R3,R5
ORR R5,R5,#0x230000
STR R5,[R2, #+0]
// pins2=b++;
MOV R3,R1
AND R4,R3,#0x3E
RBIT R4,R4
LSRS R4,R4,#+25
AND R4,R4,#0x3E
LSLS R3,R3,#+5
ORR R4,R4,#0x3E0000
AND R3,R3,#0x20
STR R4,[R2, #+1024]
ORR R3,R3,#0x200000
ADDS R0,R0,#+1
ADDS R1,R1,#+1
STR R3,[R2, #+3072]
//}
B.N ??main_0
Компилятор тут тупанул - не объединил переменные. Но вина, скорее, программиста.
GCC, кстати, допёр, что надо объединить переменные
Спойлер
Код: Выделить всё
20000410: 4d14 ldr r5, [pc, #80] ; (20000464 <main+0x58>)
20000412: 4c15 ldr r4, [pc, #84] ; (20000468 <main+0x5c>)
20000414: f8df e054 ldr.w lr, [pc, #84] ; 2000046c <main+0x60>
20000418: 2100 movs r1, #0
2000041a: f04f 4c90 mov.w ip, #1207959552 ; 0x48000000
2000041e: 0148 lsls r0, r1, #5
20000420: f000 0020 and.w r0, r0, #32
20000424: f3c1 0280 ubfx r2, r1, #2, #1
20000428: f001 0702 and.w r7, r1, #2
2000042c: f001 033e and.w r3, r1, #62 ; 0x3e
20000430: 4302 orrs r2, r0
20000432: fa93 f3a3 rbit r3, r3
20000436: 0e5b lsrs r3, r3, #25
20000438: f001 06f8 and.w r6, r1, #248 ; 0xf8
2000043c: 433a orrs r2, r7
2000043e: f003 033e and.w r3, r3, #62 ; 0x3e
20000442: f446 0678 orr.w r6, r6, #16252928 ; 0xf80000
20000446: f442 120c orr.w r2, r2, #2293760 ; 0x230000
2000044a: f443 1378 orr.w r3, r3, #4063232 ; 0x3e0000
2000044e: f440 1000 orr.w r0, r0, #2097152 ; 0x200000
20000452: 61ae str r6, [r5, #24]
20000454: 3101 adds r1, #1
20000456: f8cc 2018 str.w r2, [ip, #24]
2000045a: 61a3 str r3, [r4, #24]
2000045c: f8ce 0018 str.w r0, [lr, #24]
20000460: e7dd b.n 2000041e <main+0x12>
20000462: bf00 nop
20000464: 48000800 .word 0x48000800
20000468: 48000400 .word 0x48000400
2000046c: 48000c00 .word 0x48000c00
ARMClang
Спойлер
Код: Выделить всё
0x08000790 4912 LDR r1,[pc,#72] ; @0x080007DC
0x08000792 2000 MOVS r0,#0x00
0x08000794 2200 MOVS r2,#0x00
0x08000798 F00203F8 AND r3,r2,#0xF8
0x0800079C F0020402 AND r4,r2,#0x02
0x080007A0 F5030378 ADD r3,r3,#0xF80000
0x080007A4 F8C13800 STR r3,[r1,#0x800]
0x080007A8 F3C20380 UBFX r3,r2,#2,#1
0x080007AC 4423 ADD r3,r3,r4
0x080007AE F0000420 AND r4,r0,#0x20
0x080007B2 3020 ADDS r0,r0,#0x20
0x080007B4 4423 ADD r3,r3,r4
0x080007B6 F503130C ADD r3,r3,#0x230000
0x080007BA 600B STR r3,[r1,#0x00]
0x080007BC F002033E AND r3,r2,#0x3E
0x080007C0 3201 ADDS r2,r2,#0x01
0x080007C2 FA93F3A3 RBIT r3,r3
0x080007C6 0E5B LSRS r3,r3,#25
0x080007C8 F5031378 ADD r3,r3,#0x3E0000
0x080007CC F8C13400 STR r3,[r1,#0x400]
0x080007D0 F5041300 ADD r3,r4,#0x200000
0x080007D4 F8C13C00 STR r3,[r1,#0xC00]
0x080007D8 E7DE B 0x08000798
0x080007DA BF00 NOP
0x080007DC 0018 DCW 0x0018
0x080007DE 4800 DCW 0x4800
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вт дек 15, 2020 17:26:47
Dimon456
VladislavS писал(а):Компилятор тут тупанул - не объединил переменные. Но вина, скорее, программиста.
Нет, не тупанул, правильно сделал.
К примеру на pins1 весит индикатор какой-то лсд не важно, а на pins2 светодиоды.
Как их можно объединить и для чего?
А что это за строка?
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вт дек 15, 2020 18:11:36
VladislavS
[uquote="Dimon456",url="/forum/viewtopic.php?p=3941999#p3941999"]Нет, не тупанул, правильно сделал.[/uquote]Тупанул ещё как. В pins1 и pins2 всегда записывается одинаковое значение. GCC это смог просчитать и выкинул одну переменную. У GCC, правда, какое-то хроническое неумение объединять доступ со смещением от разных базовых адресов.
[uquote="Dimon456",url="/forum/viewtopic.php?p=3941999#p3941999"]Как их можно объединить и для чего?[/uquote]Ну так же как я в С-коде объединил. Так же как GCC это сделал в результате компиляции. Для оптимизации. Я бы ещё на его месте предупреждение "user fool" выдавал.
[uquote="Dimon456",url="/forum/viewtopic.php?p=3941999#p3941999"]А что это за строка?
[/uquote]Загрузка константы из памяти по адресу ??DataTable1_4. В комментарии компилятор показал что это константа 0x48000018 (скорее всего &GPIOA->BSRR).
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вт дек 15, 2020 18:51:30
Dimon456
VladislavS писал(а):Тупанул ещё как. В pins1 и pins2 всегда записывается одно и то же значение.
Нет, не тупанул.
Цикл while говорит компилятору что pins1 и pins2 будет использоваться многократно, значит нельзя оптимизировать.
А то что записывается одно и то же значение - это чисто случай, надо было а=10 а в=0, были бы разные значения.
А в С-коде тот же GCC используется, а ну да в иаре другой, свой какой-то.
Ну да ладно, что я хотел, то я получил.
С++ конечно красиво, но все создается на этапе компиляции и как выяснилось, плохая возможность отладки.
Что бы, найти ошибку, что то исправить, надо колупать целый класс, и что там в классе написано, да еще и связано с другими.
Увы, примеров и там и тут навалом.
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вт дек 15, 2020 19:10:06
VladislavS
[uquote="Dimon456",url="/forum/viewtopic.php?p=3942042#p3942042"]надо было а=10 а в=0, были бы разные значения.[/uquote]Что значит "были бы"? Если бы у бабушки был хрен... Компилировался конкретный код, в котором вы сами написали a=0 и b=0. Компилятор это не увидел, а значит тупанул.
[uquote="Dimon456",url="/forum/viewtopic.php?p=3942042#p3942042"]С++ конечно красиво, но все создается на этапе компиляции[/uquote]Ну надо же, превратить в недостаток бесспорное достоинство. И, по секрету, чтобы что-то просчитывалось на этапе компиляции надо приложить немалые усилия.
[uquote="Dimon456",url="/forum/viewtopic.php?p=3942042#p3942042"]и как выяснилось, плохая возможность отладки.[/uquote]Кем выяснилось? Когда выяснилось? Много вы С++ кода отладили?
[uquote="Dimon456",url="/forum/viewtopic.php?p=3942042#p3942042"]Что бы, найти ошибку, что то исправить, надо колупать целый класс, и что там в классе написано, да еще и связано с другими.[/uquote]Зачем? Воспринимайте класс как библиотечную функцию. Один раз написал, оттестировал и пользуйся как чёрным ящиком. Чего в него лазить? Вот вы написали код с pins1 и pins2 не зная что внутри и всё правильно сработало. А глупость с а=0 и b=0 без всяких классов сморозили.
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вт дек 15, 2020 19:26:09
Reflector
[uquote="Dimon456",url="/forum/viewtopic.php?p=3942042#p3942042"]С++ конечно красиво, но все создается на этапе компиляции и как выяснилось, плохая возможность отладки.[/uquote]
Показывай реализацию для своих двух списков на С, желательно с инициализацией портов, она ведь тоже нужна, а мы оценим как там обстоят дела с отладкой. Потом поменяй пины на другие и продемонстрируй насколько легко получившийся код использовать повторно

Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вт дек 15, 2020 19:48:40
Dimon456
VladislavS,
Reflector, уважаемые, мне 51 год, скоро 52 будет, на кой х мне это сдалось? Я уже "там" место себе забронировал.
Мне всего раз потребовалось 40 входов и 40 выходов, и то это на 80С31 лет так 30 назад.
Идите учите молодых, ах да забыл, молодые же в ардуино играют.
Если и начинать изучать С++ это надо начинать с буквы А и года 4 зубрить.
А мне уже лень, я в лучше в танки поиграю.
PS:
Reflector, вот вам на С реализация, правда для AVR контроллеров
Спойлер
Код: Выделить всё
typedef struct{
volatile uint8_t * port;
uint8_t or;
} port_pin;
#define FLASH __flash
#define pn(p,b) {&PORT ## p, _BV(b)}
const FLASH port_pin pins[] = {
pn(A,3),
pn(C,5),
pn(B,4),
pn(C,6)
};
const FLASH port_pin pin_ns[] = {
pn(D,1)
};
void port_write (volatile const FLASH port_pin *p, uint8_t a, uint8_t data)
{ uint8_t s=1;
for(uint8_t i=0; i<a; i++, s<<=1){
if (data & s)
*p->port |= p->or;
else
*p->port &= ~(p->or);
p++;
}
}
port_write (pins, sizeof(pins)/sizeof(port_pin), 0b00001101);
port_write (pins, sizeof(pins)/sizeof(port_pin), 0b00000101);
port_write (pins, sizeof(pins)/sizeof(port_pin), 0);
port_write (pin_ns, sizeof(pin_ns)/sizeof(port_pin), 1);
port_write (pin_ns, sizeof(pin_ns)/sizeof(port_pin), 0);
Как хотите так и трясите, я трясти не буду.
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Вт дек 15, 2020 23:55:15
VladislavS
[uquote="Dimon456",url="/forum/viewtopic.php?p=3942080#p3942080"]Идите учите молодых[/uquote]А мы этим и занимаемся. Почему мы должны куда-то уходить? Вам не нужно - проходите мимо.
[uquote="Dimon456",url="/forum/viewtopic.php?p=3942080#p3942080"]вот вам на С реализация,[/uquote]C есть С. Что-то вроде того что
Reflector по приколу с массивами показал. Только у него массивы упакованы лучше и их руками не надо делать. Единственный вопрос вызывает вот это место
Сможет ли компилятор тут sbi поставить или будет неэффективная команда записи в память? Я думаю второе.
[uquote="Dimon456",url="/forum/viewtopic.php?p=3942080#p3942080"]
Код: Выделить всё
port_write (pins, sizeof(pins)/sizeof(port_pin), 0b00001101);
[/uquote]С PinList это бы скомпилировплось в последовательность из пяти команд sbi и сbi. Представляете разницу в скорости для и так небыстрой AVR-ки?
Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Ср дек 16, 2020 03:11:00
Reflector
[uquote="VladislavS",url="/forum/viewtopic.php?p=3942098#p3942098"]C есть С. Что-то вроде того что
Reflector по приколу с массивами показал. Только у него массивы упакованы лучше и их руками не надо делать.[/uquote]
Вчера показал, сегодня уже этот код удалил как не выдерживающий конкуренции, а сам он был простейший и отладка будет соответствующая

Зато аналогичный подход для инициализации наоборот развил, теперь нет функции проверки дубликатов, эта задача легла на функцию инициализации которая и так в цикле читает данные пинов из массива. В сборке без проверок 7-й бит режима отвечает за лок, а для отладочной сборки лочить пины незачем, там этот бит отвечает за проверку дубликатов, плюс FF в конце тоже нет, все массивы стали короче на два байта:
Код: Выделить всё
PinList<PA1, PA6, PA5, PD14, PB9> pins;
pins.init<PinMode::AF_PushPull, AF5>();
PA5::init<PinMode::PullUp>();
GpioB<0xFF00>::init<PinMode::OpenDrain_MediumSpeed_PullUp>();
pins.mode<PinMode::PushPull, PinMode::PullDown, 3, PinMode::Floating>();
pins.modeInline<PinMode::AF_PushPull, AF5>();
Init() - это тот же mode(), но с проверкой дубликатов, если она включена, а modeInline() вместо массива работает напрямую c регистрами. Для этого кода получаем:
Код: Выделить всё
ldr r0, [pc, #704]
bl 0x24000c2c
ldr r0, [pc, #704]
bl 0x24000c2c
ldr r0, [pc, #700]
bl 0x24000c2c
ldr r0, [pc, #700]
bl 0x24000c2c
ldr r1, [pc, #696] ; modeInline() инитит 12 регистров, с учетом RMW - это ~50 инструкций
movw r0, #10248
movw r2, #15372
......
strh r2, [r3, #36]
Также получим два сообщения об ошибках:
Код: Выделить всё
Error: PA5 is Reused!
Error: PB9 is Reused!
Добавлено after 2 hours 57 minutes 46 seconds:
[uquote="Dimon456",url="/forum/viewtopic.php?p=3942080#p3942080"]Если и начинать изучать С++ это надо начинать с буквы А и года 4 зубрить.[/uquote]
Удалил в сишной реализации бесполезный typedef для структуры, заменил все
на
И уже пишешь на C++, для сравнения начать изучать STM32 после AVR так просто не получится

Re: Ассемблер для STM32. Сложно ли, стоит ли пытаться?
Добавлено: Ср дек 16, 2020 15:28:10
Dimon456
VladislavS писал(а):или будет неэффективная команда записи в память? Я думаю второе.
Правильно думаете
Спойлер
На 64 бита, с возможностью выбора 8-16-32-64, в любой последовательности пинов.
Не знаю поддерживает ли GCC uint128_t?Код: Выделить всё
#define k_bit uint64_t//64бита uint32_t-32бита uint16_t-16бита uint8_t-8бита
typedef struct{
volatile uint32_t * port;
k_bit or;
} port_pin;
#define PORTA (GPIOA->ODR)
#define PORTB (GPIOB->ODR)
#define PORTC (GPIOC->ODR)
#define pn(p,b) {&PORT ## p, (1<<b)}
const port_pin pins[] = {
pn(A,3),
pn(A,5),
pn(A,4),
pn(A,1),
pn(A,2),
pn(A,0),
pn(A,7),
pn(A,8),
pn(A,12),
pn(A,13),
pn(A,14),
pn(A,15),
pn(C,4),
pn(C,6),
pn(C,3),
pn(C,5),
pn(C,2),
pn(C,7),
pn(C,8),
pn(C,12),
pn(C,13),
pn(C,14),
pn(B,3),
pn(B,5),
pn(B,4),
pn(B,6),
pn(B,1),
pn(B,2),
pn(B,7),
pn(B,0),
pn(B,8),
pn(B,9),
pn(B,12),
pn(B,13),
pn(B,14)
};
const port_pin pin_ns[] = {
pn(C,1)
};
void port_write (volatile const port_pin *p, uint8_t a, k_bit data)
{ k_bit s=1;
for(uint8_t i=0; i<a; i++, s<<=1){
if (data & s)
*p->port |= p->or;
else
*p->port &= ~(p->or);
p++;
}
}
int main(void)
{
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN;
GPIOA->CRL &= ~GPIO_CRL_CNF;
GPIOA->CRL |= GPIO_CRL_MODE;
GPIOA->CRH &= ~GPIO_CRH_CNF;
GPIOA->CRH |= GPIO_CRH_MODE;
GPIOB->CRL &= ~GPIO_CRL_CNF;
GPIOB->CRL |= GPIO_CRL_MODE;
GPIOB->CRH &= ~GPIO_CRH_CNF;
GPIOB->CRH |= GPIO_CRH_MODE;
GPIOC->CRL &= ~GPIO_CRL_CNF;
GPIOC->CRL |= GPIO_CRL_MODE;
GPIOC->CRH &= ~GPIO_CRH_CNF;
GPIOC->CRH |= GPIO_CRH_MODE;
port_write (pins, sizeof(pins)/sizeof(port_pin), 0b00100001001001000001000010000100100);
port_write (pins, sizeof(pins)/sizeof(port_pin), 0b00100101101001001000001010010100100);
port_write (pins, sizeof(pins)/sizeof(port_pin), 0);
port_write (pin_ns, sizeof(pin_ns)/sizeof(port_pin), 1);
port_write (pin_ns, sizeof(pin_ns)/sizeof(port_pin), 0);
while(1)
{
}
}
да же еще без ошибок собирается.
Честно говоря, до последнего не думал что будет работать.
Пусть это и далеко не эффективный код, но он работает, и прекрасно работает.
На F103Код: Выделить всё
Program Size:
text data bss dec hex filename
1456 0 1024 2480 9b0 port_103.elf
Есть еще один метод, но он посложнее будет.