библиотека оптимизируется под архитектуру, в лучшем случае - под семейство. Дальше уже дело конечного программиста сказать компилятору, чего там его конкретная железка не умеет или чего программист сам не хочет. У gcc, например, есть флаг mno-unaligned-access.
Вопросы по С/С++ (СИ)
[uquote="VladislavS",url="/forum/viewtopic.php?p=3833099#p3833099"]Библиотека оптимизируется под конкретную железку[/uquote]нэ савсэм.
библиотека оптимизируется под архитектуру, в лучшем случае - под семейство. Дальше уже дело конечного программиста сказать компилятору, чего там его конкретная железка не умеет или чего программист сам не хочет. У gcc, например, есть флаг mno-unaligned-access.
библиотека оптимизируется под архитектуру, в лучшем случае - под семейство. Дальше уже дело конечного программиста сказать компилятору, чего там его конкретная железка не умеет или чего программист сам не хочет. У gcc, например, есть флаг mno-unaligned-access.
- Реклама
- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
[uquote="arkhnchul",url="/forum/viewtopic.php?p=3833449#p3833449"]библиотека оптимизируется под архитектуру,[/uquote]Это я и имел в виду.
[uquote="arkhnchul",url="/forum/viewtopic.php?p=3833449#p3833449"]в лучшем случае - под семейство.[/uquote]В случае ARM - под ядро. Как на уровне компилятора, так и на уровне исходного кода библиотек. При такой конкуренции среди компиляторов под ARM иметь неоптимизированные библиотеки непозволительная роскошь.
[uquote="arkhnchul",url="/forum/viewtopic.php?p=3833449#p3833449"]У gcc, например, есть флаг mno-unaligned-access.[/uquote]Это не панацея. C/C++ так устроен, что можно заставить компилятор сделать невыровненный доступ. Это грубый косяк, но он всё ещё в библиотеках встречается. Ответственный разработчик встретив такое отправит багрепорт автору.
Это мы говорили про тулчейн. Он должен всё об архитектуре чипа знать. Вон, чуть выше код под AVR былУбери одну __flash и код кардинально меняется.
[uquote="arkhnchul",url="/forum/viewtopic.php?p=3833449#p3833449"]в лучшем случае - под семейство.[/uquote]В случае ARM - под ядро. Как на уровне компилятора, так и на уровне исходного кода библиотек. При такой конкуренции среди компиляторов под ARM иметь неоптимизированные библиотеки непозволительная роскошь.
[uquote="arkhnchul",url="/forum/viewtopic.php?p=3833449#p3833449"]У gcc, например, есть флаг mno-unaligned-access.[/uquote]Это не панацея. C/C++ так устроен, что можно заставить компилятор сделать невыровненный доступ. Это грубый косяк, но он всё ещё в библиотеках встречается. Ответственный разработчик встретив такое отправит багрепорт автору.
Это мы говорили про тулчейн. Он должен всё об архитектуре чипа знать. Вон, чуть выше код под AVR был
Код: Выделить всё
const __flash char __flash *strs_pwr[] = {};хочется верить, что для ARM код будет вполне рабочим, если предварительно сделатьVladislavS писал(а):Убери одну __flash и код кардинально меняется
#define __flash /* */
интересно, каким предопределенным макросом можно отличить arm-gcc от avr-gcc?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
[uquote="ARV",url="/forum/viewtopic.php?p=3833509#p3833509"]интересно, каким предопределенным макросом можно отличить arm-gcc от avr-gcc?[/uquote]Не только что это ARM и какое конкретно ядро, но ещё и тип и версию компилятора. RTFM.
Пример из моего стартапа
Добавлено after 5 minutes 30 seconds:
[uquote="ARV",url="/forum/viewtopic.php?p=3833509#p3833509"]#define __flash /* */[/uquote]Какой ужас!
Пример из моего стартапа
Код: Выделить всё
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION>=6100100)
#define __KEIL_CODE__
#elif defined(__GNUC__)
#define __GCC_CODE__
#elif defined(__ICCARM__)
#define __IAR_CODE__
#elif defined( __CC_ARM ) || defined(__MICROLIB)
#error "ARMCC v5 and MICROLIB not supported"
#else
#error "Can't detect compiler"
#endif[uquote="ARV",url="/forum/viewtopic.php?p=3833509#p3833509"]#define __flash /* */[/uquote]Какой ужас!
поясните, а то ваш эмоциональный возглас несколько напрягает.VladislavS писал(а):Какой ужас!
правильнее было бы все это переопределить как-то так:
Код: Выделить всё
#if defined(__AVR__)
#define flash __flash
#elif defined(__ARM__)
#define flash
#else
#error ???
#endifя просто поленился писать сразу
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Реклама
помогите, как правильно написать, ни как не соображу.
так не работает
if(mode==условие){
if(month==1 && day==1 && minute%10==9){бегущая строка;} // новый год
if(month==1 && day==20&& minute%10==9){бегущая строка;} // день рож Сережи
if(month==5 && day==1 && minute%10==9){бегущая строка;} // день рож у мамы
if(month==5 && day==9 && minute%10==9){бегущая строка;} // день победы
if(month==6 && day==26&& minute%10==9){бегущая строка;} // день рож Илюши
if(month==8 && day==13&& minute%10==9){бегущая строка;} // день рож Вани
if(hour==21&&minute==55){бегущая строка;} // пора спать
else disp=показывать часы;
}
так все работает
if(mode==условие){
if (month==1 && day==1 && minute%10==9) {бегущая строка;} // новый год
else disp=показывать часы;}
так не работает
if(mode==условие){
if(month==1 && day==1 && minute%10==9){бегущая строка;} // новый год
if(month==1 && day==20&& minute%10==9){бегущая строка;} // день рож Сережи
if(month==5 && day==1 && minute%10==9){бегущая строка;} // день рож у мамы
if(month==5 && day==9 && minute%10==9){бегущая строка;} // день победы
if(month==6 && day==26&& minute%10==9){бегущая строка;} // день рож Илюши
if(month==8 && day==13&& minute%10==9){бегущая строка;} // день рож Вани
if(hour==21&&minute==55){бегущая строка;} // пора спать
else disp=показывать часы;
}
так все работает
if(mode==условие){
if (month==1 && day==1 && minute%10==9) {бегущая строка;} // новый год
else disp=показывать часы;}
- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
Применяйте более наглядное форматирование кода, тогда и логика работы программы будет лучше прослеживаться.
Так что-ли хотели?
Спойлер
Код: Выделить всё
if(mode==условие)
{
if(month==1 && day==1 && minute%10==9){бегущая строка;} // новый год
if(month==1 && day==20&& minute%10==9){бегущая строка;} // день рож Сережи
if(month==5 && day==1 && minute%10==9){бегущая строка;} // день рож у мамы
if(month==5 && day==9 && minute%10==9){бегущая строка;} // день победы
if(month==6 && day==26&& minute%10==9){бегущая строка;} // день рож Илюши
if(month==8 && day==13&& minute%10==9){бегущая строка;} // день рож Вани
if(hour==21&&minute==55)
{бегущая строка;} // пора спать
else
disp=показывать часы;
}
if(mode==условие)
{
if (month==1 && day==1 && minute%10==9)
{бегущая строка;} // новый год
else
disp=показывать часы;
}Спойлер
Код: Выделить всё
if(mode==условие)
{
if(month==1 && day==1 && minute%10==9){бегущая строка;} // новый год
else if(month==1 && day==20&& minute%10==9){бегущая строка;} // день рож Сережи
else if(month==5 && day==1 && minute%10==9){бегущая строка;} // день рож у мамы
else if(month==5 && day==9 && minute%10==9){бегущая строка;} // день победы
else if(month==6 && day==26&& minute%10==9){бегущая строка;} // день рож Илюши
else if(month==8 && day==13&& minute%10==9){бегущая строка;} // день рож Вани
else if(hour==21&&minute==55){бегущая строка;} // пора спать
else disp=показывать часы;
}- Сообщения: 1978
- Зарегистрирован: Ср июл 17, 2013 13:55:57
Serzh2000, потому что else if надо, иначе условие "else disp=показывать часы;" будет срабатывать всегда, когда не срабатывает "if(hour==21&&minute==55){бегущая строка;} // пора спать" только, наплевав на остальные.
if(условие А){Применяйте более наглядное форматирование кода
if(условие Б){...;}
if(условие В){...;}
if(условие Г){...;}
else условие Д;
}
нужно что бы было : если условие А верно
проверяем условие Б ,условие В, условие Г ( если одно из них верно бежит строка)
если не одно не верно выполняем else условие Д;
я кавычки не правильно ставлю {} , как правильно?
Спойлер
prevDisp=disp; // сохраняем предыдущий дисплейSerial.print(month);Serial.print(day);Serial.print(minute%10);
if(mode==0){ if(month==1 && day==1 && minute%10==9){disp=dispTabB[second/3];prevTrans=0;} // новый год
if(month==1 && day==20&& minute%10==9){disp=dispTabB[second/3];prevTrans=0;} // день рождения у папы
if(month==5 && day==1 && minute%10==1){disp=dispTabB[second/3];prevTrans=0;} // день рождения у мамы
if(month==5 && day==9 && minute%10==9){disp=dispTabB[second/3];prevTrans=0;} // день победы
if(month==6 && day==26&& minute%10==9){disp=dispTabB[second/3];prevTrans=0;} // день рождения Илюша
if(month==8 && day==13&& minute%10==9){disp=dispTabB[second/3];prevTrans=0;} // день рождения Ваня
if(hour==21&&minute==55) {disp=dispTabB[second/3];prevTrans=0;} // пора спать
else disp=dispTab[second/3];
}
if(mode==1) disp=CLOCKBIG;
if(mode==2){if(hour==21&&minute==55){disp=dispTabMED[second/3];prevTrans=0;}
else disp=dispTab1[second/3];}
if(mode==3) disp=CLOCKMED1;
if(mode==4){ if(month==1 && day==1 && minute%10==9){disp=dispTabANM[second/3];prevTrans=0;} // новый год
if(month==1 && day==20&& minute%10==9){disp=dispTabANM[second/3];prevTrans=0;} // день рождения у папы
if(month==5 && day==1 && minute%10==9 ){disp=dispTabANM[second/3];prevTrans=0;} // день рождения у мамы
if(month==5 && day==9 && minute%10==9){disp=dispTabANM[second/3];prevTrans=0;} // день победы
if(month==6 && day==26&& minute%10==9){disp=dispTabANM[second/3];prevTrans=0;} // день рождения Илюша
if(month==8 && day==13&& minute%10==9){disp=dispTabANM[second/3];prevTrans=0;} // день рождения Ваня
if(hour==21&&minute==55) {disp=dispTabANM[second/3];prevTrans=0;} // пора спать
else disp=dispTab2[second/3];
}
if(mode==5) disp=CLOCK1;
if(mode==6) disp=TEMP;
if(mode==7) disp=CLOCKBIGJMP;
у меня таких условий А несколько...
- Сообщения: 1978
- Зарегистрирован: Ср июл 17, 2013 13:55:57
Вам же написали как надо - else if, чтобы "если ни одно условие не верно".я кавычки не правильно ставлю {} , как правильно?
Код: Выделить всё
if(условие А){
if(условие Б){...;}
else if(условие В){...;}
else if(условие Г){...;}
else условие Д;
}
- Сообщения: 275
- Зарегистрирован: Вс окт 20, 2019 13:03:56
Написал вот такую убогую програмку:
И пытаюсь ее скомпилять с помощью AVR-GCC. А он такой мне говорит: мол, конфликт типов в подпрограмме sh_pulse().
хотя, она ничего не принимает, и ничего не возвращает. Но если заменить void на int, то становится все хорошо. На другие void почему-то не ругается
Почему компилятору не понравилась именно эта подпрограмма?
И еще вопрос: пытался делать это под линуксом (debian 10 x64), там AVR-GCC (установленный через APT) выдает типа:
avr-libs установлен. Файлы *.h физически присутствуют, проверил. Другие файлы (в. т ч с этим DDRB) компилирует. В интернете - пространные рассуждения на 20 страниц по английски.
Код: Выделить всё
#define F_CPU 1000000UL
#define sclock PB1
#define sdata PB2
#define ledpin PB0
#include <avr/io.h>
#include <util/delay.h>
void setup(void)
{
DDRB |= (1 << ledpin)|(1 << sclock)|(1 << sdata);
}
void hc164send(unsigned char sh_data)
{
int i;
for (i=0; i<8; i++)
{
if (sh_data & 0x80)
{
PORTB |= (1 << sdata);
}
else
{
PORTB &= ~(1 << sdata);
}
sh_data = sh_data<<1;
sh_pulse();
}
}
void hc164reset(void)
{
hc164send(0x00);
}
void sh_pulse(void)
{
PORTB |= (1 << sclock);
PORTB &= ~(1 << sclock);
}
void ledflash(void)
{
PORTB |= (1 << ledpin);
_delay_ms(5);
PORTB &= ~(1 << ledpin);
_delay_ms(5);
}
void main(void)
{
setup();
hc164reset();
unsigned char j = 0x00;
while(1)
{
hc164send(j);
ledflash();
j++;
_delay_ms(300);
}
}
Код: Выделить всё
D:\comp\avr8-gnu-toolchain\bin>avr-gcc -Os -mmcu=atmega48 -o d:\avr\hc164.elf d:
\avr\hc164.c
d:\avr\hc164.c:38:6: warning: conflicting types for 'sh_pulse' [enabled by defau
lt]
void sh_pulse(void)
^
d:\avr\hc164.c:30:3: note: previous implicit declaration of 'sh_pulse' was here
sh_pulse();
^
Почему компилятору не понравилась именно эта подпрограмма?
И еще вопрос: пытался делать это под линуксом (debian 10 x64), там AVR-GCC (установленный через APT) выдает типа:
Код: Выделить всё
/mnt/ntfs_d/avr/hc164.c:13:2: error: 'DDRB' undeclared (first use in this function)
DDRB |= (1 << ledpin)|(1 << sclock)|(1 << sdata);
^
/mnt/ntfs_d/avr/hc164.c:13:2: note: each undeclared identifier is reported only once for
each function it appears in
Это потому что sh_pulse вызывается в коде раньше, чем объявляется - отсюда и проблема implicit declaration.
А необъявленные функции вроде как считаются по умолчанию возвращающими int, отсюда и "починка" помогает.
Либо выстраивайте последовательность функций так, чтобы "верхние" никогда не использовали "нижние", либо, что правильнее, для каждой функции в начале файла их дополнительно объявляйте. В идеале - как static, если они не вызываются из других модулей.
А необъявленные функции вроде как считаются по умолчанию возвращающими int, отсюда и "починка" помогает.
Либо выстраивайте последовательность функций так, чтобы "верхние" никогда не использовали "нижние", либо, что правильнее, для каждой функции в начале файла их дополнительно объявляйте. В идеале - как static, если они не вызываются из других модулей.
- Сообщения: 1978
- Зарегистрирован: Ср июл 17, 2013 13:55:57
[uquote="Shuspano",url="/forum/viewtopic.php?p=3835922#p3835922"]d:\avr\hc164.c:30:3: note: previous implicit declaration of 'sh_pulse' was here
sh_pulse();
^[/uquote]
Уже ответили, но если не понятно, после #include'ов напишите строку void sh_pulse(void); именно с ; в конце, без самого тела функции и заработает всё. Кстати void в скобках можно не писать везде. void sh_pulse()
sh_pulse();
^[/uquote]
Уже ответили, но если не понятно, после #include'ов напишите строку void sh_pulse(void); именно с ; в конце, без самого тела функции и заработает всё. Кстати void в скобках можно не писать везде. void sh_pulse()
Скорее всего в опциях компиляции не указали модель МК ключиком -mmcuИ еще вопрос: пытался делать это под линуксом (debian 10 x64), там AVR-GCC (установленный через APT) выдает типа:
- Сообщения: 275
- Зарегистрирован: Вс окт 20, 2019 13:03:56
[uquote="WiseLord",url="/forum/viewtopic.php?p=3835924#p3835924"]Это потому что sh_pulse вызывается в коде раньше, чем объявляется.[/uquote]
Когда-то достаточно давно, пытался ковырятся с Borland C 3.1, помню он очень ревностно относился к синтаксису.
Спасибо, буду знать.NStorm писал(а):Кстати void в скобках можно не писать везде. void sh_pulse()
Когда-то достаточно давно, пытался ковырятся с Borland C 3.1, помню он очень ревностно относился к синтаксису.
- Сообщения: 1978
- Зарегистрирован: Ср июл 17, 2013 13:55:57
Ну нынче если вы определяете (не путать с объявлением, о котором я выше написал) функцию, то f() { ... } = f(void) { ... }. А вот с объявлением ( f(); ) могут быть нюансы, если потом определение не void. Я что-то сразу об этом не подумал. Если привыкли писать f(void) то и фиг с ним, проблема не в этом )
Подскажите как сделать. Тоже рисую велосипед меню. И у меня есть такая структура:
И вот мне захотелось, чтобы int* variable иногда являлся адресом void функции без параметров, которую я хочу запустить на выполнение.
как написать функцию, которой если передать int *variable, вызвала бы на выполнение функцию по адресу этой variable?
Код: Выделить всё
typedef struct {
unsigned char todisplay[16];
int *variable;
datatype_t datatype;
} menuitem_t;как написать функцию, которой если передать int *variable, вызвала бы на выполнение функцию по адресу этой variable?
Код: Выделить всё
void FreeRun(void);
menuitem_t menu[] = {
...
{"Free Run", (int*)FreeRun, execute},
...
}А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Можно запустить на выполнение, например, так:как написать функцию, которой если передать int *variable, вызвала бы на выполнение функцию по адресу этой variable?
void Test(void)
{
};
menuitem_t menuitem;
menuitem.variable=(int*)Test;
typedef void (*func_ptr)(void);
((func_ptr)menuitem.variable)();
И день и ночь в пути...
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos
Написал так:
Вррроде работает... сейчас попробую через typedef.
О, так даже проще! Спасибо.
Код: Выделить всё
void do_execute(int* addr) {
void (*Task)(void);
Task = (void (*)(void))addr;
(*Task)();
}О, так даже проще! Спасибо.
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Вот такой пример:
Выводит:
Спойлер
Код: Выделить всё
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
typedef enum {
var_int,
var_char,
execute,
} datatype_t;
typedef struct {
unsigned char todisplay[16];
void *variable;
datatype_t datatype;
} menuitem_t;
void FreeRun(void)
{
printf("Hello FreeRun\n");
}
int height = 3;
char hour = 10;
typedef enum {
HEIGHT,
FREE_RUN,
HOUR,
} menuidx_t;
menuitem_t menu[] = {
[HEIGHT] = {"Height", &height, var_int},
[FREE_RUN] = {"Free Run", FreeRun, execute},
[HOUR] = {"Hour", &hour, var_char},
};
typedef void (*execute_func)(void);
void handleMenu(menuidx_t idx)
{
switch (menu[idx].datatype) {
case var_int: {
int *var = (int *)(menu[idx].variable);
(*var)++;
}
break;
case var_char: {
char *var = (char *)(menu[idx].variable);
(*var)--;
}
break;
case execute: {
execute_func func = (execute_func)(menu[idx].variable);
func();
}
break;
}
}
int main()
{
printf("----Before:\n");
printf("Height: %d\n", height);
printf("Hour: %d\n", hour);
handleMenu(HEIGHT);
handleMenu(FREE_RUN);
handleMenu(HOUR);
printf("----After:\n");
printf("Height: %d\n", height);
printf("Hour: %d\n", hour);
return 0;
}
Спойлер
Код: Выделить всё
----Before:
Height: 3
Hour: 10
Hello FreeRun
----After:
Height: 4
Hour: 9


