Код: Выделить всё
static inline void lighton(void)
{
PORTB |= (1 << PB3);
DDRB |= (1 << DDRB3);
}
Код: Выделить всё
static inline void lighton(void)
{
PORTB |= (1 << PB3);
DDRB |= (1 << DDRB3);
}
Если не использовать опции оптимизации, то точно не будет. А если делать -Os - что для avr-gcc strongly recommended - то всё норм.А inline - не панацея. Это всего-лишь хинт компилятору. Не факт, что будет инлайн.
Ну, это прискорбно. Но это не значит, что на нормальных платформах теперь тоже стоит себя ограничивать в удобных инструментахЛадно еще с avr-gcc, на другой платформе, например PIC с XC8 там вообще всё плохо с этим.
Так и static inline тоже - никаких проблем. Так и используют. Вот, хотя бы, list.h - https://github.com/torvalds/linux/blob/ ... nux/list.h .Плюс макрос можно закинуть в .h и вызывать из разных .c.
Есть только в gcc. Страдает переносимость кода. Хотя если она не нужна, можно и inline конечно. Если точно уверены в своём компиляторе. Ядру Linux-то пофиг на накладные расходы, если они возникнут. А для МК это критично.__attribute__((always_inline)).
А вот как раз таки наоборот. При -Os делается rcall:А если делать -Os - что для avr-gcc strongly recommended - то всё норм.
Код: Выделить всё
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/cpufunc.h>
#include <stdbool.h>
static inline void lighton(void) {
PORTB |= (1 << PB3);
DDRB |= (1 << PB3);
}
static inline void lightoff(void) {
PORTB &= ~(1 << PB3);
DDRB &= ~(1 << PB3);
}
ISR(INT0_vect) {
lighton();
}
int main() {
lightoff();
_NOP();
lighton();
while(true);
}
Код: Выделить всё
...
00000038 <lighton>:
38: c3 9a sbi 0x18, 3 ; 24
3a: bb 9a sbi 0x17, 3 ; 23
3c: 08 95 ret
0000003e <__vector_1>:
3e: 1f 92 push r1
40: 0f 92 push r0
42: 0f b6 in r0, 0x3f ; 63
44: 0f 92 push r0
46: 11 24 eor r1, r1
48: 2f 93 push r18
4a: 3f 93 push r19
4c: 4f 93 push r20
4e: 5f 93 push r21
50: 6f 93 push r22
52: 7f 93 push r23
54: 8f 93 push r24
56: 9f 93 push r25
58: af 93 push r26
5a: bf 93 push r27
5c: ef 93 push r30
5e: ff 93 push r31
60: eb df rcall .-42 ; 0x38 <lighton>
62: ff 91 pop r31
64: ef 91 pop r30
66: bf 91 pop r27
68: af 91 pop r26
6a: 9f 91 pop r25
6c: 8f 91 pop r24
6e: 7f 91 pop r23
70: 6f 91 pop r22
72: 5f 91 pop r21
74: 4f 91 pop r20
76: 3f 91 pop r19
78: 2f 91 pop r18
7a: 0f 90 pop r0
7c: 0f be out 0x3f, r0 ; 63
7e: 0f 90 pop r0
80: 1f 90 pop r1
82: 18 95 reti
00000084 <main>:
84: c3 98 cbi 0x18, 3 ; 24
86: bb 98 cbi 0x17, 3 ; 23
88: 00 00 nop
8a: d6 df rcall .-84 ; 0x38 <lighton>
8c: ff cf rjmp .-2 ; 0x8c <main+0x8>
...
Код: Выделить всё
00000044 <__vector_1>:
44: 1f 92 push r1
46: 0f 92 push r0
48: 0f b6 in r0, 0x3f ; 63
4a: 0f 92 push r0
4c: 11 24 eor r1, r1
4e: c3 9a sbi 0x18, 3 ; 24
50: bb 9a sbi 0x17, 3 ; 23
52: 0f 90 pop r0
54: 0f be out 0x3f, r0 ; 63
56: 0f 90 pop r0
58: 1f 90 pop r1
5a: 18 95 reti
Есть только в gcc. Страдает переносимость кода. Хотя если она не нужна, можно и inline конечно. Если точно уверены в своём компиляторе. Ядру Linux-то пофиг на накладные расходы, если они возникнут. А для МК это критично.[/uquote]__attribute__((always_inline)).
Если это делается двумя выражениями, как выше, плюс do/while(0), то уж лучше функция. Хотя, это субъективно. Каждый сам определяет, когда нужно остановитьсяНо для записи битика в пару регистров честно не вижу смысла городить функцию.
Для обучения нормДиод ставить куда больший изврат )))
rcall делается с ISR. Если эту конструкцию убрать, то с inline всё норм.А вот как раз таки наоборот. При -Os делается rcall:А если делать -Os - что для avr-gcc strongly recommended - то всё норм.
Мне как-то несколько байт не хватало ) Пришлось пожертвовать читаемостью кода и все функции запихнуть одной простыней. Зато влезло в текущий МК, который был под рукой и который не надо было покупать. Это когда речь о личных поделках.Если для проекта вызов функции критичен, то надо либо в сторону ассемблера смотреть, либо в сторону контроллера помощнее.
Именно. На самом деле не критично в большинстве случаев. Мне просто максос с do {} while(0) никак читаемость кода не ухудшает, я к ним привык, они много кем используются. Но случаи бывают разные. )Хотя, это субъективно. Каждый сам определяет, когда нужно остановиться.
Код: Выделить всё
ISR(INT0_vect) {
lighton();
}
ПрикольноМне как-то несколько байт не хватало ) Пришлось пожертвовать читаемостью кода и все функции запихнуть одной простыней. Зато влезло в текущий МК, который был под рукой и который не надо было покупать. Это когда речь о личных поделках.
Ну, смотря какое серийное производство. Если это промышленное оборудование какое-то, то цена контроллера потеряется среди прочего оборудования, которое он будет мониторить/управлять. И в этом случае для стабильности и надёжности лучше выбрать что-то помощнее и с большей памятью, что бы не извращаться с исходным кодом, ибо больше хаков - больше потенциальных ошибок.А в серийных ус-ах порой разница в цене за счет серийности может встать в существенную сумму. Всякое бывает.
Не хочет )То вызовов функции не будет в main. Она будет инлайниться.
Код: Выделить всё
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/cpufunc.h>
#include <stdbool.h>
static inline void lighton(void) {
PORTB |= (1 << PB3);
DDRB |= (1 << PB3);
}
static inline void lightoff(void) {
PORTB &= ~(1 << PB3);
DDRB &= ~(1 << PB3);
}
void fn() {
lighton();
}
int main() {
fn();
_NOP();
lightoff();
_NOP();
lighton();
while(true);
}
Код: Выделить всё
...
00000038 <lighton>:
38: c3 9a sbi 0x18, 3 ; 24
3a: bb 9a sbi 0x17, 3 ; 23
3c: 08 95 ret
0000003e <fn>:
3e: fc cf rjmp .-8 ; 0x38 <lighton>
00000040 <main>:
40: fb df rcall .-10 ; 0x38 <lighton>
42: 00 00 nop
44: c3 98 cbi 0x18, 3 ; 24
46: bb 98 cbi 0x17, 3 ; 23
48: 00 00 nop
4a: f6 df rcall .-20 ; 0x38 <lighton>
4c: ff cf rjmp .-2 ; 0x4c <main+0xc>
...
Не хочет )[/uquote]То вызовов функции не будет в main. Она будет инлайниться.
Код: Выделить всё
static inline void lighton(void) {
PORTB |= (1 << PB3);
DDRB |= (1 << PB3);
}
static inline void lightoff(void) {
PORTB &= ~(1 << PB3);
DDRB &= ~(1 << PB3);
}
void fn(void) {
lighton();
}
ISR(INT0_vect) {
lighton();
}
int main(void) {
fn();
_NOP();
lightoff();
_NOP();
lighton();
while(true);
}Код: Выделить всё
00000080 <lighton>:
80: 2b 9a sbi 0x05, 3 ; 5
82: 23 9a sbi 0x04, 3 ; 4
84: 08 95 ret
00000086 <fn>:
86: 0c 94 40 00 jmp 0x80 ; 0x80 <lighton>
0000008a <__vector_1>:
8a: 1f 92 push r1
8c: 0f 92 push r0
8e: 0f b6 in r0, 0x3f ; 63
90: 0f 92 push r0
92: 11 24 eor r1, r1
94: 2f 93 push r18
96: 3f 93 push r19
98: 4f 93 push r20
9a: 5f 93 push r21
9c: 6f 93 push r22
9e: 7f 93 push r23
a0: 8f 93 push r24
a2: 9f 93 push r25
a4: af 93 push r26
a6: bf 93 push r27
a8: ef 93 push r30
aa: ff 93 push r31
ac: 0e 94 40 00 call 0x80 ; 0x80 <lighton>
b0: ff 91 pop r31
b2: ef 91 pop r30
b4: bf 91 pop r27
b6: af 91 pop r26
b8: 9f 91 pop r25
ba: 8f 91 pop r24
bc: 7f 91 pop r23
be: 6f 91 pop r22
c0: 5f 91 pop r21
c2: 4f 91 pop r20
c4: 3f 91 pop r19
c6: 2f 91 pop r18
c8: 0f 90 pop r0
ca: 0f be out 0x3f, r0 ; 63
cc: 0f 90 pop r0
ce: 1f 90 pop r1
d0: 18 95 reti
000000d2 <main>:
d2: 0e 94 40 00 call 0x80 ; 0x80 <lighton>
d6: 00 00 nop
d8: 2b 98 cbi 0x05, 3 ; 5
da: 23 98 cbi 0x04, 3 ; 4
dc: 00 00 nop
de: 0e 94 40 00 call 0x80 ; 0x80 <lighton>
e2: ff cf rjmp .-2 ; 0xe2 <main+0x10>Код: Выделить всё
static void lighton(void) {
PORTB |= (1 << PB3);
DDRB |= (1 << PB3);
}
static void lightoff(void) {
PORTB &= ~(1 << PB3);
DDRB &= ~(1 << PB3);
}
void fn(void) {
lighton();
}
ISR(INT0_vect) {
lighton();
}
int main(void) {
fn();
_NOP();
lightoff();
_NOP();
lighton();
while(true);
}Код: Выделить всё
00000080 <lighton>:
80: 2b 9a sbi 0x05, 3 ; 5
82: 23 9a sbi 0x04, 3 ; 4
84: 08 95 ret
00000086 <fn>:
86: 0c 94 40 00 jmp 0x80 ; 0x80 <lighton>
0000008a <__vector_1>:
8a: 1f 92 push r1
8c: 0f 92 push r0
8e: 0f b6 in r0, 0x3f ; 63
90: 0f 92 push r0
92: 11 24 eor r1, r1
94: 2f 93 push r18
96: 3f 93 push r19
98: 4f 93 push r20
9a: 5f 93 push r21
9c: 6f 93 push r22
9e: 7f 93 push r23
a0: 8f 93 push r24
a2: 9f 93 push r25
a4: af 93 push r26
a6: bf 93 push r27
a8: ef 93 push r30
aa: ff 93 push r31
ac: 0e 94 40 00 call 0x80 ; 0x80 <lighton>
b0: ff 91 pop r31
b2: ef 91 pop r30
b4: bf 91 pop r27
b6: af 91 pop r26
b8: 9f 91 pop r25
ba: 8f 91 pop r24
bc: 7f 91 pop r23
be: 6f 91 pop r22
c0: 5f 91 pop r21
c2: 4f 91 pop r20
c4: 3f 91 pop r19
c6: 2f 91 pop r18
c8: 0f 90 pop r0
ca: 0f be out 0x3f, r0 ; 63
cc: 0f 90 pop r0
ce: 1f 90 pop r1
d0: 18 95 reti
000000d2 <main>:
d2: 0e 94 40 00 call 0x80 ; 0x80 <lighton>
d6: 00 00 nop
d8: 2b 98 cbi 0x05, 3 ; 5
da: 23 98 cbi 0x04, 3 ; 4
dc: 00 00 nop
de: 0e 94 40 00 call 0x80 ; 0x80 <lighton>
e2: ff cf rjmp .-2 ; 0xe2 <main+0x10>
Код: Выделить всё
#define INLINE static inline __attribute__((__always_inline__))
INLINE void lighton(void) {
PORTB |= (1 << PB3);
DDRB |= (1 << PB3);
}
INLINE void lightoff(void) {
PORTB &= ~(1 << PB3);
DDRB &= ~(1 << PB3);
}
void fn(void) {
lighton();
}
ISR(INT0_vect) {
lighton();
}
int main(void) {
fn();
_NOP();
lightoff();
_NOP();
lighton();
while(true);
}Код: Выделить всё
00000080 <fn>:
80: 2b 9a sbi 0x05, 3 ; 5
82: 23 9a sbi 0x04, 3 ; 4
84: 08 95 ret
00000086 <__vector_1>:
86: 2b 9a sbi 0x05, 3 ; 5
88: 23 9a sbi 0x04, 3 ; 4
8a: 18 95 reti
0000008c <main>:
8c: 0e 94 40 00 call 0x80 ; 0x80 <fn>
90: 00 00 nop
92: 2b 98 cbi 0x05, 3 ; 5
94: 23 98 cbi 0x04, 3 ; 4
96: 00 00 nop
98: 2b 9a sbi 0x05, 3 ; 5
9a: 23 9a sbi 0x04, 3 ; 4
9c: ff cf rjmp .-2 ; 0x9c <main+0x10>