AVRMega can't switch two threads

ChibiOS public support forum for topics related to the Atmel AVR family of micro-controllers.

Moderators: utzig, tfAteba

birdkung
Posts: 9
Joined: Fri Nov 16, 2012 8:38 am

AVRMega can't switch two threads

Postby birdkung » Fri Nov 16, 2012 8:53 am

Now, I program in ATMEGA32 and using ChibiOS.

My program has 2 threads there are main and mythread, and using function chThdSleep() for delay both thread.
But after program executed function chThdSleep(), thread can't switch to other thread and it look like two thread are suspended forever.

What should I do to fix this problem?

The project file as this link : https://www.dropbox.com/sh/nsyr3ccbyg02 ... V/test.rar

Thank you.

User avatar
Giovanni
Site Admin
Posts: 13064
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 758 times
Been thanked: 636 times
Contact:

Re: AVRMega can't switch two threads

Postby Giovanni » Fri Nov 16, 2012 9:24 am

Hi,

Probably it is because you need to provide a periodic interrupt source and call chSysTimerHandlerI() from there, for example:

Code: Select all

CH_IRQ_HANDLER(TIMER0_COMPA_vect) {

  CH_IRQ_PROLOGUE();

  chSysLockFromIsr();
  chSysTimerHandlerI();
  chSysUnlockFromIsr();

  CH_IRQ_EPILOGUE();
}

/**
 * Board-specific initialization code.
 */
void boardInit(void) {

  /*
   * External interrupts setup, all disabled initially.
   */
  EICRA  = 0x00;
  EICRB  = 0x00;
  EIMSK  = 0x00;

  /*
   * Timer 0 setup.
   */
  TCCR0A  = (1 << WGM01) | (0 << WGM00) |                /* CTC mode.        */
            (0 << COM0A1) | (0 << COM0A0) |              /* OC0A disabled.   */
            (0 << COM0B1) | (0 << COM0B0);               /* OC0B disabled.   */
  TCCR0B  = (0 << WGM02) |                               /* CTC mode.        */
            (0 << CS02)  | (1 << CS01)  | (1 << CS00);   /* CLK/64 clock.    */
  OCR0A   = F_CPU / 64 / CH_FREQUENCY - 1;
  TCNT0   = 0;                                           /* Reset counter.   */
  TIFR0   = (1 << OCF0A);                                /* Reset pending.   */
  TIMSK0  = (1 << OCIE0A);                               /* IRQ on compare.  */
}


Without this the OS cannot count time and wakeup the threads. Please refer to the board files provided with the OS, and use one of those preferably.

Giovanni

mabl
Posts: 417
Joined: Tue Dec 21, 2010 10:19 am
Location: Karlsruhe, Germany
Been thanked: 1 time
Contact:

Re: AVRMega can't switch two threads

Postby mabl » Fri Nov 16, 2012 9:25 am

Ok so your main code is:

Code: Select all

#include <avr/io.h>
#include <avr/interrupt.h>

#include "ch.h"

static WORKING_AREA(myThreadWorkingArea,128);

static msg_t myThread(void *arg);


int main(void)
{
   DDRA = 0xFF;
   PORTA = 0xFF;   

   chSysInit();
   
   
   chThdCreateStatic(myThreadWorkingArea,sizeof(myThreadWorkingArea),NORMALPRIO+1,myThread,NULL);
   
   while(TRUE)
   {
      PORTA |= 0x01;
      chThdSleep(1000);
      PORTA &= 0xFE;
   }
   return 0;
}

static msg_t myThread(void *arg)
{
   while(TRUE)
   {
      PORTA &= 0xFD;
      chThdSleep(1000);
      PORTA |= 0x02;
   }
}


I' not familiar with the AVR port, how does the systemtick work there?

EDIT: *argh* Giovanni was faster again

User avatar
Giovanni
Site Admin
Posts: 13064
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 758 times
Been thanked: 636 times
Contact:

Re: AVRMega can't switch two threads

Postby Giovanni » Fri Nov 16, 2012 9:26 am

:D

birdkung
Posts: 9
Joined: Fri Nov 16, 2012 8:38 am

Re: AVRMega can't switch two threads

Postby birdkung » Fri Nov 16, 2012 9:56 am

I follow your suggest code but both threads still suspend.

mabl
Posts: 417
Joined: Tue Dec 21, 2010 10:19 am
Location: Karlsruhe, Germany
Been thanked: 1 time
Contact:

Re: AVRMega can't switch two threads

Postby mabl » Fri Nov 16, 2012 10:05 am

Have you made sure that your timer interrupts fire? Also, make sure that the code posted by Giovanni matches your hardware. Can you debug your hardware? How do you know that they are still stalled? Maybe the LEDs toggle faster than your eyes can see?

birdkung
Posts: 9
Joined: Fri Nov 16, 2012 8:38 am

Re: AVRMega can't switch two threads

Postby birdkung » Fri Nov 16, 2012 10:33 am

mabl wrote:Have you made sure that your timer interrupts fire? Also, make sure that the code posted by Giovanni matches your hardware. Can you debug your hardware? How do you know that they are still stalled? Maybe the LEDs toggle faster than your eyes can see?


From suggest code interrupt timer has interval occur 1ms (CH_FREQUENCY = 1000).

So, I confirm that by toggle LED every 1s in interrupt timer because I can't debug hardware.

birdkung
Posts: 9
Joined: Fri Nov 16, 2012 8:38 am

Re: AVRMega can't switch two threads

Postby birdkung » Fri Nov 16, 2012 11:24 am

This link I add interrupt timer for base timer OS in board.c and disable all hal use in halconf.h

https://www.dropbox.com/s/pmsckf7ujp0p153/test.rar

mabl
Posts: 417
Joined: Tue Dec 21, 2010 10:19 am
Location: Karlsruhe, Germany
Been thanked: 1 time
Contact:

Re: AVRMega can't switch two threads

Postby mabl » Fri Nov 16, 2012 12:31 pm

Hmm it's years since i last worked with AVRs...

Code: Select all

void boardInit(void) {

/*
      * Timer 1 setup.
      */
     TCCR1A  = (1 << WGM11) | (0 << WGM10) |                /* CTC mode.        */
               (0 << COM1A1) | (0 << COM1A0) |              /* OC0A disabled.   */
               (0 << COM1B1) | (0 << COM1B0);               /* OC0B disabled.   */
     TCCR1B  = (0 << WGM12) |                               /* CTC mode.        */
               (0 << CS12)  | (1 << CS11)  | (1 << CS10);   /* CLK/64 clock.    */
     OCR1A   = 16000000 / 64 / CH_FREQUENCY - 1;
     TCNT1   = 0;                                           /* Reset counter.   */
     TIFR   = (0 << OCF1A);                                /* Reset pending.   */
     TIMSK  = (1 << OCIE1A);                               /* IRQ on compare.  */

}

CH_IRQ_HANDLER(TIMER1_COMPA_vect)
{
   static int counter = 0;
   CH_IRQ_PROLOGUE();
   
   counter++;
   if(counter == 1000)
   {
      if((PINA&0x04) == 0x04)
      {
         PORTA &= 0xFB;
      }
      else
      {
         PORTA |= 0x04;
      }
      counter = 0;
   }
   
   chSysLockFromIsr();
     chSysTimerHandlerI();
     chSysUnlockFromIsr();
   
     CH_IRQ_EPILOGUE();
}


Shouldn't it be "if((PORTA&0x04) == 0x04)" ? You could also just do an xor...

Something like:

Code: Select all

counter++;
if ( (counter % 1000) == 0) {
   PORTA ^= (1<<PB2);
   counter = 0;
}


I mean, there is the AVR Dragon isn't there? Far more easy than LED debugging....

birdkung
Posts: 9
Joined: Fri Nov 16, 2012 8:38 am

Re: AVRMega can't switch two threads

Postby birdkung » Sun Nov 18, 2012 4:17 pm

mabl, do you have an example project for me? Maybe I setting wrong in file config (hal and os).

For AVR Dragon, now I'm buying it.


Return to “AVR Support”

Who is online

Users browsing this forum: No registered users and 2 guests