Página 1 de 1

saltar de tarefa utilizando rtos Keil

MensagemEnviado: 22 Jul 2010 15:32
por verd
Seguinte pessoal, o que eu quero é sair do laço while, no caso seto o flag bit 2 "0x0002", limpo ele, e a tarefa começa a ser executada dentro do laço while, o programa lê a entrada analógica e envia pelo display, ai vou setar uma interrupção e sair deste laço while, para parar de escrever no display, como faço isso? desculpa a pergunta mediocre é que so ruinzin nu C!!


Código: Selecionar todos
__task void tarefa2(void){
   for (;;){
      os_evt_wait_and(0x0002, 0xffff);
      os_evt_clr (0x0002, t_tarefa2);
      while(1){
      adc();
      envia_display();

      }           
   }
}


tem goto no rtos? hehehe!

MensagemEnviado: 22 Jul 2010 15:46
por Jorge_Francisco
testa no while mesmo :

while ( condicao == true)
{
}

Ou faz um if dentro do laço e colocar um continue ou exit ou break:

while(1)
{
if( condicao == true )
break;
}

MensagemEnviado: 22 Jul 2010 16:31
por verd
fiz varia tentativas qq condição ele sai do while!! teria q sair do while só com a condição desejada!

é o seguinte estou simulando meu programa com display de segmentos, ai eu envio os bits dos segmentos que quero q apareça no display, como estou utilizando rtos, esta tarefa do display esta sempre sendo executada, ai no caso eu queria fazer um menu de funções, iria deslocar meu programa para outra função e escrever no display outra coisa, só que minha primeira tarefa de leitura ad esta sempre em execução e escrevendo no display!!

MensagemEnviado: 22 Jul 2010 19:24
por tcpipchip
Este tal de rtos nao tem signal() e wait() ?

MensagemEnviado: 22 Jul 2010 22:23
por barboza
Se a conversão do AD sempre irá atualizar o display, porque você precisa sair do loop while???? Nao realidade acho que nem precisa dele.

Pelo o que entendi, a atualização acontece a cada evento da flag 2 (0x0002).
Poderia ter uma task só pra isso então:

Código: Selecionar todos
__task void tarefa2(void){
   for (;;){
      os_evt_wait_and(0x0002, 0xffff);
      adc();
      envia_display();
   }
}


Não precisa limpar a flag após o os_evt_wait_and(,);

The os_evt_wait_and function returns when all of the events specified in the wait_flags have occurred or when the timeout expires. If all events specified in wait_flags have arrived, this function clears them before the function returns. The function actually clears the events whose corresponding flags have been set to 1 in the wait_flags parameter. The other event flags are not changed.


Suas outras tarefas, menu, podem ter outra task, que receberá evento do teclado (eu acho) e tem digitos reservados no display.

Senão você precisa compartilhar recurso (display), então a tratativa precisa ser diferente.

MensagemEnviado: 23 Jul 2010 08:17
por verd
Opa agora deu ceto barboza!!!

Tirei o while e na função de leitura do AD eu seto o flag 2 como você havia dito, ai fica sempre em looping, ai quando entro com minha interrupção externa eu limpo o flag 2 e ele sai da rotina!! ai nesta interrupção vou limpar o flag 2 sair da rotina de leitura do AD e entrar em outra rotina de escrita em display no caso um menu!!

Valeu barboza!!

MensagemEnviado: 23 Jul 2010 10:58
por verd
tcpipchip escreveu:Este tal de rtos nao tem signal() e wait() ?


TCP signal não tem, tem wait_and e wait_or!!

MensagemEnviado: 23 Jul 2010 11:21
por verd
Interrupção Externa:

habilito a interrupção externa EINT3, funcionou blz!, se eu mudar o pino (1<<13), para (1<<10) ela continua funcionando(estranho), mas se eu habilitar a interrução EINT0 ou EINT1 ou EINT2 e pressionar algumas destas 3 o programa trava! funciona somente a interrupção EINT3!

Código: Selecionar todos
//*****************************************************************************
// Function name:   INTERRUPÇÃO EXTERNA    3
//***************************************************************************/
void extint0(void) {
  LPC_GPIO2->FIODIR      &= ~(1 << 13);    /* PORT2.13 entrada      */
  LPC_GPIOINT->IO2IntEnF |=  (1 << 13);    /* enable falling edge irq         */
  NVIC_EnableIRQ(EINT3_IRQn);              /*habilita irq            */
}

void EINT3_IRQHandler()
{
LPC_GPIOINT->IO2IntClr |= (1 << 13);     /* limpa pedido       */   
isr_evt_set(0x0003, t_tarefa3);          // envia flag de evento
}





estava fazendo o seguinte para habilitar a EINT2:
Código: Selecionar todos
//*****************************************************************************
// Function name:   INTERRUPÇÃO EXTERNA    2
//***************************************************************************/
void extint0(void) {
  LPC_GPIO2->FIODIR      &= ~(1 << 12);    /* PORT2.12 entrada     */
  LPC_GPIOINT->IO2IntEnF |=  (1 << 12);    /* enable falling edge irq         */
  NVIC_EnableIRQ(EINT2_IRQn);              /* habilita irq             */
}

void EINT2_IRQHandler()
{
LPC_GPIOINT->IO2IntClr |= (1 << 12);     /* limpa pedido       */   
isr_evt_set(0x0003, t_tarefa3);          // envia flag de evento
}


algume consegue enxergar aonde estou comendo barriga?

MensagemEnviado: 23 Jul 2010 13:07
por barboza
Nada a ver com a int, mas sim o uso do SO e dos eventos:

Código: Selecionar todos
isr_evt_set(0x0003, t_tarefa3);          // envia flag de evento


Ao fazer isso, você esta enviando dois eventos de flags, a 1(0x0001) e a 2(0x0002). Isso equivale ao or e da o valor 0x0003.

Para não cair no erro, use o deslocamento de bits, pois os eventos são orientados a bit, limitando em 16 eventos.

Código: Selecionar todos
isr_evt_set((1<<3), t_tarefa3);          // envia flag de evento



Se entendi sua aplicação, você pode usar o time-out na espera das flags e tratar tudo dentro de uma task.



Código: Selecionar todos

__task void task1 (void) {
  OS_RESULT result;

  result = os_evt_wait_and (flag, time-out);

  if (result == OS_R_TMO) {
    Atualize com o display com o adc;
  }
  else {
    Trate eventos de teclas;
  }
   ..
}




De uma lida na documentação e organize melhor as idéias.

http://www.keil.com/support/man/docs/rl ... it_and.htm

MensagemEnviado: 26 Jul 2010 09:13
por verd
Valeu barboza!!