AVRMega can't switch two threads

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

Moderator: tfAteba

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

AVRMega can't switch two threads

Post by birdkung »

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: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: AVRMega can't switch two threads

Post by Giovanni »

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
Been thanked: 1 time

Re: AVRMega can't switch two threads

Post by mabl »

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: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: AVRMega can't switch two threads

Post by Giovanni »

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

Re: AVRMega can't switch two threads

Post by birdkung »

I follow your suggest code but both threads still suspend.
mabl
Posts: 417
Joined: Tue Dec 21, 2010 10:19 am
Been thanked: 1 time

Re: AVRMega can't switch two threads

Post by mabl »

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

Post by birdkung »

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

Post by birdkung »

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
Been thanked: 1 time

Re: AVRMega can't switch two threads

Post by mabl »

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

Post by birdkung »

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.
Post Reply