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

Кто тестировал IAR ARM 8.50, отзовитесь

4 minutes ago, VladislavS said:

А дальше "держите меня двое".

А не посоветуете что-нибудь для лёгкого и непринуждённого погружения в фичи Си++ хотя бы 14? Кроме тех видео? Дело в том, что читать книги по 700 страниц (а именно такие в моей библиотеке в основном) я даже не представляю как... Может быть есть что-то для лёгкого вхождение: в стиле "наиболее частая проблема управлять несколькими светодиодами... на Си вы делали так... на Си++03 вы делали так... а сегодня вы всё это выбрасываете на... и делаете так - две строчки и работает". Я, конечно, утрирую, но здорово было бы.

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


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

Единственная книга, которую я по С++ прочитал лет 20 назад - Шилдт Герберт "C++. Базовый курс". Естественно, поверх знания С из института. Достаточно живое повествование, без потуг на фундаментальность, но раскладывающее всё по полочкам и дающее понимание как С++ устроен. Применительно к эмбедду обучалок вообще нигде не встречал. Более того, где не упомянёшь С++ тут же ведро помоев на голову получаешь.

41 минуту назад, haker_fox сказал:

на Си++03 вы делали так... а сегодня вы всё это выбрасываете на... и делаете так - две строчки и работает". Я, конечно, утрирую, но здорово было бы.

На самом деле это ни чуть не утрирование. Именно так всё и обстоит. Вот очень поучительное видео в подобном стиле Олег Фатхиев — Эволюция метапрограммирования

Кто хоть что-то слышал про работы Александреску, не могут не помнить многокилометровые рекурсивные вызовы шаблонных функций при работе со списками типов.

То что раньше заняло бы сотню строк, в С++17 можно записать легко и просто. Тут из двух списков (пины и режимы) формируется третий список (обрежимленные пины). Компилятор сам пройдёт по обоим спискам и соберёт из них третий.

  template<typename... Ps, typename... Ms>
  static inline constexpr auto MakeModedPins(TypeList<Ps...> pins, TypeList<Ms...> modes)
  {
    static_assert( sizeof...(Ps) == sizeof...(Ms), "PinList and ModeList sizes is not Equal!");

    return (TypeList<TPin<typename Ps::tgpio, Ps::pin, Ms>>{} + ...);   
  }

Вот так, например, можно режимы ножкам задать вообще не думая о регистрах. IDE сама режимы из выпадающего списка предлагает выбрать.

using nCS       = PB12<PinMode::PushPull_MediumSpeed<1>>;
using SPI2_SCK  = PB10<PinMode::AF_PushPull_HighSpeed<4>>;
using SPI2_MISO = PB14<PinMode::AF_PushPull_HighSpeed<4>>;
using SPI2_MOSI = PB15<PinMode::AF_PushPull_HighSpeed<4>>;
  
PinList<nCS, SPI2_SCK, SPI2_MISO, SPI2_MOSI>::mode();

Или вот так

ConfigList< PinMode::PushPull_MediumSpeed<1>, 
              PB_12,                           // PB12=nCS=1
            PinMode::AF_PushPull_HighSpeed<4>,
              PB_10, PB_14, PB_15              // PB10=SPI2_SCK, PB14=SPI2_MISO, PB15=SPI2_MOSI
          >::mode();

А вот это видео вообще каждый должен посмотреть, даже если считаешь себя гуру. Михаил Матросов — Спецификаторы, квалификаторы и шаблоны

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


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

57 minutes ago, VladislavS said:

А вот это видео вообще каждый должен посмотреть, даже если считаешь себя гуру. Михаил Матросов — Спецификаторы, квалификаторы и шаблоны

Пацан соврал уже на первых минутах выступления. 
Статические автоматические переменные инциализируются до main, а не при первом вызове использующей их функции. 
Ну так как ему дальше верить? 

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

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


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

1 час назад, VladislavS сказал:

Более того, где не упомянёшь С++ тут же ведро помоев на голову получаешь.

Разрешите процитировать самого себя :)

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


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

23 минуты назад, AlexandrY сказал:

Статические автоматические переменные инциализируются до main, а не при первом вызове использующей их функции. 

Можно до main, а можно при первом вызове. Естественно, чисто технически компилятору проще инициализировать её вместе с глобальными переменными, но никто не запрещает сделать и по другому. Стандарту это не противоречит.

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


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

2 часа назад, VladislavS сказал:

То что раньше заняло бы сотню строк, в С++17 можно записать легко и просто. Тут из двух списков (пины и режимы) формируется третий список (обрежимленные пины). Компилятор сам пройдёт по обоим спискам и соберёт из них третий.каждый должен посмотреть, даже если считаешь себя гуру. Михаил Матросов — Спецификаторы, квалификаторы и шаблоны

Тут недалече несколько увлечённых активистов ведут (вели?) беседу по православному тру-шаблонно-ориентированному конфигурированию пинов GPIO. Много-много дней вели и много десятков постов. Если бы это время, что было на такую ерунду потрачено, да в мирных целях! - на что-то более полезное применить! Да за это время можно было USB-стек самостоятельно написать!!! :biggrin:

2 часа назад, VladislavS сказал:

Вот так, например, можно режимы ножкам задать вообще не думая о регистрах. IDE сама режимы из выпадающего списка предлагает выбрать.

Вот как:

  static TPinSel const tPinmux[] = {
    PINSEL(concat(PIN_UART, nUART_serv, _RX), AF, concat(UART, nUART_serv, _RX), PU),
    PINSEL(concat(PIN_UART, nUART_serv, _TX), AF, concat(UART, nUART_serv, _TX)),
    PINSEL(concat(PIN_UART, nUART_term, _RX), AF, concat(UART, nUART_term, _RX), PU),
    PINSEL(concat(PIN_UART, nUART_term, _TX), AF, concat(UART, nUART_term, _TX)),
    PINSEL(concat(PIN_UART, nUART_esp, _RX), GPIO_I, PU),
    PINSEL(concat(PIN_UART, nUART_esp, _TX), GPIO_O, SPD_VH, SET1),
    PINSEL(concat(PIN_SPI, nSPI_lcd_mems, _SCLK), AF, concat(SPI, nSPI_lcd_mems, _SCK), SPD_VH, PU),
    PINSEL(concat(PIN_SPI, nSPI_lcd_mems, _MOSI), AF, concat(SPI, nSPI_lcd_mems, _MOSI), SPD_VH, PU),
    PINSEL(concat(PIN_SPI, nSPI_lcd_mems, _MISO), AF, concat(SPI, nSPI_lcd_mems, _MISO), SPD_VH, PU),
    PINSEL(concat(PIN_I2C, nI2C_share, _SCL), GPIO_O, SPD_H, OD, SET1),
    PINSEL(concat(PIN_I2C, nI2C_share, _SDA), GPIO_O, SPD_H, OD, SET1),
    PINSEL(concat(PIN_TIM, nTIM_ir, _CH, nTIMCH_ir), AF, concat(TIM, nTIM_ir, _CH, nTIMCH_ir), SPD_H, PU),
    PINSEL(PIN_LED_GREEN, GPIO_O, SPD_L, SET0),
    PINSEL(PIN_LED_RED, GPIO_O, SPD_L, SET0),
    PINSEL(PIN_LED_EXT, GPIO_O, SPD_L, SET0),
    PINSEL(PIN_BUTTON, GPIO_I),
    PINSEL(PIN_LCD_CS, GPIO_O, SPD_VH, SET1),
    PINSEL(PIN_LCD_DCX, GPIO_O, SPD_VH, SET1),
    PINSEL(PIN_LCD_TE, GPIO_I),
    PINSEL(PIN_TP_INT1, GPIO_I),
    PINSEL(concat(PIN_SPI, nSPI_dflash, _MOSI), GPIO_O, SPD_H),
    PINSEL(concat(PIN_SPI, nSPI_dflash, _MISO), GPIO_I),
    PINSEL(concat(PIN_SPI, nSPI_dflash, _SCLK), GPIO_O, SPD_H, SET1),
    PINSEL(PIN_DFLASH_CS, GPIO_O, SPD_H, SET1),
...
  };  
  PinSelN(tPinmux);

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

Недопустимый режим или опцию для ножки поставить невозможно (выводится на ошибку компиляции). И всё это - средствами языка си 20-летней давности. И без лишнего runtime кода.  :wink:

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


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

А давай код без ... и выхлоп. Без кишок, только определение. А я то же самое на еретических шаблонах.

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


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

51 minutes ago, VladislavS said:

Можно до main, а можно при первом вызове. Естественно, чисто технически компилятору проще инициализировать её вместе с глобальными переменными, но никто не запрещает сделать и по другому. Стандарту это не противоречит.

Более того, статическая переменная может быть не только int, а, например, может быть экземпляром какого-нибудь класса, конструктор которого не может быть вызван на этапе компиляции.

Изменено пользователем one_eight_seven

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


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

2 минуты назад, one_eight_seven сказал:

конструктор которого не может быть вызван на этапе компиляции

Не на этапе компиляции, а на этапе инициализации глобальных переменных/объектов. Там конструкторы и вызываются.

 

 

22 минуты назад, jcxz сказал:

Да за это время можно было USB-стек самостоятельно написать!!!

А если уже написан?

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


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

15 минут назад, VladislavS сказал:

А давай код без ... и выхлоп. Без кишок, только определение. А я то же самое на еретических шаблонах.

Тот массив из макросов формирует массив структур (const) типа:

__packed struct TPinSel {
  u8 port_pin;
  u16 cfg;
};

содержимое которого потом просто записывается в регистры конфига GPIO. Одна структура - одна нога.

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


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

1 minute ago, VladislavS said:

Не на этапе компиляции, а на этапе инициализации глобальных переменных/объектов. Там конструкторы и вызываются.

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

Но не суть. И в этой фазе конструктор не будет вызван, а вызван будет он при первом обращении:
 

Spoiler

#include <iostream>
using namespace std;

class A {
    private:
        A() { };

        int n;
    public:

        explicit A(int n): n(n) {
            cout << "Here is our n = " << n << endl;
        }

        void print() {
            cout << "now we're pringing ++n "  << ++n << endl;
        }
};

void test() {
    static A a(0);
    a.print();
}

int main () {

    cout << "Here main starts" << endl;
    for (int i = 0; i < 5; ++i) {
        test();
    }

}

 

Далее:
 

$ g++ static_test.cpp 
$ ./a.out 
Here main starts
Here is our n = 0
now we're pringing ++n 1
now we're pringing ++n 2
now we're pringing ++n 3
now we're pringing ++n 4
now we're pringing ++n 5

 

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


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

1 минуту назад, jcxz сказал:

Одна структура - одна нога.

Да это понятно. Я предлагаю просто сравнить. Выдери мне из проекта кусок где ты все ноги конфигуришь, я их точно так же законфигурю. Содержимое PinSelN() неинтересно. Только её выхлоп.

 

4 минуты назад, one_eight_seven сказал:

это всё инициализируется на этапе компиляции

То что работает в рантайме? И зачем вы мне это объясняете? AlexandrY лучше расскажите.

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


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

10 часов назад, VladislavS сказал:

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

Да не нужно мне ничего показывать. Я этот пример привёл не для меряния чего-то с кем-то, а чтобы показать, что задача вполне удобно решается и теми средствами языка, которые были 20 лет назад.

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


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

1 час назад, jcxz сказал:

что задача вполне удобно решается и теми средствами языка

Удобство понятие субъективное, тут спорить бесполезно. При том что ничего удобного я  в приведённом коде не наблюдаю.

1 час назад, jcxz сказал:

которые были 20 лет назад.

Ну так и результат получается как 20 лет назад. Хотя нет, 20 лет назад ресурсы ещё умели экономить.

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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