Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: [STM32] Проблемы в примере evantflag с добавленными прерываниями.
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > scmRTOS
Legath
Проблема с следующем, после иницализации таймера и выставления приоритетов прерывания(делаю все через стандартную библиотеку переферии) исполнение улетает в DefaultHandler, хотя у меня определен свой обработчик прерывания. Соотвественно OS::Run не выполняется.

Код main.cpp

CODE
#include "stm32f10x.h"
#include <scmRTOS.h>
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_tim.h"
#include "misc.h"
//---------------------------------------------------------------------------
//
// Process types
//
typedef OS::process<OS::pr0, 300> TProc1;
typedef OS::process<OS::pr1, 300> TProc2;

//---------------------------------------------------------------------------
//
// Process objects
//
TProc1 Proc1;
TProc2 Proc2;



//---------------------------------------------------------------------------
//
// IO Pins
//
//---------------------------------------------------------------------------
//
// Event Flags to test
//
OS::TEventFlag ef;
OS::TEventFlag TimerEvent;



void init_leds()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_ResetBits(GPIOC, GPIO_Pin_8);
GPIO_ResetBits(GPIOC, GPIO_Pin_9);
}
void timer_init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_TimeBaseInitTypeDef Init_info;
TIM_DeInit(TIM2);
/* TIM_Period * (TIM_Prescaler +1)
* Time=_______________________________
* 24МГц
*
* TIM_Prescaler=1199
* TIM_Period=20000
*/
Init_info.TIM_Prescaler=1199;
Init_info.TIM_Period=20000;
Init_info.TIM_ClockDivision=0;
Init_info.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2,&Init_info);
TIM_ARRPreloadConfig(TIM2,ENABLE);
TIM_UpdateRequestConfig(TIM2, TIM_UpdateSource_Regular);
TIM_ClearFlag(TIM2, TIM_FLAG_Update);
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
TIM_Cmd(TIM2,ENABLE);

NVIC_InitTypeDef InitTimIrq;
InitTimIrq.NVIC_IRQChannel=TIM2_IRQn;
InitTimIrq.NVIC_IRQChannelPreemptionPriority=1;
InitTimIrq.NVIC_IRQChannelSubPriority=1;
InitTimIrq.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&InitTimIrq);
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
}
int main()
{
init_leds();
timer_init();
// run
OS::run();

}

namespace OS
{
template <>
OS_PROCESS void TProc1::exec()
{
for(;;)
{
ef.wait();


}
}

template <>
OS_PROCESS void TProc2::exec()
{
for(;;)
{
TimerEvent.wait();
GPIO_ResetBits(GPIOC, GPIO_Pin_9);
}
}

}

void OS::system_timer_user_hook()
{
GPIO_SetBits(GPIOC, GPIO_Pin_9);
TimerEvent.signal_isr();
}

#if scmRTOS_IDLE_HOOK_ENABLE
void OS::idle_process_user_hook()
{
__WFI();
}
#endif

void TIM2_IRQHandler(void)
{
OS::TISRW in_handler;
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
ef.signal_isr();
if(GPIO_ReadOutputDataBit ( GPIOC,GPIO_Pin_8))
GPIO_WriteBit(GPIOC,GPIO_Pin_8,Bit_RESET);
else
GPIO_WriteBit(GPIOC,GPIO_Pin_8,Bit_SET);
}


Сергей Борщ
QUOTE (Legath @ Mar 21 2012, 11:04) *
хотя у меня определен свой обработчик прерывания.
Определен в файле .cpp. Срабатывает C++ искажение имен (name mangling) и ваш startup.c не видит вашего обработчика. Все так и должно быть.
CODE
extern "C"
void TIM2_IRQHandler(void)
{
    ....
}

Legath
Прошу у сообщества прощения за назойливость, но видимо на начальном этапе сам не разбирусь. В автономном режиме заработало после установления верного количества процессов (по невнимательности до этого стояло 3)

Код видоизменился и теперь по таймеру работает. Но почему то по системному таймеру Диод горит постоянно, не переключается. Складывается мнение что процесс не выполняется, что может быть не верно?
CODE
namespace OS
{
template <>
OS_PROCESS void TProc1::exec()
{
for(;;)
{
TimerEvent.wait();

if(GPIO_ReadOutputDataBit ( GPIOC,GPIO_Pin_8))
GPIO_WriteBit(GPIOC,GPIO_Pin_8,Bit_RESET);
else
GPIO_WriteBit(GPIOC,GPIO_Pin_8,Bit_SET);
sleep(1);

}
}

template <>
OS_PROCESS void TProc2::exec()
{
for(;;)
{
ef.wait();
if(GPIO_ReadOutputDataBit ( GPIOC,GPIO_Pin_9))
GPIO_WriteBit(GPIOC,GPIO_Pin_9,Bit_RESET);
else
GPIO_WriteBit(GPIOC,GPIO_Pin_9,Bit_SET);
sleep(20);
}
}

}

void OS::system_timer_user_hook()
{

TimerEvent.signal_isr();
}

#if scmRTOS_IDLE_HOOK_ENABLE
void OS::idle_process_user_hook()
{
__WFI();
}
#endif

extern "C" void TIM2_IRQHandler(void)
{
OS::TISRW in_handler;
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
ef.signal_isr();
}
Сергей Борщ
QUOTE (Legath @ Mar 21 2012, 15:02) *
Складывается мнение что процесс не выполняется, что может быть не верно?
А на какую частоту настроен таймер? Может быть вы просто не успеваете заметить его переключение?
Legath
Цитата(Сергей Борщ @ Mar 21 2012, 19:06) *
А на какую частоту настроен таймер? Может быть вы просто не успеваете заметить его переключение?

Вы оказались правы, погорячился я увидеть 500Гц глазами. Все отлично работает.


Большое спасибо за помощь.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.