|
|
  |
Библиотеки для STM32 |
|
|
|
Apr 19 2017, 06:37
|
Знающий
   
Группа: Участник
Сообщений: 825
Регистрация: 16-04-15
Из: КЧР, Нижний Архыз
Пользователь №: 86 250

|
Цитата(Forger @ Apr 19 2017, 09:06)  Вы ошиблись темой. Здесь собрался народ с совершенно иными взглядами на мир. Нам не по пути. Проходите мимо. Это как раз таки вы ошиблись темой! Вам к ардуинщикам надо.
|
|
|
|
|
Apr 19 2017, 06:45
|
Участник

Группа: Участник
Сообщений: 48
Регистрация: 15-07-06
Пользователь №: 18 836

|
Цитата(AHTOXA @ Apr 19 2017, 00:33)  О, пришла пора мериться пинами!  Внесу свою лепту: тынц. В общем так, проинитил я 5 пинов, получил 144 байта, против 188 у меня. Проинитил 10 пинов, получил 252 vs 216, уже в мою пользу. Но при этом твой код изначально не работает на F1, также там используется bitBand, значит он не работает и на F0, но главное это его размер в дебаге... У меня он вырос в 2.4 раза, у тебя в 110  Ты принципиально не пользуешься отладкой?
|
|
|
|
|
Apr 19 2017, 06:56
|

Профессионал
    
Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831

|
Цитата(Reflector @ Apr 19 2017, 09:45)  В общем так, проинитил я 5 пинов, получил 144 байта, против 188 у меня. Проинитил 10 пинов, получил 252 vs 216, уже в мою пользу. На момент создания всего этого у меня было две задачи: убрать кучу кода инициализации пинов, спратав это внутрь одного файла (Pin.hpp), сохранить скорость работы ногодрыга. Оптимизация - это вторично. Главное - user-код изолирован от реализации Pin, который впоследствии можно безболезненно переделать. Цитата Но при этом твой код изначально не работает на F1, также там используется bitBand, значит он не работает и на F0, По них существуют другие соотв. файлы Pin.hpp, размещенные в своих соотв. каталогах. Цитата но главное это его размер в дебаге... У меня он вырос в 2.4 раза, у тебя в 110  До оптимизации в дебаге не доходил. Не было нужды. Хотя за цифры спасибо. Заставляет задуматься )) Цитата Ты принципиально не пользуешься отладкой? Отладкой, разумеется, пользуюсь. А недавно проникся SystemView (segger), жалею, что раньше не освоил ((
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Apr 19 2017, 07:01
|
Участник

Группа: Участник
Сообщений: 48
Регистрация: 15-07-06
Пользователь №: 18 836

|
Цитата(Forger @ Apr 19 2017, 09:56)  До оптимизации в дебаге не доходил. Не было нужды. Хотя за цифры спасибо. Заставляет задуматься )) Эээ. Вообще-то это был ответ AHTOXЕ, твоего полного кода у меня то нет
|
|
|
|
|
Apr 19 2017, 07:21
|

Профессионал
    
Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045

|
Цитата(Forger @ Apr 19 2017, 11:06)  Вы ошиблись темой. Здесь собрался народ с совершенно иными взглядами на мир. Нам не по пути. Проходите мимо. Это вы хамите. Цитата Просто осторожно нужно goto использовать +1 Цитата если goto и метка лежат не дальше, чем в пределах 1-2 страниц текста, то этот код читать удобно, если дальше — могут возникнуть проблемы. эээээ...... 1-2 страницы!!!.... ЕСЛИ ДАЛЬШЕ!?.... Опять же возвращаюсь к стилю программирования.... гудстаил является таким, чтобы функция влезла в монитор. Функция должна быть как на ладони... она должна быть полностью охвачена взглядом. Если что-то скрывается за скролом - это уже черевато багой. Цитата В общем так, проинитил я 5 пинов, получил 144 байта, против 188 у меня. кстати.... эти ваши плюсы.... вот на порту РА нужно проинитить пины 0, 1, 6, 7 как выход... на Led или на CS.... не важно. с SPL или си-стаил инит не такой красивый, но там инитятся порты все хором за раз (в stm32). Теперь допустим надо 0 и 6 выствить в "0", а 1 и 7 выставить в 1. через регистр BRRS это делается за 1 команду си/с++ (вроде как в асме выходит 3 команды). AHTOXА, Forger, Reflector - в ваших юСтайлах сколько строк дизасемблера занимает инит 4-х портов, и сколько переключение? если инит одного порта будет вызван 4 раза.... то в итоге... код будет вызываться один и тот же 4 раза. Но допустим, функция - зашли в неё и проинитили 4 порта, потом выставили на них значение - сколько машинных тактов будет крутиться код при ините и при переключении? А если не 4 пина, а 13 пинов и все на РА?
|
|
|
|
|
Apr 19 2017, 07:22
|
Участник

Группа: Участник
Сообщений: 48
Регистрация: 15-07-06
Пользователь №: 18 836

|
Цитата(Эдди @ Apr 19 2017, 08:16)  Очередной подход к калокубу. Хотя, возможно, шаблоны С++ и разворачиваются в static inline, ХЗ. Но мне как-то неприятно видеть цепепешный код применительно к микроконтроллерам, а также оформление инициализации периферии в виде общих функций (как в SPL или калокубе). Либо делать каждый раз явно, либо оформлять как макросы (на худой конец — static inline функции). Как-то попалась мне на другом форуме тема в духе "помогите, код не влазит в 1Кб tiny13". Я к тому времени для avr уже практически не писал, а когда писал, то делал это еще на С, потому ради интереса взял этот код и просто поменял расширение на cpp. Gcc добавил 20 байт, не знаю точно почему, для STM32 обычно не добавляет ничего. Затем я переписал все на С++, переделав в том числе и работу с портами через шаблонный класс. Добавилось еще 4 байта. Итого +24 байта, но то ли из-за того, что у меня была другая версия компилятора, то ли другие ключи, хотя в теме вроде их подбирали под минимальный размер, размер похудел примерно байт на 150 и в 1Кб уже влазило. Даже оптимизировать ничего не пришлось, хотя основной выигрыш должен быть именно там. А теперь сравни tiny13 и самый простой STM32...
|
|
|
|
|
Apr 19 2017, 07:43
|

Профессионал
    
Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831

|
Цитата(juvf @ Apr 19 2017, 10:21)  AHTOXА, Forger, Reflector - в ваших юСтайлах сколько строк дизасемблера занимает инит 4-х портов, и сколько переключение? если инит одного порта будет вызван 4 раза.... то в итоге... код будет вызываться один и тот же 4 раза. Но допустим, функция - зашли в неё и проинитили 4 порта, потом выставили на них значение - сколько машинных тактов будет крутиться код при ините и при переключении? А если не 4 пина, а 13 пинов и все на РА? Если делать выбор между: 1) читаемость кода, его сопровждаемость и переносимостью, 2) экономия FLASH вплоть до байтов, то я всегда буду выбирать 1-е. Но если проект упирается в стоимость контроллера (тысячные партии изделия, при низкой стоимости самого изделия) и мне лично это будет выгодно (банально, бонусы или доля продаж), то я конечно же буду ставить дешевый контроллер (STM8) и мучаться с его кривой средой и втаптыванием в него кода. Но в подобных проектах код обычно предельно простой - написал и забыл. Однако, я всегда старался избегать подобных проектов. © "Не хочу, не буду" ))) Поэтому предпочитаю брать подходящий контроллер с достаточным объемом flash и озу, а код писать так, как мне удобно, поскольку сопровождать этот код мне же и придется. А экономить чужие деньги уже давно разучился, точнее, отучили более опытные товарищи )))
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Apr 19 2017, 07:46
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
А у меня самый тонкий и короткий код. CODE /*! GPIO Mode Type */ typedef enum { MD_IN, //!< Input * MD_GO, //!< General purpose output MD_AF, //!< Alternate function MD_AN //!< Analog } GPIO_MODE_t;
/*! GPIO Output Type */ typedef enum { OT_PP, //!< Output push-pull* OT_OD //!< Output open-drain } GPIO_OTYPE_t;
/*! GPIO Output Speed Type */ typedef enum { SP_LO, //!< 2 MHz Low speed * SP_ME, //!< 10 MHz Medium speed // 2 MHz SP_HI = 3 //!< 50 MHz High speed } GPIO_OSPEED_t;
/*! GPIO Pull-Up_Pull-Down Type */ typedef enum { PL_NP, //!< No pull-up, pull-down * PL_PU, //!< Pull-up PL_PD //!< Pull-down // Reserved } GPIO_PUPD_t;
/*! GPIO Alternate Functions (4 bits) The specific alternate function assignments for each pin are detailed in the device datasheet */ typedef enum { AF_00, //!< AF0 * AF_01, //!< AF1 AF_02, //!< AF2 AF_03, //!< AF3 AF_04, //!< AF4 AF_05, //!< AF5 AF_06, //!< AF6 AF_07, //!< AF7 AF_08, //!< AF8 AF_09, //!< AF9 AF_10, //!< AF10 AF_11, //!< AF11 AF_12, //!< AF12 AF_13, //!< AF13 AF_14, //!< AF14 AF_15 //!< AF15 } GPIO_AFLH_t;
/*!**************************************************************************** @brief Port configuration @details Конфигурация портов целиком @param PORT - имя порта (A..G) @param MDx, OTx, SPx, PLx, AFx - режимы x-битов порта @note Default: MD_IN, OT_PP, SP_02, PL_NP, AF_00 */ #define GPIO_CONF(PORT, \ MD00, OT00, SP00, PL00, AF00, \ MD01, OT01, SP01, PL01, AF01, \ MD02, OT02, SP02, PL02, AF02, \ MD03, OT03, SP03, PL03, AF03, \ MD04, OT04, SP04, PL04, AF04, \ MD05, OT05, SP05, PL05, AF05, \ MD06, OT06, SP06, PL06, AF06, \ MD07, OT07, SP07, PL07, AF07, \ MD08, OT08, SP08, PL08, AF08, \ MD09, OT09, SP09, PL09, AF09, \ MD10, OT10, SP10, PL10, AF10, \ MD11, OT11, SP11, PL11, AF11, \ MD12, OT12, SP12, PL12, AF12, \ MD13, OT13, SP13, PL13, AF13, \ MD14, OT14, SP14, PL14, AF14, \ MD15, OT15, SP15, PL15, AF15); \ GPIO##PORT->MODER = ( \ MD00 << 0 | MD01 << 2 | MD02 << 4 | MD03 << 6 | \ MD04 << 8 | MD05 << 10 | MD06 << 12 | MD07 << 14 | \ MD08 << 16 | MD09 << 18 | MD10 << 20 | MD11 << 22 | \ MD12 << 24 | MD13 << 26 | MD14 << 28 | (uint32_t)MD15 << 30); \ GPIO##PORT->OTYPER = ( \ OT00 << 0 | OT01 << 1 | OT02 << 2 | OT03 << 3 | \ OT04 << 4 | OT05 << 5 | OT06 << 6 | OT07 << 7 | \ OT08 << 8 | OT09 << 9 | OT10 << 10 | OT11 << 11 | \ OT12 << 12 | OT13 << 13 | OT14 << 14 | (uint32_t)OT15 << 15); \ GPIO##PORT->OSPEEDR = ( \ SP00 << 0 | SP01 << 2 | SP02 << 4 | SP03 << 6 | \ SP04 << 8 | SP05 << 10 | SP06 << 12 | SP07 << 14 | \ SP08 << 16 | SP09 << 18 | SP10 << 20 | SP11 << 22 | \ SP12 << 24 | SP13 << 26 | SP14 << 28 | (uint32_t)SP15 << 30); \ GPIO##PORT->PUPDR = ( \ PL00 << 0 | PL01 << 2 | PL02 << 4 | PL03 << 6 | \ PL04 << 8 | PL05 << 10 | PL06 << 12 | PL07 << 14 | \ PL08 << 16 | PL09 << 18 | PL10 << 20 | PL11 << 22 | \ PL12 << 24 | PL13 << 26 | PL14 << 28 | (uint32_t)PL15 << 30); \ GPIO##PORT->AFR[0] = ( \ AF00 << 0 | AF01 << 4 | AF02 << 8 | AF03 << 12 | \ AF04 << 16 | AF05 << 20 | AF06 << 24 | (uint32_t)AF07 << 28); \ GPIO##PORT->AFR[1] = ( \ AF08 << 0 | AF09 << 4 | AF10 << 8 | AF11 << 12 | \ AF12 << 16 | AF13 << 20 | AF14 << 24 | (uint32_t)AF15 << 28);
/*!**************************************************************************** @brief Port configuration lock @details Зафиксировать конфигурацию портов @param PORT - имя порта (A..G) @param BITS - биты порта, которые нужно зафиксировать (0xffff - все) @return @note */ #define GPIO_LOCK(PORT, BITS); \ GPIO##PORT->LCKR = 0x00010000 | BITS; \ GPIO##PORT->LCKR = 0x00000000 | BITS; \ GPIO##PORT->LCKR = 0x00010000 | BITS; \ GPIO##PORT->LCKR;
Пример использования. CODE /*!**************************************************************************** @brief GPIO initialize @note */ inline void GPIO_init(void) { GPIO_CONF(A, MD_AN, OT_PP, SP_LO, PL_NP, AF_00, // 0: Wake-Up Button MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 1 MD_AN, OT_PP, SP_LO, PL_NP, AF_00, // 2: ADC1_IN3 MD_AF, OT_PP, SP_ME, PL_NP, AF_01, // 3: TIM2_CH4 MD_AN, OT_PP, SP_LO, PL_NP, AF_00, // 4: DAC1_OUT1 MD_AN, OT_PP, SP_LO, PL_NP, AF_00, // 5: DAC1_OUT2 MD_AN, OT_PP, SP_LO, PL_NP, AF_00, // 6: ADC2_IN3 MD_IN, OT_PP, SP_ME, PL_NP, AF_02, // 7: MD_AF, OT_PP, SP_ME, PL_NP, AF_00, // 8: MCO MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 9 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 10 MD_AF, OT_PP, SP_HI, PL_NP, AF_14, // 11: USB_DM MD_AF, OT_PP, SP_HI, PL_NP, AF_14, // 12: USB_DP MD_AF, OT_PP, SP_ME, PL_NP, AF_00, // 13: SWDIO MD_AF, OT_PP, SP_ME, PL_NP, AF_00, // 14: SWCLK MD_IN, OT_PP, SP_LO, PL_NP, AF_00); // 15
// PB3 - SWO после сброса GPIO_CONF(B, MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 0 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 1 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 2 MD_IN, OT_PP, SP_ME, PL_NP, AF_00, // 3: SWO MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 4 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 5 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 6: MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 7: MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 8 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 9 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 10 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 11 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 12 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 13 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 14 MD_AF, OT_PP, SP_ME, PL_NP, AF_01); // 15: TIM15_CH2
GPIO_CONF(C, MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 0 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 1 MD_AF, OT_PP, SP_HI, PL_NP, AF_03, // 2: COMP7_OUT MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 3 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 4 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 5 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 6 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 7 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 8 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 9 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 10 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 11 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 12 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 13 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 14 MD_IN, OT_PP, SP_LO, PL_NP, AF_00); // 15
GPIOE->ODR = 0x0000; GPIO_CONF(E, MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 0 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 1 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 2 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 3 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 4 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 5 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 6 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 7 MD_GO, OT_PP, SP_ME, PL_NP, AF_00, // 8: NW MD_GO, OT_PP, SP_ME, PL_NP, AF_00, // 9: NN MD_GO, OT_PP, SP_ME, PL_NP, AF_00, // 10: NE MD_GO, OT_PP, SP_ME, PL_NP, AF_00, // 11: EE MD_GO, OT_PP, SP_ME, PL_NP, AF_00, // 12: SE MD_GO, OT_PP, SP_ME, PL_NP, AF_00, // 13: SS MD_GO, OT_PP, SP_ME, PL_NP, AF_00, // 14: SW MD_GO, OT_PP, SP_ME, PL_NP, AF_00); // 15: WW
GPIO_CONF(F, MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 0 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 1 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 2 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 3 MD_AF, OT_PP, SP_HI, PL_NP, AF_02, // 4: COMP1_OUT MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 5 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 6 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 7 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 8 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 9 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 10 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 11 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 12 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 13 MD_IN, OT_PP, SP_LO, PL_NP, AF_00, // 14 MD_IN, OT_PP, SP_LO, PL_NP, AF_00); // 15
/* Заблокировать конфигурацию для всех битов портов */ GPIO_LOCK(A, 0xFFFF); GPIO_LOCK(B, 0xFFFF); GPIO_LOCK(C, 0xFFFF); GPIO_LOCK(E, 0xFFFF); GPIO_LOCK(F, 0xFFFF); }
|
|
|
|
|
Apr 19 2017, 07:59
|
Участник

Группа: Участник
Сообщений: 48
Регистрация: 15-07-06
Пользователь №: 18 836

|
Цитата(SasaVitebsk @ Apr 19 2017, 09:16)  И что? Ещё раз повторяю. Совершенно бессмысленно. Приведу пример. Только что делал модификацию прибора. Изменилось количество каналов, полностью переразведена плата, на первой версии стояла отдельный МК который управлял клавой, светодиодами пищалкой и подключен был по I2C. В новой версии применили 595/165 SPI и отдельный таймер на пищалку. Отладку нового проекта производил на старой плате. При переносе старый файл local.h переименовал в local_v1.h. Добавил файл local_v2.h с данными новой платы, и написал local.h где переключатель хидеров. В main.h ввёл макрос выбора версии платы. Написал один файл обработки новой клавы и внёс некоторые изменения в инициализацию - прерывания (так как поменялись таймеры каналы spi и прочее). Думаю всего изменения коснулись строчек 10. У меня в main.h указываются дефайны типа spi_dataflash/ spi_adc. И всё! Проект компилится для двух версий плат. Чем поможет конструкция "PA5::On()"? По всему проекту её ловить? И что такое On? Я сейчас использую двухцветные светодиоды. Очень удобно Конструкция проще, информативность выше. И что даст ко всему этому PA5::On()? То есть нужен ещё слой, чтобы PA5::On превратился в удобоваримое powerled(red) или adc_cs_on. Я сейчас не о стилистике написания, поймите. Пусть стилистика будет ваша. Но применять по тексту основной программы обезличенные данные аппаратных ресурсов - тоже, что писать reg = 5. Это также недопустимо! Ни одной константы по тексту программы. Итак над этой хренью появляется ещё один файл абстракций. Итого 2. А у меня он 1. Сразу аппаратура в абстракцию. Зачем искать PA5::On() по всему проекту? И почему PA5? Дай нормальное имя: Код Pin<'A', 5> powerled; ... powerled.On(); Если у тебя двухцветные светодиод, то с парой пинов ты все равно же как-то работаешь. Покажи как, тогда сравним.
|
|
|
|
|
Apr 19 2017, 08:06
|

Профессионал
    
Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831

|
Цитата(ViKo @ Apr 19 2017, 10:59)  Необъективно судите... Извините за прямоту, но, чтобы понять ваш код, пришлось его несколько раз пролистать сверху донизу. После некоторого перерыва заново понять, что там и как делается, придется делать то же самое - листать и ломать голову, что тут и как работает. Я считаю очень объективными первые впечатления, которые создал процесс изучения нового кода. Цитата(ViKo @ Apr 19 2017, 10:59)  Минимальный размер кода. Меньше просто некуда. Может я отстал от поезда, но объясните: какой смысл такой "экономии на спичках"?
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Apr 19 2017, 08:11
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Цитата(Forger @ Apr 19 2017, 11:06)  Может я отстал от поезда, но объясните: какой смысл такой "экономии на спичках"? Мы тут о крутизне спорим, да? Так в чем смысл городить классы-шмассы, тратить время, напрягать мозг, если результат хуже, чем стандартное применение дефайнов? В чем сила, брат? С++? Явно не для этого места. Как обучающий пример, сгодится. Цитата(Forger @ Apr 19 2017, 11:06)  Необъективно? Чтобы понять ваш код, пришлось его несколько раз пролистать сверху донизу. Чтобы после некоторого перерыва заново понять, что там и как делается, придется делать то же самое - листать и ломать голову, что тут и как работает. А ваш пример я и листать не стал. Все равно не осилю.  Да и зачем? У меня в разных файлах определение и применение. Открываю в двух окнах в Notepad++. Все вижу сразу.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|