|
|
  |
Начало работы with scmRTOS, Несколько вопросиков |
|
|
|
Mar 21 2011, 06:27
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(a9d @ Mar 18 2011, 21:40)  Отсылать самому себе сигнал очень удобно в следующей ситуации. Есть два процесса. Процесс 1 производит опрос, Процесс 2 управляющий. При старте системы Процесс 1 в начале цикла ожидает флаг, Процесс 2 устанавливает флаг тем самым разрешая опрос. После успешного опроса Процесс 1 выставляет сам для себя флаг, если опрос был не успешен то он отправляет месседж с ошибкой и не выставляет флаг. Тем самым Процесс 1 в случае ошибке уснет, пока Процесс 2 не решит, что с ним делать. Интересовало насколько это корректно. Не очень понял, какой флаг имеется в виду. Флаг события (TEventFlag) или внутренняя переменная message NonEmpty? Лучше такие вещи пояснять на примере псевдокода. Цитата(a9d @ Mar 18 2011, 21:40)  Насчет месседжей я спрашивал другое. Если я использую is_non_empty(), то при получении сообщения я не нашел места где флаг сбрасывается. А значит нужно вызывать сброс вручную? Получение сообщения производится в функции wait(). Там же и обрабатывается внутренняя переменная (NonEmpty). Эта переменная устанавливается при передаче только если в этот момент никто не ждёт сообщения (тогда при первой попытке встать на ожидание процесс "увидит", что сообщение уже лежит, и его можно использовать). Если же есть ожидающие процессы, то NonEmpty не устанавливается, т.к. в этом нет необходимости - просто процесс, который находился в ожидании, будет переведён в готовые к выполнению. Следует иметь в виду, что внутренняя переменная NonEmpty - это не флаг-признак наличия сообщения. Это именно внутренняя переменная, используемая потрохами сервиса для своих служебных целей, поэтому ориентироваться на неё не следует. Работать нужно с интерфейсом - открытыми функциями-членами. Если приём сообщения осуществляется с помощью is_non_empty() (что правильнее назвать не приёмом, а проверкой наличия), то, конечно, и сброс состояния тоже придётся делать вручную. Цитата(a9d @ Mar 18 2011, 21:40)  А в случае с wait() как я понимаю флаг будет сброшен сам и вызове reset() нет необходимости? В документации не написано в каких ситуациях флаг сбрасывается. На этот вопрос уже нашел ответ. Флаг сбрасывается. В документации описано функционирование с точки зрения интерфейса сервиса. А работа с NonEmpty - это уже детали реализации, они, конечно, как обычно, не являются предметом документирования. Детали реализации вообще могут меняться вполне произвольно, при сохранении интерфейса класса и логики его работы работы, поэтому ориентироваться на них не надо.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Mar 21 2011, 14:02
|
Местный
  
Группа: Участник
Сообщений: 312
Регистрация: 9-04-10
Пользователь №: 56 532

|
Код 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); }
|
|
|
|
|
Mar 22 2011, 06:25
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Я бы сделал так. Код 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; } } } } Цитата(a9d @ Mar 21 2011, 20:02)  Это получается более корректно и правильно написать так Код while(1) { if(msg.wait(1)) { buf=msg; ..................... } .......................... } Конечно. Это и есть штатный и основной способ использования. Ждём сообщения, дождались - обрабатываем. А is_non_empty(), reset() - это вспомогательные фукнции
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Mar 22 2011, 07:15
|
Местный
  
Группа: Участник
Сообщений: 312
Регистрация: 9-04-10
Пользователь №: 56 532

|
Код Proc2 //рабочий { while(1) { flg.wait(); while(1) { if(Opros) { .......... Sleep(1); } else { err=1; //сообщаем номер ошибки err.send(); //отправляем месседж break; } } } } Этот код получше. До такого я не додумался))
|
|
|
|
|
Sep 6 2011, 01:43
|

Местный
  
Группа: Свой
Сообщений: 327
Регистрация: 24-06-06
Из: Томск
Пользователь №: 18 328

|
Цитата(a9d @ Sep 6 2011, 01:20)  Через неделю планирую начать проект на STM32W Под STM32 есть порт версии 3.10. А как обстоят дела с версией 4.0 ? Порт по идее есть, но он стабилен? Имеет смысл его использовать в проекте? scmRTOS версии 4 и порт для Cortex-M3 (без разницы какой конкретно контроллер) под нее вполне стабильны. Здесь можно скачать scmRTOS и порт версии 4. Здесь и здесь документация.
|
|
|
|
|
Sep 11 2011, 19:13
|
Местный
  
Группа: Участник
Сообщений: 312
Регистрация: 9-04-10
Пользователь №: 56 532

|
Заметил, что в 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 (;;); } Хотя проект рабочий и я вижу как плата мигает диодами.
Сообщение отредактировал a9d - Sep 11 2011, 21:45
|
|
|
|
|
Sep 12 2011, 02:58
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(a9d @ Sep 12 2011, 01:13)  Заметил, что в 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. Про отладку не подскажу, - не знаю.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Sep 12 2011, 16:37
|
Местный
  
Группа: Участник
Сообщений: 312
Регистрация: 9-04-10
Пользователь №: 56 532

|
Ну почему-же, будет работать. Там немного нужно поправить названия функций. С вашей версией выходит Код 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 Но один фиг отладчик не работает.
|
|
|
|
|
Sep 12 2011, 18:54
|
Местный
  
Группа: Участник
Сообщений: 312
Регистрация: 9-04-10
Пользователь №: 56 532

|
Уже вышла версия 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"
|
|
|
|
|
Sep 12 2011, 20:05
|
Местный
  
Группа: Участник
Сообщений: 312
Регистрация: 9-04-10
Пользователь №: 56 532

|
Начал копаться в 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. Отсюда вопрос. Что это такое?
Сообщение отредактировал a9d - Sep 12 2011, 20:29
|
|
|
|
|
Sep 13 2011, 02:42
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(a9d @ Sep 13 2011, 00:54)  Уже вышла версия 3.5. И? Есть там вызов конструкторов? Цитата(a9d @ Sep 13 2011, 00:54)  #define OS_INTERRUPT extern "C" Попробуйте просто написать extern "C" перед функцией обработчика прерывания. Цитата(a9d @ Sep 13 2011, 02:05)  От таких конструкций мозг закипает. Такое намного проще и удобней разбить на несколько команд. При этом возрастет читабельность. Так разбейте, какие проблемы? Примеры - это же не догма, а лишь руководство к действию  Цитата(a9d @ Sep 13 2011, 02:05)  Также в этом файле нашел следующее Код #if (!defined STM32F10X_LD_VL) && (!defined STM32F10X_MD_VL) ... Также у value line потолок 24 Mhz. Отсюда вопрос. Что это такое? Видите первую строчку? Эта часть - не для value line.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
  |
3 чел. читают эту тему (гостей: 3, скрытых пользователей: 0)
Пользователей: 0
|
|
|