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.
AVRMega can't switch two threads
- Giovanni
- Site Admin
- Posts: 14455
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: AVRMega can't switch two threads
Hi,
Probably it is because you need to provide a periodic interrupt source and call chSysTimerHandlerI() from there, for example:
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
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
-
- 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
Ok so your main code is:
I' not familiar with the AVR port, how does the systemtick work there?
EDIT: *argh* Giovanni was faster again
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
- Giovanni
- Site Admin
- Posts: 14455
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
-
- 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
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?
Re: AVRMega can't switch two threads
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.
Re: AVRMega can't switch two threads
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
https://www.dropbox.com/s/pmsckf7ujp0p153/test.rar
-
- 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
Hmm it's years since i last worked with AVRs...
Shouldn't it be "if((PORTA&0x04) == 0x04)" ? You could also just do an xor...
Something like:
I mean, there is the AVR Dragon isn't there? Far more easy than LED debugging....
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....
Re: AVRMega can't switch two threads
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.
For AVR Dragon, now I'm buying it.
Who is online
Users browsing this forum: No registered users and 10 guests