eRTK
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
Data Structures | Macros | Enumerations | Functions | Variables
eRTK.h File Reference
#include <avr/io.h>
#include <stddef.h>
#include <util/atomic.h>
#include <avr/interrupt.h>
Include dependency graph for eRTK.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  t_eRTK_tcb
 

Macros

#define VANZTASK   6
 
#define F_CPU   16000000ul
 
#define eRTKHZ   1000
 
#define TIMERPREDIV   64ul
 
#define TIMERPRELOAD   ( F_CPU/( TIMERPREDIV*eRTKHZ ) )
 
#define ERTKDEBUG
 
#define eRTK_STARTUP_MS   0
 
#define eRTK_MAX_OVERLOAD   0
 
#define ERTK_STACKSIZE   256
 
#define IDLELED
 
#define sbi(port, nr)   (port|=_BV(nr))
 
#define cbi(port, nr)   (port&=~_BV(nr))
 
#define oIDLE(a)   { ( a ) ? sbi( PORTE, PE2 ) : cbi( PORTE, PE2 ); sbi( DDRE, PE2 ); }
 
#define oIDLEfast(a)   { ( a ) ? sbi( PORTE, PE2 ) : cbi( PORTE, PE2 ); }
 

Enumerations

enum  tsys {
  SYS_NOTASK, SYS_NULLPTR, SYS_NULLTIMER, SYS_OVERLOAD,
  SYS_VERIFY, SYS_UNKNOWN
}
 

Functions

void deadbeef (tsys reason)
 
void __attribute__ ((naked)) eRTK_scheduler(void)
 
uint8_t eRTK_GetTimer8 (void)
 
uint16_t eRTK_GetTimer16 (void)
 
uint8_t eRTK_GetTid (void)
 
void eRTK_SetReady (uint8_t tid)
 
void eRTK_SetSuspended (uint8_t tid)
 
void eRTK_WaitUntil (uint8_t then)
 
void eRTK_Sleep_ms (uint16_t ms)
 
void eRTK_get_sema (uint8_t semaid)
 
void eRTK_wefet (uint8_t timeout)
 
void eRTK_init (void)
 
void eRTK_timer_init (void)
 
void eRTK_go (void)
 

Variables

const t_eRTK_tcb rom_tcb [VANZTASK]
 

Macro Definition Documentation

#define cbi (   port,
  nr 
)    (port&=~_BV(nr))

Definition at line 38 of file eRTK.h.

#define eRTK_MAX_OVERLOAD   0

Definition at line 30 of file eRTK.h.

#define ERTK_STACKSIZE   256

Definition at line 32 of file eRTK.h.

#define eRTK_STARTUP_MS   0

Definition at line 29 of file eRTK.h.

#define ERTKDEBUG

Definition at line 27 of file eRTK.h.

#define eRTKHZ   1000

Definition at line 19 of file eRTK.h.

#define F_CPU   16000000ul

Definition at line 17 of file eRTK.h.

#define IDLELED

Definition at line 34 of file eRTK.h.

#define oIDLE (   a)    { ( a ) ? sbi( PORTE, PE2 ) : cbi( PORTE, PE2 ); sbi( DDRE, PE2 ); }

Definition at line 41 of file eRTK.h.

#define oIDLEfast (   a)    { ( a ) ? sbi( PORTE, PE2 ) : cbi( PORTE, PE2 ); }

Definition at line 42 of file eRTK.h.

#define sbi (   port,
  nr 
)    (port|=_BV(nr))

Definition at line 37 of file eRTK.h.

#define TIMERPREDIV   64ul

Definition at line 20 of file eRTK.h.

#define TIMERPRELOAD   ( F_CPU/( TIMERPREDIV*eRTKHZ ) )

Definition at line 21 of file eRTK.h.

#define VANZTASK   6

Definition at line 15 of file eRTK.h.

Enumeration Type Documentation

enum tsys
Enumerator
SYS_NOTASK 
SYS_NULLPTR 
SYS_NULLTIMER 
SYS_OVERLOAD 
SYS_VERIFY 
SYS_UNKNOWN 

Definition at line 50 of file eRTK.h.

Function Documentation

void __attribute__ ( (naked)  )

Definition at line 115 of file eRTK.c.

115  { /* start der hoechstprioren ready task, notfalls idle */
116  push();
118  //
119  if( pTaskRdy ) { //da muss natuerlich immer was drinstehen ;)
120  //do round robin bei mehreren mit gleicher prio
121  s_tcd *p=pTaskRdy;
122  while( p->tid != akttask ) {
123  p=p->pnext; //finde aktuelle task
124  if( !p ) break;
125  }
126  if( p ) { //task stand noch in der ready liste
127  //teste pri des nachfolgers
128  if( p->pnext!=NULL ) { //wenn es nachfolger gibt
129  if( p->prio == p->pnext->prio ) { //schalte weiter wenn nachfolger prio genauso ist
130  akttask=p->pnext->tid;
131  }
132  else {
134  }
135  }
136  else { //sonst nimm den ersten in der liste, der muss per definition die gleiche prio haben da wir bei kleineren prios gar nicht suchen !
138  }
139  }
140  else akttask=pTaskRdy->tid; //nimm das erstbeste aus der ready liste ;)
141  }
142  else deadbeef( SYS_NOTASK );
143  //
145  pop();
146  sei();
147  asm volatile ( "ret" );
148  }
uint8_t tid
Definition: eRTK.c:30
Definition: eRTK.c:27
s_tcd * pTaskRdy
Definition: eRTK.c:40
struct s_tcd * pnext
Definition: eRTK.c:28
void * pp_stack
Definition: eRTK.c:85
void deadbeef(tsys reason)
volatile uint8_t akttask
Definition: eRTK.c:24
void * stackptr[VANZTASK+1]
Definition: eRTK.c:22
#define push()
Definition: eRTK.c:87
uint8_t prio
Definition: eRTK.c:31
#define pop()
Definition: eRTK.c:101

Here is the call graph for this function:

void deadbeef ( tsys  reason)

Here is the caller graph for this function:

void eRTK_get_sema ( uint8_t  semaid)

Definition at line 309 of file eRTK.c.

309  { /* Warten bis Semaphore frei ist und danach besetzen */
310  if( semaid>=ANZSEMA ) deadbeef( SYS_UNKNOWN );
311  while( xch( &sema[semaid], 1 ) ) { /* >0 = sema blockiert */
312  sei();
313  eRTK_wefet( 1 );
314  }
315  }
#define ANZSEMA
Definition: eRTK.c:294
void eRTK_wefet(uint8_t timeout)
Definition: eRTK.c:269
void deadbeef(tsys reason)

Here is the call graph for this function:

Here is the caller graph for this function:

uint8_t eRTK_GetTid ( void  )

Definition at line 233 of file eRTK.c.

233  { //holen der eigenen task id
234  return akttask;
235  }
volatile uint8_t akttask
Definition: eRTK.c:24

Here is the caller graph for this function:

uint16_t eRTK_GetTimer16 ( void  )

Definition at line 461 of file eRTK.c.

461  { //wenn 256ms nicht reichen
462  register uint16_t val;
463  ATOMIC_BLOCK( ATOMIC_RESTORESTATE ) {
464  val=eRTK_m_timer.timer16;
465  }
466  return val;
467  }
union @0 eRTK_m_timer
uint8_t eRTK_GetTimer8 ( void  )

Definition at line 457 of file eRTK.c.

457  { //256ms bis overflow
458  return eRTK_m_timer.timer8[0];
459  }
union @0 eRTK_m_timer

Here is the caller graph for this function:

void eRTK_go ( void  )

Definition at line 151 of file eRTK.c.

151  { /* start der hoechstprioren ready task, notfalls idle */
152  if( pTaskRdy ) akttask=pTaskRdy->tid;
153  else deadbeef( SYS_NOTASK );
154  //
155  eRTK_up=1;
157  pop();
158  asm volatile( "ret" );
159  }
uint8_t tid
Definition: eRTK.c:30
s_tcd * pTaskRdy
Definition: eRTK.c:40
void * pp_stack
Definition: eRTK.c:85
volatile uint8_t eRTK_up
Definition: eRTK.c:52
void deadbeef(tsys reason)
volatile uint8_t akttask
Definition: eRTK.c:24
void * stackptr[VANZTASK+1]
Definition: eRTK.c:22
#define pop()
Definition: eRTK.c:101

Here is the call graph for this function:

Here is the caller graph for this function:

void eRTK_init ( void  )

Definition at line 371 of file eRTK.c.

371  { /* Initialisierung der Daten des Echtzeitsystems */
372  uint8_t n, prio, index;
373  uint8_t task;
374  //
375  for( n=0; n<VANZTASK+1; n++ ) {
376  tcd[n].pnext=NULL; /* verkettung der tcd's in unsortiertem grundzustand */
377  tcd[n].pbefore=NULL;
378  tcd[n].tid=n;
379  tcd[n].prio=n ? rom_tcb[n-1].prio : 0; //idle task ist immer da mit pri 0
380  tcd[n].timer=0;
381  //die parameter merken zum debuggen
382 #ifdef ERTK_DEBUG
383  tcd[n].param0= n ? 0 : rom_tcb[n-1].param0;
384  tcd[n].param1= n ? 0 : rom_tcb[n-1].param1;
385 #endif
386  }
387  //einsetzen der idle task, die muss immer da sein !
388  pTaskRdy=( s_tcd * )&tcd[0];
389  pTaskRdy->pnext=NULL;
390  pTaskRdy->pbefore=NULL;
391  /* einsortieren der tasks mit verkettung nach absteigender prioritaet */
392  char hit[VANZTASK+1];
393  memset( hit, 0, sizeof hit );
394  for( task=1; task<VANZTASK+1; task++ ) {
395  prio=0;
396  index=0;
397  for( n=1; n<VANZTASK+1; n++ ) { //hoechstpriore ready und noch nicht verkettete task finden
398  if( tcd[n].prio>=prio && !hit[n] ) { /* prio>prio und noch nicht in liste */
399  prio=tcd[n].prio;
400  index=n;
401  }
402  }
403  eRTK_SetReady( index ); //pTaskReady -> tcdx -> txdy -> 0
404  hit[index]=1;
405  }
406  //
407  for( n=0; n<VANZTASK+1; n++ ) { /* SP der Tasks auf jeweiliges Stackende setzen */
408  for( uint16_t f=0; f<ERTK_STACKSIZE/4; f++ ) memcpy( stack[n]+4*f, "\xde\xad\xbe\xef", 4 );
409  //memcpy( &stack[n][214], "0123456789abcdef0123456789ABCDEF", 32 );
410  /* startadressen und parameter auf den stack */
411  stack[n][ERTK_STACKSIZE-9]=0; //r1=0
412  //
413  union {
414  uint32_t ui32;
415  uint8_t ui8[4];
416  void ( *task )( uint16_t param0, void *param1 );
417  void ( *tvoid )( void );
418  void ( *tbeef )( tsys );
419  } taddr;
420  memset( &taddr, 0, sizeof taddr );
421  taddr.tbeef=deadbeef;
422  stack[n][ERTK_STACKSIZE-1]=taddr.ui8[0];
423  stack[n][ERTK_STACKSIZE-2]=taddr.ui8[1];
424  stack[n][ERTK_STACKSIZE-3]=taddr.ui8[2];
425  if( n ) taddr.task=rom_tcb[n-1].task;
426  else taddr.tvoid=eRTK_Idle;
427  stack[n][ERTK_STACKSIZE-4]=taddr.ui8[0];
428  stack[n][ERTK_STACKSIZE-5]=taddr.ui8[1];
429  stack[n][ERTK_STACKSIZE-6]=taddr.ui8[2];
430  //
431  // hi lo hi lo
432  //zwei parameter in p0=r25:r24 und p1=r23:r22
433  if( n ) {
434  stack[n][ERTK_STACKSIZE-32]=rom_tcb[n-1].param0&0xff;
435  stack[n][ERTK_STACKSIZE-33]=rom_tcb[n-1].param0>>8;
436  stack[n][ERTK_STACKSIZE-30]=( uint16_t )( rom_tcb[n-1].param1 )&0xff;
437  stack[n][ERTK_STACKSIZE-31]=( uint16_t )( rom_tcb[n-1].param1 )>>8;
438  }
439  //
440  stackptr[n]=&stack[n][ERTK_STACKSIZE-40];
441  }
442  sema_init();
443  }
push r0 npush r1 npush r2 npush r3 npush r4 npush r5 npush r6 npush r7 npush r8 npush r9 npush r10 npush r11 npush r12 npush r13 npush r14 npush r15 npush r16 npush r17 npush r18 npush r19 npush r20 npush r21 npush r22 npush r23 npush r24 npush r25 npush r26 npush r27 npush r28 npush r29 npush r30 npush r31 n in __SP_L__ n sts r0 n in __SP_H__ n sts r0 n
Definition: eRTK.c:93
s_tcd tcd[VANZTASK+1]
Definition: eRTK.c:38
uint8_t tid
Definition: eRTK.c:30
Definition: eRTK.c:27
#define ERTK_STACKSIZE
Definition: eRTK.h:32
void sema_init(void)
Definition: eRTK.c:322
s_tcd * pTaskRdy
Definition: eRTK.c:40
void(* task)(uint16_t param0, void *param1)
Definition: eRTK.h:68
#define VANZTASK
Definition: eRTK.h:15
struct s_tcd * pnext
Definition: eRTK.c:28
uint8_t prio
Definition: eRTK.h:69
struct s_tcd * pbefore
Definition: eRTK.c:29
void eRTK_SetReady(uint8_t tid)
Definition: eRTK.c:238
void deadbeef(tsys reason)
uint8_t timer
Definition: eRTK.c:32
void * param1
Definition: eRTK.h:71
const t_eRTK_tcb rom_tcb[VANZTASK]
Definition: main.c:90
void * stackptr[VANZTASK+1]
Definition: eRTK.c:22
tsys
Definition: eRTK.h:50
uint8_t prio
Definition: eRTK.c:31
uint16_t param0
Definition: eRTK.h:70

Here is the call graph for this function:

Here is the caller graph for this function:

void eRTK_SetReady ( uint8_t  tid)

Definition at line 238 of file eRTK.c.

238  {
239  if( !tid ) deadbeef( SYS_NULLPTR ); //idle task ist immer ready
240  if( tcd[tid].pnext || tcd[tid].pbefore ) deadbeef( SYS_VERIFY ); //war gar nicht suspendiert
241  //
242  s_tcd *pthis=pTaskRdy;
243  ATOMIC_BLOCK( ATOMIC_RESTORESTATE ) {
244  tcd[tid].timer=0; //timer loeschen damit er nicht spaeter nochmal startet
245  do { //pthis->hoechstprioren tcd oder idle
246  if( tcd[tid].prio > pthis->prio || pthis->pnext==NULL ) { //neuer eintrag hat hoehere prio oder es gibt keinen nachfolger
247  insertat( pthis, &tcd[tid] );
248  break;
249  }
250  } while( ( pthis=pthis->pnext ) );
251  }
252  }
s_tcd tcd[VANZTASK+1]
Definition: eRTK.c:38
Definition: eRTK.c:27
s_tcd * pTaskRdy
Definition: eRTK.c:40
struct s_tcd * pnext
Definition: eRTK.c:28
void deadbeef(tsys reason)
uint8_t timer
Definition: eRTK.c:32
uint8_t prio
Definition: eRTK.c:31

Here is the call graph for this function:

Here is the caller graph for this function:

void eRTK_SetSuspended ( uint8_t  tid)

Definition at line 255 of file eRTK.c.

255  { //tcd[tid] aus der ready list austragen
256  if( !tid ) deadbeef( SYS_NULLPTR ); //idle task darf nicht suspendiert werden
257  if( !tcd[tid].pbefore && !tcd[tid].pnext ) deadbeef( SYS_VERIFY ); //war nicht in ready list
258  s_tcd *pthis=pTaskRdy;
259  ATOMIC_BLOCK( ATOMIC_RESTORESTATE ) {
260  do {
261  if( pthis->tid==tid ) {
262  removeat( pthis );
263  break;
264  }
265  } while( ( pthis=pthis->pnext ) );
266  }
267  }
s_tcd tcd[VANZTASK+1]
Definition: eRTK.c:38
uint8_t tid
Definition: eRTK.c:30
Definition: eRTK.c:27
s_tcd * pTaskRdy
Definition: eRTK.c:40
struct s_tcd * pnext
Definition: eRTK.c:28
void deadbeef(tsys reason)

Here is the call graph for this function:

Here is the caller graph for this function:

void eRTK_Sleep_ms ( uint16_t  ms)

Definition at line 280 of file eRTK.c.

280  {
281  while( ms ) {
282  if( ms>255 ) {
283  eRTK_wefet( 255 );
284  ms-=255;
285  }
286  else {
287  eRTK_wefet( ms );
288  ms=0;
289  }
290  }
291  }
void eRTK_wefet(uint8_t timeout)
Definition: eRTK.c:269

Here is the call graph for this function:

Here is the caller graph for this function:

void eRTK_timer_init ( void  )

Definition at line 515 of file eRTK.c.

515  {
516 #if defined (__AVR_ATmega2560__)
517  timer0_init();
518 #elif defined (__AVR_ATxmega128A1U__)
519 #endif
520  }

Here is the caller graph for this function:

void eRTK_WaitUntil ( uint8_t  then)

Definition at line 469 of file eRTK.c.

469  {
470  eRTK_wefet( then-eRTK_GetTimer8() );
471  }
uint8_t eRTK_GetTimer8(void)
Definition: eRTK.c:457
void eRTK_wefet(uint8_t timeout)
Definition: eRTK.c:269

Here is the call graph for this function:

void eRTK_wefet ( uint8_t  timeout)

Definition at line 269 of file eRTK.c.

269  {
270  if( timeout ) { //sonst klinkt sich die task in einem wait_until() fuer immer aus
271  ATOMIC_BLOCK( ATOMIC_RESTORESTATE ) { //14+2=16 cycles pro loop -> 16MHz -> 1000 inc/ms
272  if( tcd[akttask].timer ) deadbeef( SYS_UNKNOWN );
273  tcd[akttask].timer=timeout;
275  eRTK_scheduler();
276  }
277  }
278  }
s_tcd tcd[VANZTASK+1]
Definition: eRTK.c:38
void deadbeef(tsys reason)
volatile uint8_t akttask
Definition: eRTK.c:24
void eRTK_SetSuspended(uint8_t tid)
Definition: eRTK.c:255
uint8_t timer
Definition: eRTK.c:32

Here is the call graph for this function:

Here is the caller graph for this function:

Variable Documentation

const t_eRTK_tcb rom_tcb[VANZTASK]

Definition at line 90 of file main.c.