|
|
  |
scmRtos для медных чайников |
|
|
|
Jan 24 2013, 05:12
|
Участник

Группа: Участник
Сообщений: 25
Регистрация: 18-03-11
Пользователь №: 63 690

|
Цитата(AHTOXA @ Jan 22 2013, 12:20)  ЗЫ. Если уж совсем не пойдёт, и вы боитесь самодельных сборок, то есть Sourcery CodeBench Lite, бывшая sourcery g++ lite. (качать ARM EABI Release). вчера собрал arm-none-eabi 4.7.2. проект 1-EVENT собирается без шаманств с линкер скриптом и раьотает. собрал свой рабочий проект - вылетел в HardFault. поставил на закачку CodeBench Lite. посмотрим как он себя поведёт.
Сообщение отредактировал dezna - Jan 24 2013, 09:12
|
|
|
|
|
Dec 7 2015, 14:43
|

Гуру
     
Группа: Свой
Сообщений: 2 429
Регистрация: 30-11-05
Из: Ижевск
Пользователь №: 11 606

|
Вопрос больше касается С++. Делаю первый проект на scmRTOS и на С++ еще никогда не писал. Накидал 3 процесса в одном мейн файле. Все работают как надо. Начал раскидывать процесессы по отдельным файлам. Я привык раскидывать процессы по своим c и h файлам. Тут произошло что-то странное. Начал обрабатываться только один процесс и девайс как будто перезагружается раз в секунду. Хотя у меня watchdog даже не задействован. файл thread_lcd.cpp Код #include "thread_lcd.h"
template<> void TProc3::exec(); TProc3 Proc3; //--------------------------------------------------------------------------- namespace OS {
template<> void TProc3::exec() { uint8_t i; sleep(1000); lcd_clear(); lcd_goto(1,0); for(;;) { lcd_goto(1,0); xprintf("hello %d", i++); sleep(1000); } } // TProc3::exec()
} // namespace OS файл thread_lcd.h Код #ifndef _THREAD_LCD_H_ #define _THREAD_LCD_H_ #include <scmRTOS.h> #include "hardware/hardware.h" typedef OS::process<OS::pr2, 120> TProc3; #endif Снова перетащил теже исходники в один файл и работает как надо.
|
|
|
|
|
Dec 10 2015, 06:18
|

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

|
Цитата(dxp @ Dec 10 2015, 10:30)  Ещё. Код исполняемой функции процесса я не помещаю в пространство имён OS - ведь это уже код приложения, ему нечего делать в OS. Вообще, при написании прикладного кода ничего не нужно помещать в OS, это не "территория" проекта. GCC на такое ругается: Код error: specialization of 'template in different namespace [-fpermissive]
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Dec 10 2015, 09:59
|

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

|
QUOTE (AHTOXA @ Dec 10 2015, 12:18)  GCC на такое ругается: CODE error: specialization of 'template in different namespace [-fpermissive] А, это не тот ли самый косяк застарелый? CODE namespace OS { #ifndef __GNUC__ // avoid GCC bug ( http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15867 ) template<> void TIdleProc::exec(); #endif
TIdleProc IdleProc; }
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Dec 10 2015, 11:32
|

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

|
Цитата(dxp @ Dec 10 2015, 14:59)  А, это не тот ли самый косяк застарелый? Не, то было другое. Там GCC давал предупреждение "redundant redeclaration". А тут, как мне кажется, всё верно. Если прототип функции объявлен в пространстве имён OS, то и реализация должна быть там же. Иначе это будет реализация какой-то другой функции. ЗЫ. Кстати, баг тот уже давно исправлен, можно вычистить этот кусочек.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Dec 10 2015, 12:16
|

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

|
Цитата(Сергей Борщ @ Dec 10 2015, 16:53)  И специализацию exec мы пишем не для OS::process<тра-та-та>, а для TProc3, разве не так? Так TProc3 - это просто typedef для OS::process<тра-та-та>. Алиас, так сказать. По сути мы имеем Код namespace OS { template <> void OS::process<OS::pr0, 3600>::exec() { ...
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Dec 10 2015, 15:23
|

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

|
QUOTE (AHTOXA @ Dec 10 2015, 18:16)  Так TProc3 - это просто typedef для OS::process<тра-та-та>. Алиас, так сказать. По сути мы имеем CODE namespace OS { template <> void OS::process<OS::pr0, 3600>::exec() { ... OS::process<тра-та-та> в том случае - это уже инстанцирование шаблона, т.е. рожается конкретный тип из параметрического, и этот конкретный тип уже объявлен не в OS, а в глобальном. И это правильно. Иначе получалось бы, что все производные типы гвоздями были бы прибиты к пространству имён базового типа.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Dec 11 2015, 01:07
|

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

|
Цитата(dxp @ Dec 10 2015, 20:23)  OS::process<тра-та-та> в том случае - это уже инстанцирование шаблона, т.е. рожается конкретный тип из параметрического, и этот конкретный тип уже объявлен не в OS, а в глобальном. GCC с тобой не согласен  Цитата(dxp @ Dec 10 2015, 20:23)  И это правильно. Иначе получалось бы, что все производные типы гвоздями были бы прибиты к пространству имён базового типа. Ты не путай наследование и инстанцирование. Если бы мы написали class SuperProcess : public OS::process<тра-та-та> - тогда да, это производный тип, и он уже не в пространстве имён OS. А в обсуждаемом случае мы всего лишь реализуем объявленную ранее функцию шаблона. И объявлена она в пространстве имён OS.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Dec 11 2015, 05:26
|

Гуру
     
Группа: Свой
Сообщений: 2 429
Регистрация: 30-11-05
Из: Ижевск
Пользователь №: 11 606

|
Между тем у меня появились некоторые подробности по поводу моей неудачной попытки разбить процессы по файлам. Проблема вовсе не в С++. Что-то новое пугает и сразу валишь на это.
Я не уточнял что это контроллер STM8L152. C scmRTOS не пошло, решил запустить операционку OSA. В обоих операционках три задачи: дисплей, rf модуль и пока просто мигание светодиодом. И увидел ту же самую периодическую перезагрузку. Я был очень удивлен. При включении добавил вывод на дисплей регистра источника сброса. Причиной сброса оказался WWDG (window watchdog). Удивился еще больше. WWDG никогда не использую, даже не понимаю как его применить. Ограничиваюсь обычным watchdog, но в этом проекте даже он еще не был задействован. Причина проблем оказалась в связке ADC+DMA+TIM. DMA складывает три канала АЦП в буфер. В прерывании по завершении заполнения буфера проводит рассчет. Прерывание происходит пару раз в секунду. Запрет прерываний не устраняет проблему. Как-будто DMA пишет туда куда не надо.
Дальше сделал вывод на дисплей переменной равной нулю при старте с инкрементом раз в секунду. При отключенном ADC+DMA+TIM переменная обновляется на дисплее, rf модуль принимает валидные данные, светодиод мигает. Включаю ADC+DMA+TIM. Переменная на дисплее по прежнему обновляется раз в секунду. Но она уже принимает случайные значения, обмен с rf модулем нарушен, а контроллер больше не перезагружается. Во всех экспериментах в буфере АЦП всегда складывались ожидаемые значения.
В случае с scmRTOS похоже просто повезло что проблема не вылезла сразу когда все задачи были в одном файле. Разбираться с этим пока не стал, пишу остальную часть кода.
|
|
|
|
|
Dec 11 2015, 05:48
|

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

|
Цитата(dxp @ Dec 11 2015, 07:47)  OS::process<тра-та-та> - это уже другой тип, чем OS::process. И его функция exec - это полная специализация этого нового типа. Обе эти новые сущности могут жить в любом пространстве имён, в т.ч. и в глобальном. Начнём с того, что типа OS::process не существует. Существует шаблонный класс (class template) OS::process. При его инстанцировании с конкретными параметрами появляется тип OS::process<конкретные параметры>. Он точно также находится в пространстве имён OS. (Смотри на его имя). Для удобства мы дали этому типу псевдоним TProc3. Думаю, что GCC делает правильно. Думаю также, что твой компилятор просто удовлетворяется префиксом OS:: в имени класса, и считает, что этого достаточно для того, чтобы реализация функции была в пространстве имён OS. Но наверняка по стандарту это не так (gcc довольно ревностно относится к соблюдению стандартов).
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Dec 11 2015, 08:10
|

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

|
QUOTE (AHTOXA @ Dec 11 2015, 11:48)  Начнём с того, что типа OS::process не существует. Существует шаблонный класс (class template) OS::process. При его инстанцировании с конкретными параметрами появляется тип OS::process<конкретные параметры>. Он точно также находится в пространстве имён OS. (Смотри на его имя). Для удобства мы дали этому типу псевдоним TProc3. Как это не существует? Это параметризованный тип. И OS:: в OS::process - это просто квалификация пути к этому типу. А конкретный тип, который от него рожается путём подстановки параметра шаблона, уже возникает в том пространстве имён, в котором он объявлен. По твоей логике получается, что в std::vector<int> my_vector; my_vector тоже находится в пространстве имён std. Так? QUOTE (uriy @ Dec 11 2015, 11:26)  Прерывание происходит пару раз в секунду. Запрет прерываний не устраняет проблему. Как-будто DMA пишет туда куда не надо. Т.е. подозреваете банальный (и подлый) memory overwrite при пересылке данных?
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|