a9d 0 18 марта, 2011 Опубликовано 18 марта, 2011 (изменено) · Жалоба Мне не нужны старые данные. Поэтому вариант с затиранием подходит. Интересовало насколько это корректно. Отсылать самому себе сигнал очень удобно в следующей ситуации. Есть два процесса. Процесс 1 производит опрос, Процесс 2 управляющий. При старте системы Процесс 1 в начале цикла ожидает флаг, Процесс 2 устанавливает флаг тем самым разрешая опрос. После успешного опроса Процесс 1 выставляет сам для себя флаг, если опрос был не успешен то он отправляет месседж с ошибкой и не выставляет флаг. Тем самым Процесс 1 в случае ошибке уснет, пока Процесс 2 не решит, что с ним делать. Интересовало насколько это корректно. Насчет месседжей я спрашивал другое. Если я использую is_non_empty(), то при получении сообщения я не нашел места где флаг сбрасывается. А значит нужно вызывать сброс вручную? А в случае с wait() как я понимаю флаг будет сброшен сам и вызове reset() нет необходимости? В документации не написано в каких ситуациях флаг сбрасывается. На этот вопрос уже нашел ответ. Флаг сбрасывается. Изменено 18 марта, 2011 пользователем a9d Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 53 21 марта, 2011 Опубликовано 21 марта, 2011 · Жалоба Отсылать самому себе сигнал очень удобно в следующей ситуации. Есть два процесса. Процесс 1 производит опрос, Процесс 2 управляющий. При старте системы Процесс 1 в начале цикла ожидает флаг, Процесс 2 устанавливает флаг тем самым разрешая опрос. После успешного опроса Процесс 1 выставляет сам для себя флаг, если опрос был не успешен то он отправляет месседж с ошибкой и не выставляет флаг. Тем самым Процесс 1 в случае ошибке уснет, пока Процесс 2 не решит, что с ним делать. Интересовало насколько это корректно. Не очень понял, какой флаг имеется в виду. Флаг события (TEventFlag) или внутренняя переменная message NonEmpty? Лучше такие вещи пояснять на примере псевдокода. Насчет месседжей я спрашивал другое. Если я использую is_non_empty(), то при получении сообщения я не нашел места где флаг сбрасывается. А значит нужно вызывать сброс вручную? Получение сообщения производится в функции wait(). Там же и обрабатывается внутренняя переменная (NonEmpty). Эта переменная устанавливается при передаче только если в этот момент никто не ждёт сообщения (тогда при первой попытке встать на ожидание процесс "увидит", что сообщение уже лежит, и его можно использовать). Если же есть ожидающие процессы, то NonEmpty не устанавливается, т.к. в этом нет необходимости - просто процесс, который находился в ожидании, будет переведён в готовые к выполнению. Следует иметь в виду, что внутренняя переменная NonEmpty - это не флаг-признак наличия сообщения. Это именно внутренняя переменная, используемая потрохами сервиса для своих служебных целей, поэтому ориентироваться на неё не следует. Работать нужно с интерфейсом - открытыми функциями-членами. Если приём сообщения осуществляется с помощью is_non_empty() (что правильнее назвать не приёмом, а проверкой наличия), то, конечно, и сброс состояния тоже придётся делать вручную. А в случае с wait() как я понимаю флаг будет сброшен сам и вызове reset() нет необходимости? В документации не написано в каких ситуациях флаг сбрасывается. На этот вопрос уже нашел ответ. Флаг сбрасывается. В документации описано функционирование с точки зрения интерфейса сервиса. А работа с NonEmpty - это уже детали реализации, они, конечно, как обычно, не являются предметом документирования. Детали реализации вообще могут меняться вполне произвольно, при сохранении интерфейса класса и логики его работы работы, поэтому ориентироваться на них не надо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
a9d 0 21 марта, 2011 Опубликовано 21 марта, 2011 · Жалоба OS::TEventFlag flg; OS::message<char> err; .................... ................... Proc1 //управляющий { flg.Signal(); while(1) { err.wait(); //ждем сообщение об ошибке ............ ............ } } Proc2 //рабочий { while(1) { flg.wait(); if(Opros) { .......... flg.Signal(); .......... Sleep(1); } else { err=1; //сообщаем номер ошибки err.send(); //отправляем месседж //флаг не взведен и при следующем проходе процесс уснет } } } Если требуется конечный автомат, то можно флаг заменить на месседж. Теперь про месседжи. У меня один процесс главный он через сообщения рассылает другим процессам команды. Процессы которые принимают команды не должны работать постоянно. Это получается более корректно и правильно написать так while(1) { if(msg.wait(1)) { buf=msg; ..................... } .......................... } Чем так while(1) { if(msg.is_non_empty()) { buf=msg; msg.reset(); ................ } ................................. Sleep(1); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 53 22 марта, 2011 Опубликовано 22 марта, 2011 · Жалоба Я бы сделал так. OS::TEventFlag flg; OS::message<char> err; Proc1 //управляющий { flg.Signal(); while(1) { err.wait(); //ждем сообщение об ошибке ............ ............ } } Proc2 //рабочий { while(1) { flg.wait(); while(1) { if(Opros) { .......... Sleep(1); } else { err=1; //сообщаем номер ошибки err.send(); //отправляем месседж break; } } } } Это получается более корректно и правильно написать так while(1) { if(msg.wait(1)) { buf=msg; ..................... } .......................... } Конечно. Это и есть штатный и основной способ использования. Ждём сообщения, дождались - обрабатываем. А is_non_empty(), reset() - это вспомогательные фукнции Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
a9d 0 22 марта, 2011 Опубликовано 22 марта, 2011 · Жалоба Proc2 //рабочий { while(1) { flg.wait(); while(1) { if(Opros) { .......... Sleep(1); } else { err=1; //сообщаем номер ошибки err.send(); //отправляем месседж break; } } } } Этот код получше. До такого я не додумался)) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
a9d 0 5 сентября, 2011 Опубликовано 5 сентября, 2011 · Жалоба Через неделю планирую начать проект на STM32W Под STM32 есть порт версии 3.10. А как обстоят дела с версией 4.0 ? Порт по идее есть, но он стабилен? Имеет смысл его использовать в проекте? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ashr 0 6 сентября, 2011 Опубликовано 6 сентября, 2011 · Жалоба Через неделю планирую начать проект на STM32W Под STM32 есть порт версии 3.10. А как обстоят дела с версией 4.0 ? Порт по идее есть, но он стабилен? Имеет смысл его использовать в проекте? scmRTOS версии 4 и порт для Cortex-M3 (без разницы какой конкретно контроллер) под нее вполне стабильны. Здесь можно скачать scmRTOS и порт версии 4. Здесь и здесь документация. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
a9d 0 6 сентября, 2011 Опубликовано 6 сентября, 2011 (изменено) · Жалоба За доку на кортексы спасибо. О ее существовании даже не знал. Изменено 6 сентября, 2011 пользователем a9d Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
a9d 0 11 сентября, 2011 Опубликовано 11 сентября, 2011 (изменено) · Жалоба Заметил, что в 4 версии для cortex-m3 есть файлик startup.c. Хотя в тоже время имеется "\STM32\STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm" тоже самое только на ассемблере. Почему не используется ассемблерная версия? Также в примерах содержаться файлы core_cm3.h и stm32f10x.h которые тоже содержаться STM32F10x_StdPeriph_Lib_V3.5.0. Зачем их добавлять в примеры? Настроил отладчик ST-Link (использую дисковери) как написано в статье http://we.easyelectronics.ru/STM32/otladka...eclipsegcc.html . В проектах без ОС отладка работает. А вот с ОС неработает. Зависает здесь void Reset_Handler(void) { __Init_Data(); main(); } или void Default_Handler(void) { for (;;); } Хотя проект рабочий и я вижу как плата мигает диодами. Изменено 11 сентября, 2011 пользователем a9d Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 15 12 сентября, 2011 Опубликовано 12 сентября, 2011 · Жалоба Заметил, что в 4 версии для cortex-m3 есть файлик startup.c. Хотя в тоже время имеется "\STM32\STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm" тоже самое только на ассемблере. Где "имеется"? :) Дело в том, что в то время, когда создавался порт, в составе CMSIS не было ассемблерных стартапов. Да и нынешние - не будут работать с C++. К тому же, версии библиотек от ST имеют нехорошую тенденцию меняться в самый неподходящий момент. Поэтому в состав примеров были включены нужные для работы примеров файлы. Обратите внимание, для собственно ОС эти файлы не нужны, порт - универсален для любых Cortex-M3. Про отладку не подскажу, - не знаю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
a9d 0 12 сентября, 2011 Опубликовано 12 сентября, 2011 · Жалоба Ну почему-же, будет работать. Там немного нужно поправить названия функций. С вашей версией выходит Invoking: ARM Sourcery Windows GNU Print Size arm-none-eabi-size --format=berkeley scmRTOS_stm32v3.elf text data bss dec hex filename 1872 4 1680 3556 de4 scmRTOS_stm32v3.elf Finished building: scmRTOS_stm32v3.siz с версией от STM Invoking: ARM Sourcery Windows GNU Print Size arm-none-eabi-size --format=berkeley scmRTOS_stm32v3.elf text data bss dec hex filename 1912 4 1680 3596 e0c scmRTOS_stm32v3.elf Finished building: scmRTOS_stm32v3.siz Но один фиг отладчик не работает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 15 12 сентября, 2011 Опубликовано 12 сентября, 2011 · Жалоба Компилируется != работает:) В том варианте startup_stm32f10x_xx.s, что есть у меня (V3.3.0), не вызываются конструкторы глобальных объектов. Хотя может сейчас уже поправили... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
a9d 0 12 сентября, 2011 Опубликовано 12 сентября, 2011 · Жалоба Уже вышла версия 3.5. Также нашел объяснение с отладкой Brain13 Aug 12 2011, 08:23 StAlexy, у Вас в коде полная мешанина: разрешение прерывания SPI, инициализация TIM, разрешение прерывания TIM, инициализация SPI. Так делать нехорошо, когда проект вырастет сложно будет разобраться. Если процессор зависает, но в обработчик не заходит, то скорее всего прерывание вызывается, но обработчика просто нет, поэтому он виснет в Default_Handler, которы по стандарту представляет из себя бесконечный цикл. Если у вас смесь С и С++. То необходимо добавить extern "C" при обьявлении обработчика, то есть: Код extern "C" void TIM2_IRQHandler(void); Я на такое тоже натыкался, теперь все обработчики так описываю. Посмотрите регистр статуса SPI, биты запроса прерывания выставлены? У Вас есть возможность узнать где зависла программа? PS: уход от проблемы - не решение, разберитесь с прерываниями, без них - тяжко. Сделал так но результата не дало. #define OS_INTERRUPT extern "C" Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
a9d 0 12 сентября, 2011 Опубликовано 12 сентября, 2011 (изменено) · Жалоба Начал копаться в sysinit.cpp. Читабельность оставляет желать лучшего. RCC->CFGR = (RCC->CFGR & ~(RCC_CFGR_HPRE | RCC_CFGR_PPRE2 | RCC_CFGR_PPRE1 | RCC_CFGR_ADCPRE)) | RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PPRE2_DIV1 | RCC_CFGR_PPRE1_DIV2 | RCC_CFGR_ADCPRE_DIV6; От таких конструкций мозг закипает. Такое намного проще и удобней разбить на несколько команд. При этом возрастет читабельность. Также в этом файле нашел следующее #if (!defined STM32F10X_LD_VL) && (!defined STM32F10X_MD_VL) // Enable Prefetch Buffer FLASH->ACR |= FLASH_ACR_PRFTBE; // Flash 2 wait state (if freq in 24..48 MHz range - 1WS.) FLASH->ACR = (FLASH->ACR & ~FLASH_ACR_LATENCY) | FLASH_ACR_LATENCY_2; #endif Но в ACR есть всего один бит и эта конструкция его никак не трогает. Также у value line потолок 24 Mhz. Отсюда вопрос. Что это такое? Изменено 12 сентября, 2011 пользователем a9d Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 15 13 сентября, 2011 Опубликовано 13 сентября, 2011 · Жалоба Уже вышла версия 3.5. И? Есть там вызов конструкторов? #define OS_INTERRUPT extern "C" Попробуйте просто написать extern "C" перед функцией обработчика прерывания. От таких конструкций мозг закипает. Такое намного проще и удобней разбить на несколько команд. При этом возрастет читабельность. Так разбейте, какие проблемы? Примеры - это же не догма, а лишь руководство к действию :) Также в этом файле нашел следующее #if (!defined STM32F10X_LD_VL) && (!defined STM32F10X_MD_VL) ... Также у value line потолок 24 Mhz. Отсюда вопрос. Что это такое? Видите первую строчку? Эта часть - не для value line. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться