Перейти к содержанию
    

Странное предупреждение

описание SPI_FLAG_BSY и декларации SPI1 где?
Вы мои посты читаете? все описания и декларации в приведённом коде.

 

Как одна из возможных причин:....
Я же говорю, вы не читаете мои посты. Смотрите код. Наверно на си не понятно, напишу на русском.

 

CS - нет. СПИ-мастер.

 

1)спим секунду. если что-то и было в спи, то давно вышло.

2)готовим данные....

3)проверяем бизи - waitSpi()

4)записываем в SPI1->DR данные. Данные пишутся в тх регистр, и потом копируются в шифтРегистр. в этот момент должен встать флаг бизи.

6)если ещё есть данные для передачи, goto 2)

 

с момента записи в SPI1->DR до waitSpi() проходит не 1 такт цпу. Тут один поток...проверка на кол-во переданых данных, подготовка данных не быстрая, спешить не куда, всё равно ждать waitSpi().

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

CS - нет. СПИ-мастер.

 

1)спим секунду. если что-то и было в спи, то давно вышло.

2)готовим данные....

...

Суть в том, что вы замели проблему под ковёр, не разбираясь в причинах. В условиях цейтнота такое бывает оправдано, а вообще это некрасиво, не говоря уже о том, что эта проблема может вылезти в будущем. Плюс опыт - он ведь сын ошибок трудных. Вот, собственно, и всё. Лезть глубже в вашу систему сейчас едва ли продуктивно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

PS: Если хотите чтобы Вас понимали однозначно, излагайте свои мысли ясно.

Дык, вы же заявляете: "Я не смотрю на имена файлов тем более пути".

Может, вам стоит более вдумчиво читать, что тут пишут, вместо упражнений в фантазировании? (которое уже даже не смешно).

Сейчас вам ясно, что виноват компилятор, а не я?

Сказанное "В приведённом Вами примере баг в Вашем коде, а не в компиляторе" не желаете опровергнуть и извиниться?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот такой тип багов и называется "гонки". Как я выше и писал. И он конечно ваш, а не оптимизатора. :laughing:
Допустим, гипотетически.... записал в спи-сд данные, что-то сделал пусть будет проверка for(), проверил бизи. между записью и бизи было времени достаточно для выставлдения флага бизи. нужно 1 мкс, f было 10 мкс. Код рабочий, глюков нет. Может такой код перваться прерыванием и 10 мкс могут только увеличиться.... до 100, до 200.... код от этого не упадет и всё будет работать.

Гипотетически!

 

for()
{
waitSpi();
spi->sd = data_out;
somethinkDo();
}

 

Допустим такой код работает без оптимизации..... включили оптимизацию и появилась ваша гонка.... опять же гипотетически.... Вот вы взяли асм.... и начали исследовать, что там не так... и нашли ГОНКУ!!! Как её убрать? не нужно сразу читать SR, а нужно подождать начало передачи. Что делать? Поставить паузу.... Т.е. поставите оптимизатор, чтоб было быстрее, и потом поставите паузу, чтоб не было гонки? Я просто отключу оптимизатор в нужном месте и всё.

 

В таком случает я считаю нет ошибки в неоптимизированном исходном коде и нет ошибки компилятора. Есть одно - при включении оптимизатора код перестает работать. Я вам не пытаюсь доказать, что есть ошибка компилятора. я не знаю. я говорю, что при включении оптимизатора на весь код, на код без ошибок и без глюков - код может лечь. И это не ошибка кода.

 

Суть в том, что вы замели проблему под ковёр, не разбираясь в причинах. В условиях цейтнота такое бывает оправдано
В чем то я с вами соглашусь.... Про цейтнот согласен, про проблему под ковром - нет. Дело в том, что проблема такая "оптимизированный waitSpi() не работает". Тут два пути: 1 - не использовать оптимизированный waitSpi(), 2 - искать причину в оптимизированном waitSpi(). Посмотрите код waitSpi - там по сути оптимизация не нужна. Там нужно указать volatile, что делается в SPL. Весь код функции - одна строчка. Я пошел по пути наименьшего сопротивления. Тоже самое можно сказать про црц и про другие случаи (не буду всё сюда валить). У меня ещё не было случаев, чтобы оптимизатор оголял ошибки в коде. Если есть ошибка в коде - она находится без всяких оптимизаторов. Горе программист, которому для нахождения ошибки нужен оптимизатор.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Дело в том, что проблема такая "оптимизированный waitSpi() не работает". Тут два пути: 1 - не использовать оптимизированный waitSpi(), 2 - искать причину в оптимизированном waitSpi().

Это совсем поверхностный взгляд на проблему. "Когда мокрые пальцы сую в розетку - бьёт током, а когда сухие - не бьёт. Буду совать в розетку сухие пальцы." :laughing:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Т.е. поставите оптимизатор, чтоб было быстрее, и потом поставите паузу,

Именно.

Без for(delay = 0; delay < 20; delay++) __NOP(); не работает складно в железе, ибо

таймер питается частотой с предделителя и запись в регистр MDR_TIMER3->CH1_CNTRL1 не

приводит к должному результату, если после записи MDR_TIMER3->CH1_CNTRL не установить нужное число NOPов.

                            MDR_TIMER3->CH1_CNTRL1 = CH_CNTRL1_FORCE_0;
                            MDR_TIMER3->CH1_CNTRL = (0 << MDR_TIMER_CH_CNTRL_OCCM);
                            MDR_TIMER3->CCR1 = last_cnt + temp;
                            MDR_TIMER3->CH1_CNTRL = (3 << MDR_TIMER_CH_CNTRL_OCCM);
                            for(delay = 0; delay < 20; delay++) __NOP();
                            MDR_TIMER3->CH1_CNTRL1 = CH_CNTRL1_WAIT_RISE;
                            //for(delay = 0; delay < 20; delay++) __NOP();
                            MDR_TIMER3->STATUS = ~(1 << MDR_TIMER_STATUS_CCR_REF1_EVENT);
                            //for(delay = 0; delay < 20; delay++) __NOP();
                            MDR_TIMER3->IE |= (1 << MDR_TIMER_IE_CCR_REF1_EVENT_IE);
                            pulse[0].state = PULSE_STATE_WAIT_RISE;

Телепаты в курсе, что это миландровский К1986ВЕ92 попил мою кровушку.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Телепаты в курсе, что это миландровский К1986ВЕ92 попил мою кровушку.

А не лучше ли вот так:

MDR_TIMER3->CH1_CNTRL = NEW_VALUE;
while (MDR_TIMER3->CH1_CNTRL != NEW_VALUE);

???

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А не лучше ли вот так:

MDR_TIMER3->CH1_CNTRL = NEW_VALUE;
while (MDR_TIMER3->CH1_CNTRL != NEW_VALUE);

???

Не пройдет. Я так понял, что там это не просто регистр, а какой-то командный центр.

Запишется-прочитается на HCLK, но реальное железо отработает, только когда на него клок придет с предделителя.

Вроде, с RTC такое бывает - там нужно ждать синхронизации с блоком 32кГц, но там и битик есть, что синхронизация состоялась.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я же говорю, вы не читаете мои посты. Смотрите код. Наверно на си не понятно, напишу на русском.

Да пишите хоть на китайском, мне ваш код безразличен, это ведь не у меня при включении/выключении оптимизации он то работает, то нет. Мои исходники работают вне зависимости от того включена оптимизация или нет, у меня таких проблем нет.

 

1)спим секунду. если что-то и было в спи, то давно вышло.

2)готовим данные....

3)проверяем бизи - waitSpi()

4)записываем в SPI1->DR данные. Данные пишутся в тх регистр, и потом копируются в шифтРегистр. в этот момент должен встать флаг бизи.

6)если ещё есть данные для передачи, goto 2)

Должен да не обязан. Где между п.4 и п.6 проверка, что бизи установился? "Вы мои посты читаете"? Я о таком кривом подходе как здесь ещё несколько постов назад написал. Вот как раз такой код и будет работать в зависимости от уровня оптимизации, количества передаваемых данных, фаз луны.... А, ну да, зачем читать и думать, ведь всё уже выяснено - компилятор виноват! :laughing:

 

Сказанное "В приведённом Вами примере баг в Вашем коде, а не в компиляторе" не желаете опровергнуть и извиниться?

Нет, не желаю так как причина баг не найдена. Вы не доказали никак вину компилятора. Да собственно там у вас и не баг в выполнении программы, а ошибка компиляции.

 

Допустим такой код работает без оптимизации..... включили оптимизацию и появилась ваша гонка....

Гонки у Вас всегда есть, а не только при вкл. оптимизации. Почитайте в инете что это такое. Надо писать код, свободный от такого.

 

Как её убрать? не нужно сразу читать SR, а нужно подождать начало передачи. Что делать? Поставить паузу.... Т.е. поставите оптимизатор, чтоб было быстрее, и потом поставите паузу, чтоб не было гонки? Я просто отключу оптимизатор в нужном месте и всё.

Правильно тут уже написали про Ваш стиль: Вместо подумать и понять как сделать правильно, замести проблему под ковёр. :biggrin:

В том цикле достаточно всего лишь после записи данных в SPI, дождаться начала их передачи (выставления бизи). Но конечно это кривой метод, так как потребует запрета прерываний (чтобы вся передача не проскочила за время внезапно возникшего прерывания).

А чтобы написать правильно и корректно нужно вообще весь алгоритм этот изменить, использовать другие флаги, прерывания и пр.

 

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

Ещё горше тот, которому оптимизатор её нашёл, указал, а он прячет голову в песок.

 

Телепаты в курсе, что это миландровский К1986ВЕ92 попил мою кровушку.

И DSB/DMB не спасают?

 

Запишется-прочитается на HCLK, но реальное железо отработает, только когда на него клок придет с предделителя.

Тогда должны быть какие-то статусные биты, говорящие о завершении операции периферией.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Правильно тут уже написали про Ваш стиль: Вместо подумать и понять как сделать правильно, замести проблему под ковёр.
Нет, не правильно. Есть задача - написать текст. Есть 2 карандаша. Один пишет, другой не пишет. Я не буду тратить время на выяснение, почему не пишет один карандаш, если я могу обойтись без него. Я другим карандашом текст напишу.

Вы выяснили и устранили, почему при вкл холодильника виснет CCS? Вы замелм пролему под ковёр заменили кабель усб и продолжили работать.

 

Ещё горше тот, которому оптимизатор её нашёл
У меня оптимизатор ошибок не нашел.

мне ваш код безразличен
Зачем вы просили код в студию? Хотели найти в нем ошибку. Нашли? Или чтоб написать "мне ваш код безразличен"?

 

при включении/выключении оптимизации он то работает, то нет
Где я писал, что "то работает то нет"? У меня такого кода нет.

А, ну да, зачем читать и думать, ведь всё уже выяснено - компилятор виноват!
Что компилятор виноват - это ваши слова, не нужно их мне приписывать.

Я же говорю вы не читаете мои посты, не вижу смысла дальнейшей дискуссии с вами по этому поводу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нет, не желаю так как причина баг не найдена. Вы не доказали никак вину компилятора. Да собственно там у вас и не баг в выполнении программы, а ошибка компиляции.

Если компилятор не может собрать корректный код, то по вашему это не баг компилятора?

Вы понимаете, что компилятор, компилируя esp8266.c, создал временный s-файл, в котором смещение им же считается неверно?

А при эквивалентной перестановке строк в Си-исходнике он может собирать или не собирать исходник.

В этом я виноват?

 

И DSB/DMB не спасают?

Очевидно же нет, т.к. у таймера как у периферийного блока своя собственная частота.

 

Пример из errata на этот проц привел в скрине.

"Обеспечивать необходимую задержку" тупо NOP`ами.

 

Насчет MDR_TIMER3->CH1_CNTRL там же есть бага 0013:

"В регистре есть бит, но он всегда читается как 1, при этом запись в него корректно задает режим".

 

Тогда должны быть какие-то статусные биты, говорящие о завершении операции периферией.

А если их нет? В данном случае их нет, и производитель в аналогичной ситуации рекомендует "обеспечивать необходимую задержку".

post-27702-1529592362_thumb.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вместо стольких слов достаточно посмотреть листинг одной строчки, чтобы увидеть виноват ли оптимизатор.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вместо стольких слов достаточно посмотреть листинг одной строчки, чтобы увидеть виноват ли оптимизатор.

Я об этом неоднократно тут говорил. Но товарищ, винивший оптимизатор, так и не привёл этот самый листинг. Может он не знает что это такое? B)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Посмотрите сколько лишних операций в for у ТС! какие-то приведения типов, операторы, << и |, дополнительный j, операции j++!!! УЖАС!!!

И что? Современные оптимизаторы творят чудеса. И им по-барабану Ваши жалкие потуги заменить операции индексирования на указатели и подобное - они это и сами хорошо делают, даже ещё и лучше. Так что если бы код автора не был такой кривой, результат работы оптимизирующего компилятора мог быть лучше memcpy().

 

Попробуйте когда-нить

попробую обязательно.

 

Добрый день фантазёры, эльфы, а также программисты. Совсем недавно (2017-2018 год) занимался оптимизацией кода в STM8. Ручные потуги оптимизации давали очень хороший результат. Оптимизатор конечно оптимизировал код, но некоторый несложный рефакторинг давал значительно лучший результат. Может стм8 сырой? может арм действительно рулит? Проверил на арме.... собрал код ТС, улучшенный код ТС, а также просто memcpy(). В трёх случаях заполнял массив uin16_t [16] из массива uin8_t[32]. Измерял осциллографом.

улучшенный код ТС выглядит так:

 

#define SIZ    32
uint8_t dataOut[SIZ+2];
uint16_t buffer[SIZ/2];
uint8_t *p1 = (uint8_t*)buffer;
uint8_t *p2 = (uint8_t*)&dataOut[0];
...
GPIO_SetBits(GPIOA, GPIO_Pin_5); //ТР2 = 1
//оптимизированный варинат ТС
for(int i = 0; i < SIZ; i++)
    p1[i] = p2[i];
GPIO_ResetBits(GPIOA, GPIO_Pin_5);

 

Результат - (код TC с "<<", "|", "++", "j") / (улучшенный код ТС) / (говноmemcpy() )

Не оптимизированный код дал результат 8/5/1.3 мкс

с оптимизацией по скорости -Ohs результат 3/0.5/0.5 мкс

 

кагбэ в примере всё выровнено к 4. Но серийные данные не всегда выровнены, поэтому усложнил задачу МК и приблизил к реальности, uint8_t *p2 = (uint8_t*)&dataOut[1];

получил без оптимизациии 8/5/2мкс, с оптимизацией -Ohs 3/2/1.7 мск

 

Результат на лицо. Априори. Вот вам и наряд в не очереди современные оптимизаторы!!!

 

ps проверял на стм32ф103, компилятор иар.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Добрый день фантазёры, эльфы, а также программисты. Совсем недавно (2017-2018 год) занимался оптимизацией кода в STM8. Ручные потуги оптимизации давали очень хороший результат. Оптимизатор конечно оптимизировал код, но некоторый несложный рефакторинг давал значительно лучший результат. Может стм8 сырой?

Кстати, стм8 - особый случай. Там нет выдающихся компиляторов. Яр на уровне исходника умеет выкидывать лишние переменные и т.д., но машинный код делает плохенький. Видимо, избрана плохая стратегия генерации кода, и/или реализация подкачала. Они там придумали виртуальные регистры, предположительно, чтобы компилятору было удобнее. Результат так себе. Недавно попробовал космик, там код генерится практически в лоб, строчка исходника - несколько инструкций. Каждая локальная переменная выделяется на стеке. Результат в целом лучше, чем у яра. Ну и зная о прямом соответствии исходника и машинного кода, простор для микрооптимизаций на уровне исходника огромный.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...