eRTK
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
eRTK.c
Go to the documentation of this file.
1 /*
2  * eRTK.cpp
3  *
4  * Created: 13.04.2015 07:52:46
5  * Author: er
6  */
7 #include <avr/io.h>
8 #include <avr/interrupt.h>
9 #include <string.h>
10 #include <stdio.h>
11 #include <avr/sleep.h>
12 #include <avr/wdt.h>
13 #include "eRTK.h"
14 #include "adc.h"
15 
16 #ifdef ERTKDEBUG
17 uint8_t stack[VANZTASK+1][ERTK_STACKSIZE] __attribute__ ((aligned (256))); /* Jede Task hat Stack a' STACKSIZE Byte */
18 #else
19 uint8_t stack[VANZTASK+1][ERTK_STACKSIZE]; /* Jede Task hat Stack a' STACKSIZE Byte */
20 #endif
21 
22 void * stackptr[VANZTASK+1]; /* Ablage fuer Stackpointer der Tasks */
23 
24 volatile uint8_t akttask; /* Nummer der aktuellen Task, 0=idle */
25 
26 /* struktur task control block */
27 typedef struct s_tcd { /* queue mit ordnungskriterium task prioritaet 255..0 */
28  struct s_tcd * pnext; /* 1. element immer verkettungszeiger !!! */
29  struct s_tcd * pbefore; /* vorgaenger in liste */
30  uint8_t tid; /* index aus der reihenfolge der statischen deklaration */
31  uint8_t prio; /* 0..255 */
32  uint8_t timer; /* timeout counter mit system tick aufloesung */
33 #ifdef ERTK_DEBUG
34  uint16_t param0;
35  void * param1;
36 #endif
37  } s_tcd;
38 s_tcd tcd[VANZTASK+1]; /* indizierung ueber task index */
39 
40 s_tcd * pTaskRdy; /* einfache verkettung aller ready tasks ueber tcd.next in reihenfolge der prioritaet */
41 
42 /*
43  die perfcounter:
44  stellen in einem schieberegister die letzten 256 messergebnisse dar.
45  bei system im leerlauf stehen die zaehler auf 1000-overhead.
46  eine schleife dauert 16 zyklen, alle 1ms wird abgefragt und da sind 16000 zyklen ausgefuehrt worden.
47  je mehr systemlast um so kleiner der zaehlerstand.
48  1000 -> leerlauf
49  900 -> 100*16=1600 zyklen wurden anderweitig verbraucht (in diesem 1ms intervall)
50  ! z.b. lcd_clear_area() braucht mehr als 10ms !
51 */
52 volatile uint8_t eRTK_up; //wird gesetzt wenn das system gestartet ist
53 volatile uint16_t eRTK_perfcount; //aktueller counter
54 volatile uint16_t eRTK_perfcounter[256]; //counter array der letzen 256ms
55 volatile uint8_t eRTK_iperf; //index im array 0..255
56 volatile uint16_t eRTK_ticks; //wie spaet ist es nach dem urknall in ms
57 volatile uint8_t eRTK_cnt_overload; //zaehlt die aufeinanderfolgenden overload phasen
58 
59 void __attribute__ ((optimize("O2"))) eRTK_Idle( void ) {
60 #ifdef ERTKDEBUG
61  while( 1 ) { //14+2=16 cycles pro loop -> 16MHz -> 1000 inc/ms
62  cli(); //cli=1clock
63  ++eRTK_perfcount; //lds,lds,adiw,sts,sts=5x2clocks
64  sei(); //sei=1clock
65  oIDLEfast( 1 ); //2 cycles fuer 2xnop oder ein output bit setzen
66  } //rjmp=2clocks
67 #else
68  while( 1 ) {
69  set_sleep_mode( SLEEP_MODE_IDLE );
70  sleep_enable();
71  sei();
72  oIDLE( 1 );
73  sleep_cpu();
74  sleep_disable();
75  }
76 #endif
77  }
78 
79 
80 __attribute__ ((noinline)) void deadbeef( tsys reason ) {
81  while( 1 );
82  }
83 
84 
85 void * pp_stack; //speicher f�r stackpointer w�hrend push/pop
86 //push pc, push r0, r0<-sreg, push r0..r31
87 #define push() { \
88  asm volatile ( \
89  "push r0\n"/*push r0*/ \
90  "in r0, __SREG__\n" \
91  "cli\n" /*push sreg, push r1..r31 */\
92  "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" \
93  "in r0, __SP_L__\n" \
94  "sts pp_stack, r0\n" \
95  "in r0, __SP_H__\n" \
96  "sts pp_stack+1, r0\n" \
97  ); \
98  }
99 
100 //pop r31 .. r0, sreg<-r0, pop r0
101 #define pop() { \
102  asm volatile ( \
103  "lds r0, pp_stack \n" \
104  "out __SP_L__, r0 \n" \
105  "lds r0, pp_stack+1\n" \
106  "out __SP_H__, r0\n" \
107  /*pop r31..sreg*/ \
108  "pop r31\npop r30\npop r29\npop r28\npop r27\npop r26\npop r25\npop r24\npop r23\npop r22\npop r21\npop r20\npop r19\npop r18\npop r17\npop r16\npop r15\npop r14\npop r13\npop r12\npop r11\npop r10\npop r9\npop r8\npop r7\npop r6\npop r5\npop r4\npop r3\npop r2\npop r1\npop r0\n" \
109  "out __SREG__, r0\n" \
110  "pop r0\n"/*pop r0*/ \
111  "sei\n" \
112  ); \
113  }
114 
115 void __attribute__ ((naked)) eRTK_scheduler( void ) { /* start der hoechstprioren ready task, notfalls idle */
116  push();
117  stackptr[akttask]=pp_stack;
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 {
133  akttask=pTaskRdy->tid;
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 !
137  akttask=pTaskRdy->tid;
138  }
139  }
140  else akttask=pTaskRdy->tid; //nimm das erstbeste aus der ready liste ;)
141  }
142  else deadbeef( SYS_NOTASK );
143  //
144  pp_stack=stackptr[akttask];
145  pop();
146  sei();
147  asm volatile ( "ret" );
148  }
149 
150 
151 void eRTK_go( void ) { /* start der hoechstprioren ready task, notfalls idle */
152  if( pTaskRdy ) akttask=pTaskRdy->tid;
153  else deadbeef( SYS_NOTASK );
154  //
155  eRTK_up=1;
156  pp_stack=stackptr[akttask];
157  pop();
158  asm volatile( "ret" );
159  }
160 
161 /* Prinzip der Ready Liste:
162  * pTskRdy ist nie 0 und zeigt zumindest auf den tcd[0]==idle task.
163  * wenn eine task bereit wird geschieht dies durch einhaengen in die liste
164  * und zwar vor der ersten task mit niedrigerer prio.
165  * zunaechst also pTskRdy->tcd[0]->0 wird pTskRdy->tcd[x]->tcd[0]->0 ( falls tcd[x].prio>0 )
166  * wenn tcd[y].prio > tcd[x].prio dann pTskRdy->tcd[y]->tcd[x]->tcd[0]->0
167  * sonst pTskRdy->tcd[x]->tcd[y]->0
168  * usw.
169  * Der scheduler sucht immer ob tcd[akttask] noch in der liste steht.
170  * wenn nein, nimmt er den ersten eintrag der liste zum start ( highest prio task always runs )
171  * wenn ja, schaut er nach ob der nachfolger gleiche pri hat. ( round robin )
172  * wenn ja nimmt er diesen ( weiterschaltung in prio ebene )
173  * wenn nein nimmt er den ersten eintrag der liste ( das ist ja immer der mit der hoechsten prio )
174  *
175  * Ausgangszustand nur mit idle task:
176  *
177  * pTsk-->tcd[0]
178  * pnext=0
179  * pbefore=0
180  *
181  * task 2 dazu mit insertat( this=&tcd[0], new=&tcd[2] )
182  *
183  * new this
184  * pTsk-->tcd[2] tcd[0]
185  * pnext------->pnext=0
186  * pbefore=0 <--pbefore
187  *
188  * task 1 dazu mit insertat( this=&tcd[0], new=&tcd[1] )
189  *
190  * new this
191  * pTsk-->tcd[2] tcd[1] tcd[0]
192  * pnext------->pnext------->pnext=0
193  * pbefore=0 <--pbefore<-----pbefore
194  *
195  */
196 static __inline__ void insertat( s_tcd *pthis, s_tcd *newone ) { //newone vor pthis eintragen
197  if( !pthis || !newone ) deadbeef( SYS_NULLPTR );
198  ATOMIC_BLOCK( ATOMIC_RESTORESTATE ) {
199  if( pthis->pbefore == NULL ) { //der erste tcd
200  pTaskRdy=newone;
201  newone->pbefore=NULL;
202  }
203  else { //tcd in der kette
204  pthis->pbefore->pnext=newone;
205  newone->pbefore=pthis->pbefore;
206  }
207  newone->pnext=pthis;
208  pthis->pbefore=newone;
209  }
210  }
211 
212 static __inline__ void removeat( s_tcd *pthis ) { //den node pthis austragen
213  ATOMIC_BLOCK( ATOMIC_RESTORESTATE ) {
214  if( pthis==NULL || pthis==&tcd[0] ) { //0 oder idle task
216  }
217  if( pthis->pbefore==NULL ) { //es ist der erste block auf den pTskReady zeigt
218  if( pthis->pnext==NULL ) { //und er hat keinen nachfolger den man vorziehen kann
220  }
221  pTaskRdy=pthis->pnext; //nachfolger einhaengen
222  pthis->pnext->pbefore=NULL;
223  }
224  else { //mittendrin in der kette
225  pthis->pbefore->pnext=pthis->pnext;
226  pthis->pnext->pbefore=pthis->pbefore;
227  }
228  pthis->pnext=NULL; //diesen block aus verkettung nehmen
229  pthis->pbefore=NULL;
230  }
231  }
232 
233 uint8_t eRTK_GetTid( void ) { //holen der eigenen task id
234  return akttask;
235  }
236 
237 //Verwaltung der ready list mit einfuegen/ausfuegen in der reihenfolge der prio
238 void eRTK_SetReady( uint8_t tid ) {
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  }
253 
254 //pTskRdy->tcdx->tcdy->0 es muss immer mindestens ein tcd (idle) in der liste bleiben
255 void eRTK_SetSuspended( uint8_t tid ) { //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  }
268 
269 void eRTK_wefet( uint8_t timeout ) {
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;
274  eRTK_SetSuspended( akttask );
275  eRTK_scheduler();
276  }
277  }
278  }
279 
280 void eRTK_Sleep_ms( uint16_t ms ) {
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  }
292 
293 //semaphoren
294 #define ANZSEMA 10
295 static uint8_t sema[ANZSEMA];
296 
297 static inline __attribute__((__always_inline__)) uint8_t xch ( uint8_t volatile *p, uint8_t x ) {
298  //wenn die cpu xch kennt:
299  // __asm volatile ("xch %a1,%0" : "+r"(x) : "z"(p) : "memory");
300  register uint8_t tmp;
301  ATOMIC_BLOCK( ATOMIC_RESTORESTATE ) {
302  tmp=*p;
303  *p=x;
304  }
305  return tmp;
306  //return x;
307  }
308 
309 void eRTK_get_sema( uint8_t semaid ) { /* 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  }
316 
317 void eRTK_free_sema( uint8_t semaid ) {
318  if( semaid>=ANZSEMA ) deadbeef( SYS_UNKNOWN );
319  xch( &sema[semaid], 0 ) ;
320  }
321 
322 void sema_init( void ) {
323  static uint8_t n;
324  for( n=0; n<ANZSEMA; n++ ) {
325  sema[n]=0; /* ff=keine task wartend */
326  }
327  }
328 
329 /*
330 stck[n][STACKSIZE]
331 - 1-+
332 - 2 |deadbeef() bei return aus der task zurueck
333 - 3-+
334 - 4-+
335 - 5 |task()
336 - 6-+
337 - 7 r0
338 - 8 SREG
339 - 9 r1
340 -10 r2
341 -11 r3
342 -12 r4
343 -13 r5
344 -14 r6
345 -15 r7
346 -16 r8
347 -17 r9
348 -18 r10
349 -19 r11
350 -20 r12
351 -21 r13
352 -22 r14
353 -23 r15
354 -24 r16
355 -25 r17
356 -26 r18
357 -27 r19
358 -28 r20
359 -29 r21
360 -30 r22-+
361 -31 r23-+param1
362 -32 r24-+
363 -33 r25-+param0
364 -34 r26
365 -35 r27
366 -36 r28
367 -37 r29
368 -38 r30
369 -39 r31
370 */
371 void eRTK_init( void ) { /* 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  }
444 
445 /*
446  Ein Prozess holt den aktuellen Zaehlerstand in ms mit eRTK_GetTimer().
447  Wenn er in 10ms erneut starten will, kann er folgendes tun:
448  uint8_t now=eRTK_GetTimer();
449  ...do something
450  eRTK_WaitUntil( now+10 );
451 */
452 union {
453  volatile uint8_t timer8[2];
454  volatile uint16_t timer16;
455  } eRTK_m_timer;
456 
457 uint8_t eRTK_GetTimer8( void ) { //256ms bis overflow
458  return eRTK_m_timer.timer8[0];
459  }
460 
461 uint16_t eRTK_GetTimer16( void ) { //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  }
468 
469 void eRTK_WaitUntil( uint8_t then ) {
470  eRTK_wefet( then-eRTK_GetTimer8() );
471  }
472 
473 
474 __inline__ void __attribute__ ( ( always_inline ) ) eRTK_timertick( void ) { //damit im irq alle register gesichert werden
475  oIDLE( 0 );
476  if( eRTK_ticks<65535u ) ++eRTK_ticks;
477  ++eRTK_m_timer.timer16;
478  s_tcd *p=tcd;
479  //timer service
480  for( uint8_t n=0; n<VANZTASK+1; n++ ) {
481  if( p->timer ) {
482  if( !--p->timer ) {
483  eRTK_SetReady( p->tid );
484  }
485  }
486  ++p;
487  }
488  if( eRTK_up && eRTK_ticks>eRTK_STARTUP_MS ) { //solange geben wir dem system zum hochlauf
489  eRTK_perfcounter[ ( eRTK_iperf++ )/*&0x0f*/ ]=eRTK_perfcount;
490  if( eRTK_perfcount<1 ) {
492  if( eRTK_MAX_OVERLOAD && eRTK_cnt_overload>eRTK_MAX_OVERLOAD ) deadbeef( SYS_OVERLOAD );
493  }
494  else eRTK_cnt_overload=0;
495  eRTK_perfcount=0;
496  }
497  if( eRTK_up ) eRTK_scheduler();
498  }
499 
500 
501 #if defined (__AVR_ATmega2560__)
502 ISR( TIMER0_OVF_vect ) { //1kHz timer
503  TCNT0=( uint8_t )( -1*TIMERPRELOAD );
504  eRTK_timertick();
505  adc_sequencer();
506  }
507 
508 static void timer0_init( void ) {
509  TCCR0B=/*(1<<CS12)|*/(1<<CS01)|(1<<CS00); //prescaler CLK/64
510  TIMSK0|=(1<<TOIE0);
511  TCNT0=( uint8_t )( -1*TIMERPRELOAD );
512  }
513 #endif
514 
515 void eRTK_timer_init( void ) {
516 #if defined (__AVR_ATmega2560__)
517  timer0_init();
518 #elif defined (__AVR_ATxmega128A1U__)
519 #endif
520  }
521 
522 
523 
524 
525 #if eRTKTEST
526 uint16_t loop1, loop2;
527 void TMain1( uint16_t param0, void *param1 ) {
528  uint16_t p0=param0;
529  uint16_t p1=param1;
530  while( 1 ) {
531  uint8_t now=eRTK_GetTimer();
532  uint32_t cnt;
533  for( cnt=0; cnt<1000; cnt++ );
534  eRTK_WaitUntil( now+10 );
535  }
536  while( 0 ) {
537  eRTK_get_sema( 0 );
538  write0( ( uint8_t* )"1234567890", 10 );
539  eRTK_free_sema( 0 );
540  }
541  while( 1 ) {
542  char tmp[100];
543  strcpy( tmp, "12345678901234567890123456789012345678901234567890" );
544  }
545  while( 1 ) {
546  eRTK_wefet( 1 );
547  ++loop1;
548  eRTK_wefet( 1 );
549  --loop1;
550  }
551  }
552 
553 void TMain2( uint16_t param0, void *param1 ) {
554  uint16_t p0=param0;
555  uint16_t p1=param1;
556  while( 0 ) {
557  eRTK_get_sema( 0 );
558  write0( ( uint8_t* )"abcdefghij", 10 );
559  eRTK_free_sema( 0 );
560  }
561  while( 1 ) {
562  char tmp[100];
563  strcpy( tmp, "abcdefghijklabcdefghijklabcdefghijklabcdefghijkl" );
564  }
565  while( 1 ) {
566  eRTK_wefet( 1 );
567  ++loop2;
568  eRTK_wefet( 1 );
569  --loop2;
570  }
571  }
572 #endif
volatile uint8_t timer8[2]
Definition: eRTK.c:453
#define ANZSEMA
Definition: eRTK.c:294
uint8_t eRTK_GetTimer8(void)
Definition: eRTK.c:457
void eRTK_go(void)
Definition: eRTK.c:151
#define eRTK_MAX_OVERLOAD
Definition: eRTK.h:30
uint8_t eRTK_GetTid(void)
Definition: eRTK.c:233
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
void eRTK_Sleep_ms(uint16_t ms)
Definition: eRTK.c:280
void eRTK_wefet(uint8_t timeout)
Definition: eRTK.c:269
volatile uint8_t eRTK_iperf
Definition: eRTK.c:55
void eRTK_get_sema(uint8_t semaid)
Definition: eRTK.c:309
Definition: eRTK.c:27
#define ERTK_STACKSIZE
Definition: eRTK.h:32
volatile uint16_t eRTK_ticks
Definition: eRTK.c:56
void sema_init(void)
Definition: eRTK.c:322
ISR(USART0_RX_vect)
Definition: uart.c:104
volatile uint16_t eRTK_perfcount
Definition: eRTK.c:53
#define oIDLEfast(a)
Definition: eRTK.h:42
s_tcd * pTaskRdy
Definition: eRTK.c:40
void(* task)(uint16_t param0, void *param1)
Definition: eRTK.h:68
#define VANZTASK
Definition: eRTK.h:15
void eRTK_init(void)
Definition: eRTK.c:371
#define TIMERPRELOAD
Definition: eRTK.h:21
#define eRTK_STARTUP_MS
Definition: eRTK.h:29
struct s_tcd * pnext
Definition: eRTK.c:28
void eRTK_WaitUntil(uint8_t then)
Definition: eRTK.c:469
uint8_t prio
Definition: eRTK.h:69
struct s_tcd * pbefore
Definition: eRTK.c:29
struct s_tcd s_tcd
#define oIDLE(a)
Definition: eRTK.h:41
void * pp_stack
Definition: eRTK.c:85
volatile uint8_t eRTK_cnt_overload
Definition: eRTK.c:57
volatile uint8_t eRTK_up
Definition: eRTK.c:52
void eRTK_SetReady(uint8_t tid)
Definition: eRTK.c:238
void deadbeef(tsys reason)
uint8_t stack[VANZTASK+1][ERTK_STACKSIZE] __attribute__((aligned(256)))
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
union @0 eRTK_m_timer
void * param1
Definition: eRTK.h:71
void eRTK_timer_init(void)
Definition: eRTK.c:515
volatile uint16_t eRTK_perfcounter[256]
Definition: eRTK.c:54
const t_eRTK_tcb rom_tcb[VANZTASK]
Definition: main.c:90
void * stackptr[VANZTASK+1]
Definition: eRTK.c:22
void eRTK_free_sema(uint8_t semaid)
Definition: eRTK.c:317
uint8_t adc_sequencer(void)
tsys
Definition: eRTK.h:50
uint16_t eRTK_GetTimer16(void)
Definition: eRTK.c:461
#define push()
Definition: eRTK.c:87
uint8_t prio
Definition: eRTK.c:31
#define pop()
Definition: eRTK.c:101
volatile uint16_t timer16
Definition: eRTK.c:454
uint16_t param0
Definition: eRTK.h:70