2017-02-16 3 views
1

Quelle est la meilleure façon de créer un minuteur avec Microblaze qui me permettrait de le faire fonctionner plus comme une fonction comme delay_ms() ou sleep() dans des scripts plus classiques?Configurer une minuterie avec Microblaze?

facilement, je peux créer une fonction stupide comme ceci:

void delay_ms(int i) { 
    //mind that I am doing this on the top of my head 
    for(delays=0; delay<(i*((1/frequency of the device)/2)); delays++) { 
    } 
} 

... mais qui n'aurait rien de processus de traitement jusqu'à ce qu'il se termine, alors qu'en réalité je besoin d'avoir la fonction me permet de Arrêtez un processus pendant une certaine période de temps pendant qu'un autre continue à travailler.

Une telle chose est possible, sans aucun doute à ce sujet, mais quelle serait la solution la plus simple à ce problème?

(J'utilise Spartan-3A, mais je crois que la solution fonctionnerait pour les kits différents, ainsi FPGAs.)

+0

Vous pouvez le faire avec une interruption ou un signal ... mais cela dépend de la façon dont vous programmez le processeur. Utilisez-vous un système d'exploitation? – purplepsycho

+0

Aucun, pas du tout. J'essaie de tout faire aussi léger que possible. –

+0

Comment exécutez-vous donc plusieurs processus? – purplepsycho

Répondre

2

TL; DR

Utilisez un micro OS, comme FreeRTOS.

réponse Bad

Eh bien, si vous n'avez pas OS, aucune commutation de tâches, mais ont une minuterie externe, vous pouvez utiliser l'approche suivante:

Activer l'interruption de votre horloge matérielle et gérer un compteur entraîné par cette interrution:

Vous devriez avoir quelque chose comme

/**timer.c**/ 

/* The internal counters 
* each task have its counter 
*/ 
static int s_timers[NUMBER_OF_TASKS] = {0,0}; 

/* on each time tick, decrease timers */ 
void timer_interrupt() 
{ 
    int i; 
    for (i = 0; i < NUMBER_OF_TASKS; ++i) 
    { 
     if (s_timer[i] > 0) 
     { 
      s_timer[i]--; 
     } 
    } 
} 

/* set wait counter: 
* each task says how tick it want to wait 
*/ 
void timer_set_wait(int task_num, int tick_to_wait) 
{ 
    s_timer[task_num] = tick_to_wait; 
} 

/** 
* each task can ask if its time went out 
*/ 
int timer_timeout(int task_num) 
{ 
    return (0 == s_timer[task_num]); 
} 

Une fois que vous avez quelque chose comme une minuterie (le code ci-dessus est facilement perfectibles), Programmez vos tâches:

/**task-1.c**/ 

/*TASK ID must be valid and unique in s_timer */ 
#define TASK_1_ID 0 

void task_1() 
{ 
    if (timer_timeout(TASK_1_ID)) 
    { 
     /* task has wait long enough, it can run again */ 

     /* DO TASK 1 STUFF */ 
     printf("hello from task 1\n"); 

     /* Ask to wait for 150 ticks */ 
     timer_set_wait(TASK_1_ID, 150); 
    } 
} 

/**task-2.c**/ 

/*TASK ID must be valid and unique in s_timer */ 
#define TASK_2_ID 1 

void task_2() 
{ 
    if (timer_timeout(TASK_2_ID)) 
    { 
     /* task has wait long enough, it can run again */ 

     /* DO TASK 2 STUFF */ 
     printf("hello from task 2\n"); 

     /* Ask to wait for 250 ticks */ 
     timer_set_wait(TASK_2_ID, 250); 
    } 
} 

et le calendrier (un grand mot ici) les tâches:

/** main.c **/ 

int main() 
{ 
    /* init the program, like set up the timer interruption */ 
    init() 

    /* do tasks, for ever*/ 
    while(1) 
    { 
     task_1(); 
     task_2(); 
    } 
    return 0; 
} 

Je pense Ce que j'ai décrit est une solution boiteuse qui ne devrait pas être sérieusement utilisée.

Le code que j'ai donné est plein de problèmes, comme ce qui se passe si une tâche se ralentir à exécuter ...

Au lieu de cela, vous --could-- devez utiliser une RT Os, comme FreeRTOS qui est très utile dans ce genre de problèmes.

+0

La solution est vraiment très intelligente. Le seul problème est que je peux y faire une quantité indéfinie de tâches et que j'aurais besoin de beaucoup de bricolage. –

+0

Les OS (OSi?) Sont en fait assez lourds pour ce que je fais, donc il vaut mieux les ignorer, même si cela serait beaucoup plus facile avec ça. –

+0

"La solution est vraiment très intelligente." Merci – purplepsycho