Jump to content
    

[STM32] Проблемы в примере evantflag с добавленными прерываниями.

Проблема с следующем, после иницализации таймера и выставления приоритетов прерывания(делаю все через стандартную библиотеку переферии) исполнение улетает в DefaultHandler, хотя у меня определен свой обработчик прерывания. Соотвественно OS::Run не выполняется.

 

Код main.cpp

 

#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);
}

 

 

Share this post


Link to post
Share on other sites

хотя у меня определен свой обработчик прерывания.
Определен в файле .cpp. Срабатывает C++ искажение имен (name mangling) и ваш startup.c не видит вашего обработчика. Все так и должно быть.

extern "C"
void TIM2_IRQHandler(void)
{
    ....
}

 

Share this post


Link to post
Share on other sites

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

 

Код видоизменился и теперь по таймеру работает. Но почему то по системному таймеру Диод горит постоянно, не переключается. Складывается мнение что процесс не выполняется, что может быть не верно?

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();
}

Edited by Legath

Share this post


Link to post
Share on other sites

Складывается мнение что процесс не выполняется, что может быть не верно?
А на какую частоту настроен таймер? Может быть вы просто не успеваете заметить его переключение?

Share this post


Link to post
Share on other sites

А на какую частоту настроен таймер? Может быть вы просто не успеваете заметить его переключение?

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

2602942m.png

 

Большое спасибо за помощь.

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...