Nixon 3 19 марта, 2018 Опубликовано 19 марта, 2018 (изменено) · Жалоба По мотивам STM32TPL от Anton B. Gusev aka AHTOXA сделал с учетом новых возможностей С++11/14 подобное для EFM32 Особенно интересно получился класс PortPins. чуток поправил efm32lg_gpio.zip Изменено 20 марта, 2018 пользователем Nixon форматирование Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 35 19 марта, 2018 Опубликовано 19 марта, 2018 · Жалоба Порадовала особенно эта строка enum { MODE0 = X*0x00, MODE1 = X*0x01, MODE2 = X*0x02, MODE3 = X*0x03, MODE4 = X*0x04, MODE5 = X*0x05, MODE6 = X*0x06, MODE7 = X*0x07, MODE8 = X*0x08, MODE9 = X*0x09, MODEA = X*0x0A, MODEB = X*0x0B, MODEC = X*0x0C, MODED = X*0x0D, MODEE = X*0x0E, MODEF = X*0x0F }; ну и остальное смотрел на одном дыхании. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 10 20 марта, 2018 Опубликовано 20 марта, 2018 · Жалоба а этот код рабочий? или я не понимаю этот с++14 новомодный.... class Pin { ... enum { DOUTx = 0x42000000UL + (GPIOx_BASE + offsetof(GPIOxTypeDef, DOUT) - 0x40000000UL) * 32 + pin * 4 }; ..} как это работает? чему DOUTx будет равно для РА5? Я так посчитал DOUTx = 0x4200_0000 + (0x4000_6000 + 0x1C - 0x4000_0000) * 0x20 + 5 * 4 DOUTx = 0x4200_0000 + 0x601C * 0x20 + 0x14 DOUTx = 0x4200_0000 + 0xС0380 + 0x14 DOUTx = 0x420С_0394 я правильно посчитал? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nixon 3 20 марта, 2018 Опубликовано 20 марта, 2018 · Жалоба а этот код рабочий? или я не понимаю этот с++14 новомодный.... class Pin { ... enum { DOUTx = 0x42000000UL + (GPIOx_BASE + offsetof(GPIOxTypeDef, DOUT) - 0x40000000UL) * 32 + pin * 4 }; ..} как это работает? чему DOUTx будет равно для РА5? Я так посчитал DOUTx = 0x4200_0000 + (0x4000_6000 + 0x1C - 0x4000_0000) * 0x20 + 5 * 4 DOUTx = 0x4200_0000 + 0x601C * 0x20 + 0x14 DOUTx = 0x4200_0000 + 0xС0380 + 0x14 DOUTx = 0x420С_0394 я правильно посчитал? Правильно. BitBanding memory area. Делал для себя, поэтому комментарии почти не писал. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RadiatoR 2 20 марта, 2018 Опубликовано 20 марта, 2018 · Жалоба А почему нет? Если обертка для bb рабочая и эффективная, то не грех выложить. Лично я попробую. Спасибо автору. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nixon 3 20 марта, 2018 Опубликовано 20 марта, 2018 · Жалоба По поводу эффективности. IAR 8.22, optimization - medium Время выполнения на константных параметрах: PortPins::Mode - 20 + pins тактов PortPins::Set - 2 * pins тактов PortPins::Get - 2 + 3*pins тактов PortMask::Mode - 19 тактов PortMask::Set - 4 такта PortMask::Get - 4 такта Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kabdim 0 20 марта, 2018 Опубликовано 20 марта, 2018 · Жалоба Исходники всё же лучше выкладывать на гитхаб(или аналоги), нет лицензии. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 10 20 марта, 2018 Опубликовано 20 марта, 2018 · Жалоба PortPins::Get - 2 + 3*pins тактовне торт. 16 пинов 50 тактов. Если в лоб вычитать ODR 1-3 такта. Но в коде писать удобней. Плата за удобство. А сколько тактов Pin::Get()? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 20 марта, 2018 Опубликовано 20 марта, 2018 · Жалоба По поводу эффективности. Цифры действительно неплохие ... для поклонников ногодрыга :) Но в остальных случаях особой разницы не будет: 1) скорость настройки портов в подавляющем число проектов не важна, т.к. это делается один раз при запуске 2) может иметь значение лишь скорость чтения/записи пинов, но это делается несколькими строчками инлайн кода, годится любое решение, на классах и без 3) если делать на классах, то размер занимаемого кода (озу/флэш) для классов пинов тоже не имеет критичного значение, т.к. в камне число пинов ограничено физически, а у толстых камней и озу/флэши всегда больше. Потому, имхо, применение той или иной обертки (не только для пинов) должно быть предельно очевидным, ознозначным и тривиальным. Т.е. читаемым должен прежде всего быть код, а не сама библиотека. В данном случае такое обилие способов применения мне лично кажется избыточным (судя по приведенным примерам), ну, главный "недостаток" - повышенные требования к компилятору: C++11/14. В целом, пример интересный и полезный, ну, хотя бы в образовательных целях ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nixon 3 20 марта, 2018 Опубликовано 20 марта, 2018 · Жалоба не торт. 16 пинов 50 тактов. Если в лоб вычитать ODR 1-3 такта. Но в коде писать удобней. Плата за удобство. А сколько тактов Pin::Get()? Согласен, потому и использую для широких портов PortMask. Там все побыстрее будет. Но бывает что нужно красиво использовать неширокую шину с разбросанными пинами. Pin практически не отличим от PortPins на один пин. Можно и убрать этот класс. По поводу вычитки напрямую - вы не забывайте что PortPins еще и правильно мапит нужный пин в нужный бит. А это тоже затраты. Цифры действительно неплохие ... для поклонников ногодрыга :) Но в остальных случаях особой разницы не будет: 1) скорость настройки портов в подавляющем число проектов не важна, т.к. это делается один раз при запуске 2) может иметь значение лишь скорость чтения/записи пинов, но это делается несколькими строчками инлайн кода, годится любое решение, на классах и без 3) если делать на классах, то размер занимаемого кода (озу/флэш) для классов пинов тоже не имеет критичного значение, т.к. в камне число пинов ограничено физически, а у толстых камней и озу/флэши всегда больше. Потому, имхо, применение той или иной обертки (не только для пинов) должно быть предельно очевидным, ознозначным и тривиальным. Т.е. читаемым должен прежде всего быть код, а не сама библиотека. В данном случае такое обилие способов применения мне лично кажется избыточным (судя по приведенным примерам), ну, главный "недостаток" - повышенные требования к компилятору: C++11/14. В целом, пример интересный и полезный, ну, хотя бы в образовательных целях ;) 1. Скорость настройки портов бывает важна - например при двунаправленных шинах. Согласен, это редкое применение, но бывает 2. Иногда после чтения (или перед записью) пинов нужно делать кучу преобразований (битовых манипуляций), тут это делается автоматически 3. Необходимый размер RAM для данной обертки 1 байт на экземпляр класса (или 0 байт для работы со статическими методами). Размер ROM действительно велик (по сравнению с требованиями к RAM), из-за сплошного inline, но для большинства камней действительно не критичен А по поводу компилятора - а кто сейчас для ARM не делает поддержку С++11/14? Последним был IAR и то уже исправился. В целом я с вами согласен - это чисто образовательный пример, но с практическим значением :) Хотел бы заметить что многие вещи, ранее невозможные (или приводящие к большой избыточности кода) на 11/14 делаются не в пример легче и удобнее. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 10 20 марта, 2018 Опубликовано 20 марта, 2018 · Жалоба Pin практически не отличимвроде как 3 такта должен быть. ну это мож на стм32. Пример интересный.... я бы не полез смотеть сырц, если бы в описании видел IV. Check pin state: * Var = PA5::Get() //return int: 0 when RESET, 1 when SET * Var = pa5.Get() or * VAR = pa5; вроде как логично 0 это 0, а 1 это 1, но вдруг вы возвращяете для порта РА5 значение (1<<5)? Такое тоже бывает. А может возвращаете RESET или SET, true или false, LOW или HI. Но так вы пишете для себя.... 2Forger если дополнить описание в шапке, то будет всё очевидно, понятно, тривиально и читаемо. В реализацию вообще можно не заглядывать, разве что для образовательных целей. c11 щя все поддерживают. IAR, gcc. Про кеил не знаю, может там его нет. вроде как 7 лет прошло. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nixon 3 20 марта, 2018 Опубликовано 20 марта, 2018 · Жалоба вроде как 3 такта должен быть. ну это мож на стм32. Пример интересный.... я бы не полез смотеть сырц, если бы в описании видел вроде как логично 0 это 0, а 1 это 1, но вдруг вы возвращяете для порта РА5 значение (1<<5)? Такое тоже бывает. А может возвращаете RESET или SET, true или false, LOW или HI. Но так вы пишете для себя.... Для Pin и PortPins производится приведение считываемых данных к их реальному размеру. Т.е. для Pin вернется или 0 или 1, но никак не 1<<5 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 20 марта, 2018 Опубликовано 20 марта, 2018 · Жалоба Про кеил не знаю, может там его нет. вроде как 7 лет прошло. У кейла С++11/14 держит ARM компилятор v6, но он делает заметно бОльший код, чем старый компилятор v5 (по крайней мере в моих проектах). старый v5 лишь частично поддерживает C++11 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 10 20 марта, 2018 Опубликовано 20 марта, 2018 · Жалоба Для Pin и PortPins производится приведение считываемых данных к их реальному размеру. Т.е. для Pin вернется или 0 или 1, но никак не 1<<5 Это вы знаете, так как вы знаете, что так и куда приводиться. Вы знаете что там BitBanding. у того же АНТОХА * V. Check pin state: * if (PA5::Signalled()) // returns non-zero if pin input = active state (H for PA5) возвращает ноль и НЕ НОЛЬ, а не ноль может быть и 1<<5. Ни куда не надо лезть, из шапки всё понятно. Если писать для людей (да и для себя. т.к. сможете забыть), то уж лучше уже в шапке чиркнуть возвращаемое значение. Хотел сразу про это сказать, но у вас код "для себя". )) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 20 марта, 2018 Опубликовано 20 марта, 2018 · Жалоба например при двунаправленных шинах Да это - ногодрыг в чистом виде! Такое, имхо, лучше делать через прямое обращение к портам без всяких оберток и классов, разумеется, в ущерб читаемости. Но такие случаи обычно связаны с очень медленными (например, 1-wire) интерфейсами, где суперскорость не имеет значения. Поэтому ни что не мешает использовать даже толстые обертки. Лишь бы код был предельно простой, лаконичный и читаемый, а вся эта "срамота" скрыта в недрах библиотеки/обертки. В особых случаях, если число пинов позволяет, то я бы задействовал не один двунаправленный, а два однонаправленных пина, соединенных вместе: один на выход, второй на вход. Но признаюсь, с таким пока еще ни разу никогда не сталкивался. 2. Иногда после чтения (или перед записью) пинов нужно делать кучу преобразований (битовых манипуляций), тут это делается автоматически Надуманная "проблема" или я не пойму о чем речь. Приведите пример )) Хотел бы заметить что многие вещи, ранее невозможные (или приводящие к большой избыточности кода) на 11/14 делаются не в пример легче и удобнее. А вот этот момент просвятите, пожалуйста, по-подробнее, разумеется, в применении к нашей области (МК) ;) Если возможно, то конкретные ситуации, где это действительно оказалось полезным. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться