My Project - RET HER  versionsnr
krnl.h
Go to the documentation of this file.
1 /******************************************************
2  x
3 * *
4  | |/ /___| _ \| \ | | ___| |
5  | ' // _ \ |_) | \| |/ _ \ |
6  | . \ __/ _ <| |\ | __/ |___
7  |_|\_\___|_| \_\_| \_|\___|_____|
8 * *
9 * *
10  you are watching krnl.h
11 * *
12  March 2015,2016,..,2018
13  Author: jdn
14  13 March 2018
15 * *
16 *******************************************************
17 
18  (simple not - not ?! :-) )
19  my own small KeRNeL adapted for Arduino
20 
21  KRNL
22 
23  this version adapted for Arduino
24 
25  (C) 2012,2013,2014
26  2017,2018,2019
27  2020,2021
28 
29  config info on the fly
30  int k_config = KRNLTMR | (DYNMEM << 4) | (KRNLBUG << 5) | (sBACKSTOPPER << 6)
31 
32  Jens Dalsgaard Nielsen <jdn@es.aau.dk>
33  http://es.aau.dk/staff/jdn
34  Section of Automation & Control
35  Aalborg University,
36  Denmark
37 
38  "THE BEER-WARE LICENSE" (frit efter PHK)
39  <jdn@es.aau.dk> wrote this file. As long as you
40  retain this notice you can do whatever you want
41  with this stuff, but You shall add your
42  name and email and date for your
43  modification.
44 
45  If we meet some day, and you think
46  this stuff is worth it ...
47  you can buy me a beer in return :-)
48  or if you are real happy then ...
49  single malt will be well received :-)
50 
51  Use it at your own risk - no warranty
52 
53  tested with duemilanove w/328, uno R3,
54  seeduino 1280 and mega2560 1284p and 2561
55 *****************************************************
56  remember to update in krnl.c !!!
57 *****************************************************/
58 #define KRNL_VRS 20210114
59 
60 /***********************
61 
62  WE DO RUN N TIMER 0 AS STANDARD AND Ticks is 1msec independet og parm in calll to k_start !!!!
63  NB NB ABOUT WRAP AROUND
64 
65  Krnl maintain a milisecond timer (k_millis_counter)
66  It s 32 bit unsigned long so it wraps around after 49.7 days.
67  As all timing internal in krnl is relative (from now) then
68  wrap around will have no influence on krnl !!!fk_eat
69 
70  NB NB ABOUT TIMERS PORTS ETC
71 
72  You can configure krnl to use timer 1,2,3,4,5
73 
74  If you want to use timer 0 then you need to
75 
76  - set KRNLTMR = 0 just below in USER CONFIGURATION PART
77  - mangle with Arduino library code in ...
78  hardware/arduino/avr/cores/arduino/wiring.c
79  rename ISR ... with function head:
80  #if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) | defined(__AVR_ATtiny84__)
81  ISR(TIM0_OVF_vect)
82  #else
83  ISR(TIMER0_OVF_vect)
84  #endif
85  to something else : mayby void kurt()
86 
87  This is because krnl install an ISR on timer0 and there cant be two
88  Krnl to maintain the millis counters so everything with millis, micros etc is as usual.
89 
90 
91  Buth normally you cant use timer 0 bq it is used for millis and preallocated.
92 
93  See below
94 
95  When using a timer you must be aware of that it will prohibit you from things like
96  - tone (pwm sound) uses timer2
97 
98  ... from http://blog.oscarliang.net/arduino-timer-and-interrupt-tutorial/
99 
100  Timer0:
101  - 8bit timer.
102  - In the Arduino world Timer0 is been used for the timer functions, like delay(), millis() and micros().
103  - If you change Timer0 registers, this may influence the Arduino timer function.
104  - So you should know what you are doing.
105 
106  - 16bit timer.
107  - In the Arduino world the Servo library uses Timer1 on Arduino Uno (Timer5 on Arduino Mega).
108 
109  Timer2:
110  - 8bit timer like Timer0.
111  - In the Arduino world the tone() function uses Timer2.
112 
113  Timer3 16 bits
114  - 1280/1284P and 2560 only
115 
116  Timer4, Timer5 16 bits
117  - 1280 and 2560 only
118 
119  On Uno
120  - Pins 5 and 6: controlled by timer0
121  - Pins 9 and 10: controlled by timer1
122  - Pins 11 and 3: controlled by timer2
123 
124  On the Arduino Mega we have 6 timers and 15 PWM outputs:
125 
126  TODO pinout below need checkup
127 
128  - Pins 4 and 13: controlled by timer0
129  - Pins 11 and 12: controlled by timer1
130  - Pins 9 and10: controlled by timer2
131  - Pin 2, 3 and 5: controlled by timer 3
132  - Pin 6, 7 and 8: controlled by timer 4
133  - Pin 46, 45 and 44:: controlled by timer 5
134 
135  ... from http://arduino-info.wikispaces.com/Timers-Arduino
136 
137  - Servo Library uses Timer1.
138  -- You can’t use PWM on Pin 9, 10 when you use the Servo Library on an Arduino.
139  -- For Arduino Mega it is a bit more difficult. The timer needed depends on the number of servos.
140  -- Each timer can handle 12 servos.
141  -- For the first 12 servos timer 5 will be used (losing PWM on Pin 44,45,46).
142  -- For 24 Servos timer 5 and 1 will be used (losing PWM on Pin 11,12,44,45,46)..
143  -- For 36 servos timer 5, 1 and 3 will be used (losing PWM on Pin 2,3,5,11,12,44,45,46)..
144  -- For 48 servos all 16bit timers 5,1,3 and 4 will be used (losing all PWM pins).
145 
146  - Pin 11 has shared functionality PWM and MOSI.
147  -- MOSI is needed for the SPI interface, You can’t use PWM on Pin 11 and the SPI interface at the same time on Arduino.
148  -- On the Arduino Mega the SPI pins are on different pins.
149 
150  - tone() function uses at least timer2.
151  -- You can’t use PWM on Pin 3,11 when you use the tone() function an Arduino and Pin 9,10 on Arduino Mega.
152 
153  SO BEWARE !!!
154 
155 
156  PERFORMANCE
157 
158  std internal speed 1 kHz
159 
160  Rudimentary prog with one task the timer ISR takes about 21 usec
161  Uno, leonardo and mega measures the same
162 
163  period:
164  timer0 1024 usec for 1 msec ...
165  timer1,2,3... 1007 usec for 1 msec
166 
167 
168  >>>>>>>>>>>>
169 
170  MODIFY OF/hardware/arduino/avr/cores/arduino/wiring.c
171 
172  I have added the MOD part (MOD: modification)
173 
174  So if you go for timer0
175  1)remove the // in front of #define MOD
176  2) change here in krnl.h KRNLTMR to 0 for your architecture
177 
178  ONLY SUPPORT FOR AVR's (uno,leonardo,nano,mega,...)
179 
180 
181 
182  //#define MOD
183 
184  #if defined (MOD)
185 
186  void justFakeFctHead()
187  #else
188  #if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
189  ISR(TIM0_OVF_vect)
190  769769876987 lalalalalalal
191  #else
192  ISR(TIMER0_OVF_vect)
193  #endif
194 
195  #endif
196  >>>>>>>>>>>>
197 
198 ***********************************************************/
199 
200 #ifndef sbi
201 #define sbi(r, b) r |= _BV(b)
202 #endif
203 
204 #ifndef cbi
205 #define cbi(r, b) r &= ~_BV(b)
206 #endif
207 
208 #ifndef rbi
209 #define cbi(r, b) r &= ~_BV(b)
210 #endif
211 
212 #ifndef KRNL
213 
214 // blink with led 13 when dmy is running
215 #define K_BUGBLINK 0
216 // 1 for activate
217 
218 #define KRNL
219 
220 // breakout fct to be called in dispatcher
221 // or 0
222 #define KRNLBUG 1
223 
224 // >>>>>>>>>>>>>>>>> USER CONFIGURATION PART <<<<<<<<<<<<<<<<<<
225 
226 // if you want k_malloc
227 // NB k_free wont release mem due to possible fragmentation
228 // SO DONT USE k_free
229 
230 #define DYNMEMORY 1
231 
232 // or 0 for deactivate
233 
234 // watchdog 1 sec
235 // JDN #define WDT_TIMER 1
236 #define WDT_PERIOD WDTO_1S
237 
238 #define QHD_PRIO 102 // Queue head prio - for sentinel use
239 
240 #define DMY_PRIO (QHD_PRIO - 2) // dummy task prio (0 == highest prio)
241 #define ZOMBI_PRIO (QHD_PRIO - 1)
242 #define DMY_STK_SZ 90 // staksize for dummy
243 #define MAIN_PRIO 50 // main task prio
244 #define STAK_HASH 0x5c // just a hashcode
245 #define MAX_SEM_VAL 50 // NB is also max for nr elem in msgQ !
246 #define MAX_INT 0x7FFF
247 // not in use #define SEM_MAX_DEFAULT 50
248 #define SEM_MAX_VALUE 32000
249 
250 // BACKSTOPPER wraps a looping fct around your task so it will just restart
251 // is the task leaves the task body code
252 // like loop function
253 // BEWARE bq local variables in the task body just evaporate
254 #define BACKSTOPPER 1
255 
256 #define CEILINGFAIL -3
257 
258 /* which timer to use for krnl heartbeat
259  timer 0 ( 8 bit) is normally used by millis - avoid !
260  timer 1 (16 bit)
261  timer 2 ( 8 bit) not 32u4
262  timer 3 (16 bit) 32u4/1280/1284p/2560 only
263  timer 4 (16 bit) 1280/2560 only (MEGA)
264  timer 5 (16 bit) 1280/2560 only (MEGA)
265 */
266 
267 // XXXXXXXXXXXXXXXXXXXXXXXXXX
268 
269 // DONT CHANGE TO OTHER TIMERS IF YOU DONT KNOW WHAT YOU ARE DOING /JDN
270 
271 #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)
272 #define KRNLTMR 0
273 
274 #elif defined(__AVR_ATmega1284P__)
275 #define KRNLTMR 0
276 
277 #elif defined(__AVR_ATmega328P__)
278 #define KRNLTMR 0
279 
280 #elif defined(__AVR_ATmega32U4__)
281 #define KRNLTMR 0
282 
283 #else
284 #error "unknown AVR cpu type - bad place to come"
285 
286 #endif
287 // END USER CONFIGURATION
288 
289 // check for legal timers
290 #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__)
291 
292 #if (KRNLTMR != 0) && (KRNLTMR != 1) && (KRNLTMR != 2)
293 #error "bad timer selection for krnl heartbeat(168/328/328p/...)"
294 #endif
295 
296 #endif
297 
298 #if defined(__AVR_ATmega32U4__)
299 
300 #if (KRNLTMR != 0) && (KRNLTMR != 1) && (KRNLTMR != 3)
301 #error "bad timer selection for krnl heartbeat(32u4)...)"
302 #endif
303 
304 #endif
305 
306 #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)
307 
308 #if (KRNLTMR != 0) && (KRNLTMR != 1) && (KRNLTMR != 2) && (KRNLTMR != 3) && (KRNLTMR != 4) && (KRNLTMR != 5)
309 #error "bad timer for krnl heartbeat(1280/2560/2561) in krnl"
310 #endif
311 
312 #endif
313 
314 #if defined(__AVR_ATmega1284P__)
315 
316 #if (KRNLTMR != 0) && (KRNLTMR != 1) && (KRNLTMR != 2) && (KRNLTMR != 3)
317 #error "bad timer for krnl heartbeat(1284P) in krnl"
318 #endif
319 
320 #endif
321 
322 //----------------------------------------------------------
323 
324 #ifdef __cplusplus
325 extern "C"
326 {
327 #endif
328 
329 extern int k_config;
330 extern int k_task, k_sem, k_msg;
331 extern volatile char krnl_preempt_flag;
332 extern char dmy_stk[DMY_STK_SZ];
333 
334 /***** KeRNeL data types *****/
335 struct k_t
336 {
337 #if BACKSTOPPER == 1
338  void (*pt)(void);
339 #endif
340  unsigned char nr;
341  struct k_t *next, // task,sem: double chain lists ptr
342  *pred; // task,sem: double chain lists ptr
343  volatile char sp_lo, // sem:vacant | task: low 8 byte of stak adr
344  sp_hi; // sem: vacant |task: high 8 byte of stak adr
345  char prio, // task & sem: priority
346  ceiling_prio, // sem
347  saved_prio; // semaohore
348  volatile int cnt1, // sem: sem counter | task: ptr to stak
349  cnt2, // asem: dyn part of time counter | task: timeout
350  cnt3, // sem: preset timer value | task: ptr to Q we are hanging in
351  maxv, // sem: max value | task: org priority
352  clip; // sem: counter for lost signals | task: vacant
353 };
354 
355 struct k_msg_t
356 {
357  // msg type
358  unsigned char nr;
359  struct k_t *sem;
360  char *pBuf; // ptr to user supplied ringbuffer
361  volatile int nr_el, el_size, lost_msg;
362  volatile int r, w, cnt;
363 };
364 
365 /***** KeRNeL variables *****/
366 
367 extern struct k_t *task_pool, *sem_pool, AQ, // activeQ
368  *pmain_el, *pAQ, *pDmy, // ptr to dummy task descriptor
369  *pRun, // ptr to running task
371 
372 extern struct k_msg_t *send_pool;
373 
374 extern char nr_task, nr_sem, nr_send;
375 
376 extern volatile char k_running; // no running
377 
378 extern volatile char k_err_cnt; // every time an error occurs cnt is incr by one
379 extern unsigned long k_millis_counter;
380 extern char k_preempt_flag;
381 
382 /******************************************************
383  MACROS MACROS
384 
385  PUSHREGS AND POPREGS
386  is actual staklayout plus task address at top
387  A push/pop takes 2 cycles
388  a call takes 3 cycles
389  ret/iret 3-4 cycles
390  So a PUSHREGS is 33 instructions(@ 2 cycles) = 66 cycles ~= 66 cycles /"16 MHz" ~= 4.1 usec
391  So an empty iSR which preserves all registers takes 2*4.1usec + 8-10 cycles (intr + iret) ~= 9 usec
392  So max isr speed with all regs saved is around 100 kHz but then with no code inside ISR !
393 
394  WARNING
395  The 2560 series has 3 bytes PC the rest only 2 bytes PC !!! (PC. program counter)
396  and no tall has rampz and eind register
397 
398  REGISTER NAMING AND INTERNAL ADRESSING
399 
400  https://en.wikipedia.org/wiki/Atmel_AVR_instruction_set
401  Register I/O address Data address
402  SREG 0x3F 0x5F
403  SP 0x3E:0x3D 0x5E:0x5D
404  EIND 0x3C 0x5C
405  RAMPZ 0x3B 0x5B
406  RAMPY 0x3A 0x5A
407  RAMPX 0x39 0x59
408  RAMPD 0x38 0x58
409  A typical ATmega memory map may look like:
410 
411  Data address I/O address Contents
412  0x0000 – 0x001F Registers R0 – R31
413 
414  general purpose regs
415  0 0
416  1 1
417  2 2
418  3 3
419  4 4
420  5 5
421  6 6
422  7 7
423  8 8
424  9 9
425  a 10
426  b 11
427  c 12
428  d 13
429  e 14
430  f 15
431  10 16
432  11 17
433  12 18
434  13 19
435  14 20
436  15 21
437  16 22
438  17 23
439  18 24
440  19 25
441  1a 26 Xref L
442  1b 27 Xreg H
443  1c 28 Yreg L
444  1d 29 Yreg H
445  1e 30 Zreg L
446  1f 31 Zreg H
447 
448  0x0020 – 0x003F 0x00 – 0x1F I/O registers (bit-addressable)
449  0x0040 – 0x005F 0x20 – 0x3F I/O registers (not bit-addressable)
450  0x0060 – 0x00FF Extended I/O registers (memory-mapped I/O only)
451  0x0100 – RAMEND Internal SRAM
452 
453  Register addresses
454  IO adr data addr
455  0x3f SREG 0x5f
456  0x3e SPH
457  0x3d SPL
458  0x3c EIND 0x5c 1280/2560 only
459  0x3b RAMPZ 0x5b 1280/2560/1284p only
460  ...
461  0x1f R31
462  etc
463  0x01 R1
464  0x00 R0
465 
466  PC is NOT available
467 */
468 
469 #define lo8(X) ((unsigned char)((unsigned int)(X)))
470 #define hi8(X) ((unsigned char)((unsigned int)(X) >> 8))
471 
472 extern volatile char k_bug_on;
473 
474 #if KRNLBUG == 1
475 #define K_CHG_STAK() \
476  if (pRun != AQ.next) \
477  { \
478  pRun->sp_lo = SPL; \
479  pRun->sp_hi = SPH; \
480  pRun = AQ.next; \
481  k_breakout(); \
482  SPL = pRun->sp_lo; \
483  SPH = pRun->sp_hi; \
484  }
485 
486 #else
487 #define K_CHG_STAK() \
488  if (pRun != AQ.next) \
489  { \
490  pRun->sp_lo = SPL; \
491  pRun->sp_hi = SPH; \
492  pRun = AQ.next; \
493  SPL = pRun->sp_lo; \
494  SPH = pRun->sp_hi; \
495  }
496 
497 #endif
498 
499 // MISSING no code 1284p
500 
501 /* below: r1 must/shall always assumed to be zero in c code (gcc issue I think) */
502 
503 // AVR / ARDUINO PART PUSH POP
504 // 0x3b RAMPZ extended z-pointer register
505 // 0x3c EIND extended indirect register
506 
507 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2561__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega32U4__)
508 
509 #define DI() __asm__ volatile("cli")
510 #define EI() __asm__ volatile("sei")
511 #define RETI() __asm__ volatile("reti")
512 
513 #endif
514 
515 /* below: r1 must/shall always assumed to be zero in c code (gcc issue I think) */
516 
517 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2561__)
518 
519 // 0x3b RAMPZ extended z-pointer register
520 // 0x3c EIND extended indirect register
521 
522 #define PUSHREGS() __asm__ volatile( \
523  "push r1 \n\t" \
524  "push r0 \n\t" \
525  "in r0, __SREG__ \n\t" \
526  "cli \n\t" \
527  "push r0 \n\t" \
528  "in r0 , 0x3b \n\t" \
529  "push r0 \n\t" \
530  "in r0 , 0x3c \n\t" \
531  "push r0 \n\t" \
532  "clr r1 \n\t" \
533  "push r2 \n\t" \
534  "push r3 \n\t" \
535  "push r4 \n\t" \
536  "push r5 \n\t" \
537  "push r6 \n\t" \
538  "push r7 \n\t" \
539  "push r8 \n\t" \
540  "push r9 \n\t" \
541  "push r10 \n\t" \
542  "push r11 \n\t" \
543  "push r12 \n\t" \
544  "push r13 \n\t" \
545  "push r14 \n\t" \
546  "push r15 \n\t" \
547  "push r16 \n\t" \
548  "push r17 \n\t" \
549  "push r18 \n\t" \
550  "push r19 \n\t" \
551  "push r20 \n\t" \
552  "push r21 \n\t" \
553  "push r22 \n\t" \
554  "push r23 \n\t" \
555  "push r24 \n\t" \
556  "push r25 \n\t" \
557  "push r26 \n\t" \
558  "push r27 \n\t" \
559  "push r28 \n\t" \
560  "push r29 \n\t" \
561  "push r30 \n\t" \
562  "push r31 \n\t")
563 
564 #define POPREGS() __asm__ volatile( \
565  "pop r31 \n\t" \
566  "pop r30 \n\t" \
567  "pop r29 \n\t" \
568  "pop r28 \n\t" \
569  "pop r27 \n\t" \
570  "pop r26 \n\t" \
571  "pop r25 \n\t" \
572  "pop r24 \n\t" \
573  "pop r23 \n\t" \
574  "pop r22 \n\t" \
575  "pop r21 \n\t" \
576  "pop r20 \n\t" \
577  "pop r19 \n\t" \
578  "pop r18 \n\t" \
579  "pop r17 \n\t" \
580  "pop r16 \n\t" \
581  "pop r15 \n\t" \
582  "pop r14 \n\t" \
583  "pop r13 \n\t" \
584  "pop r12 \n\t" \
585  "pop r11 \n\t" \
586  "pop r10 \n\t" \
587  "pop r9 \n\t" \
588  "pop r8 \n\t" \
589  "pop r7 \n\t" \
590  "pop r6 \n\t" \
591  "pop r5 \n\t" \
592  "pop r4 \n\t" \
593  "pop r3 \n\t" \
594  "pop r2 \n\t" \
595  "pop r0 \n\t" \
596  "out 0x3c , r0 \n\t " \
597  "pop r0 \n\t" \
598  "out 0x3b , r0 \n\t " \
599  "pop r0 \n\t" \
600  "out __SREG__ , r0 \n\t " \
601  "pop r0 \n\t" \
602  "pop r1 \n\t")
603 
604 #elif defined(__AVR_ATmega1284P__)
605 
606 // 0x3b RAMPZ extended z-pointer register
607 // 0x3c EIND extended indirect register
608 
609 #define PUSHREGS() __asm__ volatile( \
610  "push r1 \n\t" \
611  "push r0 \n\t" \
612  "in r0, __SREG__ \n\t" \
613  "cli \n\t" \
614  "push r0 \n\t" \
615  "in r0 , 0x3b \n\t" \
616  "push r0 \n\t" \
617  "clr r1 \n\t" \
618  "push r2 \n\t" \
619  "push r3 \n\t" \
620  "push r4 \n\t" \
621  "push r5 \n\t" \
622  "push r6 \n\t" \
623  "push r7 \n\t" \
624  "push r8 \n\t" \
625  "push r9 \n\t" \
626  "push r10 \n\t" \
627  "push r11 \n\t" \
628  "push r12 \n\t" \
629  "push r13 \n\t" \
630  "push r14 \n\t" \
631  "push r15 \n\t" \
632  "push r16 \n\t" \
633  "push r17 \n\t" \
634  "push r18 \n\t" \
635  "push r19 \n\t" \
636  "push r20 \n\t" \
637  "push r21 \n\t" \
638  "push r22 \n\t" \
639  "push r23 \n\t" \
640  "push r24 \n\t" \
641  "push r25 \n\t" \
642  "push r26 \n\t" \
643  "push r27 \n\t" \
644  "push r28 \n\t" \
645  "push r29 \n\t" \
646  "push r30 \n\t" \
647  "push r31 \n\t")
648 
649 #define POPREGS() __asm__ volatile( \
650  "pop r31 \n\t" \
651  "pop r30 \n\t" \
652  "pop r29 \n\t" \
653  "pop r28 \n\t" \
654  "pop r27 \n\t" \
655  "pop r26 \n\t" \
656  "pop r25 \n\t" \
657  "pop r24 \n\t" \
658  "pop r23 \n\t" \
659  "pop r22 \n\t" \
660  "pop r21 \n\t" \
661  "pop r20 \n\t" \
662  "pop r19 \n\t" \
663  "pop r18 \n\t" \
664  "pop r17 \n\t" \
665  "pop r16 \n\t" \
666  "pop r15 \n\t" \
667  "pop r14 \n\t" \
668  "pop r13 \n\t" \
669  "pop r12 \n\t" \
670  "pop r11 \n\t" \
671  "pop r10 \n\t" \
672  "pop r9 \n\t" \
673  "pop r8 \n\t" \
674  "pop r7 \n\t" \
675  "pop r6 \n\t" \
676  "pop r5 \n\t" \
677  "pop r4 \n\t" \
678  "pop r3 \n\t" \
679  "pop r2 \n\t" \
680  "pop r0 \n\t" \
681  "out 0x3b , r0 \n\t " \
682  "pop r0 \n\t" \
683  "out __SREG__ , r0 \n\t " \
684  "pop r0 \n\t" \
685  "pop r1 \n\t")
686 
687 #elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega32U4__)
688 
689 // 328p etc
690 #define PUSHREGS() __asm__ volatile( \
691  "push r1 \n\t" \
692  "push r0 \n\t" \
693  "in r0, __SREG__ \n\t" \
694  "cli \n\t" \
695  "push r0 \n\t" \
696  "clr r1 \n\t" \
697  "push r2 \n\t" \
698  "push r3 \n\t" \
699  "push r4 \n\t" \
700  "push r5 \n\t" \
701  "push r6 \n\t" \
702  "push r7 \n\t" \
703  "push r8 \n\t" \
704  "push r9 \n\t" \
705  "push r10 \n\t" \
706  "push r11 \n\t" \
707  "push r12 \n\t" \
708  "push r13 \n\t" \
709  "push r14 \n\t" \
710  "push r15 \n\t" \
711  "push r16 \n\t" \
712  "push r17 \n\t" \
713  "push r18 \n\t" \
714  "push r19 \n\t" \
715  "push r20 \n\t" \
716  "push r21 \n\t" \
717  "push r22 \n\t" \
718  "push r23 \n\t" \
719  "push r24 \n\t" \
720  "push r25 \n\t" \
721  "push r26 \n\t" \
722  "push r27 \n\t" \
723  "push r28 \n\t" \
724  "push r29 \n\t" \
725  "push r30 \n\t" \
726  "push r31 \n\t")
727 
728 #define POPREGS() __asm__ volatile( \
729  "pop r31 \n\t" \
730  "pop r30 \n\t" \
731  "pop r29 \n\t" \
732  "pop r28 \n\t" \
733  "pop r27 \n\t" \
734  "pop r26 \n\t" \
735  "pop r25 \n\t" \
736  "pop r24 \n\t" \
737  "pop r23 \n\t" \
738  "pop r22 \n\t" \
739  "pop r21 \n\t" \
740  "pop r20 \n\t" \
741  "pop r19 \n\t" \
742  "pop r18 \n\t" \
743  "pop r17 \n\t" \
744  "pop r16 \n\t" \
745  "pop r15 \n\t" \
746  "pop r14 \n\t" \
747  "pop r13 \n\t" \
748  "pop r12 \n\t" \
749  "pop r11 \n\t" \
750  "pop r10 \n\t" \
751  "pop r9 \n\t" \
752  "pop r8 \n\t" \
753  "pop r7 \n\t" \
754  "pop r6 \n\t" \
755  "pop r5 \n\t" \
756  "pop r4 \n\t" \
757  "pop r3 \n\t" \
758  "pop r2 \n\t" \
759  "pop r0 \n\t" \
760  "out __SREG__ , r0 \n\t " \
761  "pop r0 \n\t" \
762  "pop r1 \n\t")
763 
764 #else
765 #error "unknown arch"
766 #endif
767 
768 // function prototypes
769 // naming convention
770 // k_... function do a DI/EI and can impose task shift
771 // ki_... expects interrupt to be disablet and do no task shift
772 // rest is internal functions
773 
774 #if DYNMEMORY == 1
775 
780 void *k_malloc(int k);
781 
788 void k_free(void *m);
789 #endif
790 
791 void __attribute__((weak)) k_enable_wdt(void);
798 unsigned long ki_millis(void);
799 
807 unsigned long k_millis(void);
808 
813 #define k_eat_msec_time(x) _delay_ms(x)
814 // JDN 180312 void k_eat_time (unsigned int eatTime);
815 
820 void k_eat_ticks(int ticks);
825 void ki_task_shift(void) __attribute__((naked));
826 
833 int k_sleep(int time);
834 
843 struct k_t * k_crt_task(void (* pTask )(void), char prio, int stkSize);
844 
852 int k_set_prio(char prio);
853 
861 struct k_t *k_crt_sem(char init_val, int maxvalue);
862 
872 int k_mut_ceil_set(struct k_t *sem, char prio);
873 
881 int k_mut_ceil_enter(struct k_t *sem, int timeout);
882 
889 int k_mut_ceil_leave(struct k_t *sem);
890 
899 int k_set_sem_timer(struct k_t *sem, int val);
900 
907 int ki_signal(struct k_t *sem);
908 
916 int k_signal(struct k_t *sem);
917 
927 int k_wait(struct k_t *sem, int timeout);
928 
935 int k_sem_signals_lost(struct k_t *sem);
936 
946 int ki_wait(struct k_t *sem, int timeout);
947 
956 int ki_semval(struct k_t *sem);
957 
965 int k_semval(struct k_t *sem);
966 
974 int ki_msg_count(struct k_msg_t *m);
975 
983 int k_msg_count(struct k_msg_t *m);
984 
985 /*********************************************************************
986 ************************* DEBUG BREAKOUT FUNCTIONS *******************
987 **********************************************************************
988 
989  Breakout functions can be removed by commenting out define of
990  KRNLBUG in krnl.h (located around line 216)
991 
992  All semaphore calls k_sem_clip, k_sem_signal, k_Sem_wait are all called
993  AFTER decrement/incr of semaphore has taken place BUT before eventually
994  taskshift.
995 
996  For message buffers/semaphores an internal semaphore is used for synchronization
997  so referring to the msgQ is by
998  struct k_msg_t *msgSem; msgSem->sem->nr
999 
1000 */
1001 
1011 #if KRNLBUG == 1
1012 void __attribute__((weak)) k_sem_clip(unsigned char nr, int nrClip);
1013 #endif
1014 
1018 #if KRNLBUG == 1
1019 void __attribute__((weak)) k_sem_signal(unsigned char nr, int val);
1020 #endif
1021 
1027 #if KRNLBUG == 1
1028 void __attribute__((weak)) k_sem_wait(unsigned char nr, int val);
1029 #endif
1030 
1039 #if KRNLBUG == 1
1040 void __attribute__((weak)) k_send_Q_clip(unsigned char nr, int nrClip);
1041 #endif
1042 
1043 struct k_msg_t *k_crt_send_Q(int nr_el, int el_size, void *pBuf);
1044 
1055 char ki_send(struct k_msg_t *pB, void *el);
1056 
1066 char k_send(struct k_msg_t *pB, void *el);
1067 
1079 char k_receive(struct k_msg_t *pB, void *el, int timeout, int *lost_msg);
1080 
1094 char ki_receive(struct k_msg_t *pB, void *el, int *lost_msg);
1095 
1100 int k_tmrInfo(void); // tm in milliseconds
1101 
1122 int k_init(int nrTask, int nrSem, int nrMsg);
1123 
1141 int k_start(int tm); // tm in milliseconds
1142 
1150 int k_stop(unsigned int exitVal);
1151 
1155 void k_reset();
1156 
1163 #if K_BUGBLINK == 1
1164 void k_bugblink13(char on);
1165 #endif
1166 
1174 int k_stk_chk(struct k_t *t);
1175 
1182 int k_unused_stak(struct k_t *t);
1183 
1184 #ifdef NEVER
1185 
1190 char k_set_preempt(char on);
1191 
1196 char k_get_preempt(void);
1197 #endif
1198 
1202 void k_round_robbin(void);
1203 
1208 void k_release(void);
1209 
1213 int freeRam(void);
1214 
1215 #if KRNLBUG == 1
1216 
1220 void __attribute__((weak)) k_breakout(void);
1221 #endif
1222 
1223 #ifdef __cplusplus
1224 }
1225 #endif
1226 
1227 #endif // #ifndef KRNL
k_reset
void k_reset()
ki_signal
int ki_signal(struct k_t *sem)
Definition: krnl.c:830
k_mut_ceil_set
int k_mut_ceil_set(struct k_t *sem, char prio)
Definition: krnl.c:753
nrClip
void int nrClip
Definition: krnl.h:1012
k_msg
int k_msg
Definition: krnl.h:330
k_tmrInfo
int k_tmrInfo(void)
Definition: krnl.c:1453
k_sleep
int k_sleep(int time)
Definition: krnl.c:677
pAQ
struct k_t * pAQ
Definition: krnl.h:368
k_free
void k_free(void *m)
k_crt_sem
struct k_t * k_crt_sem(char init_val, int maxvalue)
Definition: krnl.c:772
k_bug_on
volatile char k_bug_on
task_pool
struct k_t * task_pool
k_crt_send_Q
struct k_msg_t * k_crt_send_Q(int nr_el, int el_size, void *pBuf)
Definition: krnl.c:1043
ki_wait
int ki_wait(struct k_t *sem, int timeout)
Definition: krnl.c:886
k_msg_count
int k_msg_count(struct k_msg_t *m)
Definition: krnl.c:1033
k_crt_task
struct k_t * k_crt_task(void(*pTask)(void), char prio, int stkSize)
Definition: krnl.c:565
k_t::clip
volatile int clip
Definition: krnl.h:352
k_semval
int k_semval(struct k_t *sem)
Definition: krnl.c:1019
k_start
int k_start(int tm)
Definition: krnl.c:1303
k_mut_ceil_leave
int k_mut_ceil_leave(struct k_t *sem)
Definition: krnl.c:975
k_msg_t::w
volatile int w
Definition: krnl.h:362
k_t::sp_hi
volatile char sp_hi
Definition: krnl.h:344
k_config
int k_config
Definition: krnl.c:279
k_msg_t::el_size
volatile int el_size
Definition: krnl.h:361
k_init
int k_init(int nrTask, int nrSem, int nrMsg)
Definition: krnl.c:1261
k_round_robbin
void k_round_robbin(void)
Definition: krnl.c:1225
k_signal
int k_signal(struct k_t *sem)
Definition: krnl.c:867
dmy_stk
char dmy_stk[90]
k_preempt_flag
char k_preempt_flag
k_set_prio
int k_set_prio(char prio)
Definition: krnl.c:725
k_t::sp_lo
volatile char sp_lo
Definition: krnl.h:343
k_task
int k_task
Definition: krnl.c:295
k_msg_t::nr_el
volatile int nr_el
Definition: krnl.h:361
k_sem_signals_lost
int k_sem_signals_lost(struct k_t *sem)
Definition: krnl.c:999
__attribute__
void __attribute__((weak)) k_enable_wdt(void)
k_receive
char k_receive(struct k_msg_t *pB, void *el, int timeout, int *lost_msg)
Definition: krnl.c:1182
k_millis_counter
unsigned long k_millis_counter
Definition: krnl.c:306
nr_send
char nr_send
Definition: krnl.h:374
k_t::nr
unsigned char nr
Definition: krnl.h:340
k_unused_stak
int k_unused_stak(struct k_t *t)
Definition: krnl.c:698
k_stk_chk
int k_stk_chk(struct k_t *t)
k_t::prio
char prio
Definition: krnl.h:345
k_send
char k_send(struct k_msg_t *pB, void *el)
Definition: krnl.c:1129
k_t::ceiling_prio
char ceiling_prio
Definition: krnl.h:346
k_t::cnt2
volatile int cnt2
Definition: krnl.h:349
ki_receive
char ki_receive(struct k_msg_t *pB, void *el, int *lost_msg)
Definition: krnl.c:1145
k_mut_ceil_enter
int k_mut_ceil_enter(struct k_t *sem, int timeout)
Definition: krnl.c:939
k_t
Definition: krnl.h:335
DMY_STK_SZ
#define DMY_STK_SZ
Definition: krnl.h:242
k_msg_t::sem
struct k_t * sem
Definition: krnl.h:359
k_running
volatile char k_running
Definition: krnl.c:298
k_t::cnt3
volatile int cnt3
Definition: krnl.h:350
pRun
struct k_t * pRun
Definition: krnl.h:369
k_msg_t::cnt
volatile int cnt
Definition: krnl.h:362
k_msg_t
Definition: krnl.h:355
k_sem
int k_sem
Definition: krnl.h:330
ki_send
char ki_send(struct k_msg_t *pB, void *el)
Definition: krnl.c:1087
ki_task_shift
void ki_task_shift(void) __attribute__((naked))
k_t::cnt1
volatile int cnt1
Definition: krnl.h:348
k_t::pred
struct k_t * pred
Definition: krnl.h:342
k_err_cnt
volatile char k_err_cnt
Definition: krnl.c:298
sem_pool
struct k_t * sem_pool
Definition: krnl.h:367
k_t::saved_prio
char saved_prio
Definition: krnl.h:347
val
void int val
Definition: krnl.h:1019
k_msg_t::r
volatile int r
Definition: krnl.h:362
freeRam
int freeRam(void)
Definition: krnl.c:654
k_set_sem_timer
int k_set_sem_timer(struct k_t *sem, int val)
Definition: krnl.c:814
ki_msg_count
int ki_msg_count(struct k_msg_t *m)
Definition: krnl.c:1027
pDmy
struct k_t * pDmy
Definition: krnl.h:368
k_msg_t::nr
unsigned char nr
Definition: krnl.h:358
k_t::maxv
volatile int maxv
Definition: krnl.h:351
AQ
struct k_t AQ
Definition: krnl.h:367
k_malloc
void * k_malloc(int k)
krnl_preempt_flag
volatile char krnl_preempt_flag
k_stop
int k_stop(unsigned int exitVal)
Definition: krnl.c:1407
k_wait
int k_wait(struct k_t *sem, int timeout)
Definition: krnl.c:930
ki_semval
int ki_semval(struct k_t *sem)
Definition: krnl.c:1012
nr_sem
char nr_sem
Definition: krnl.h:374
pmain_el
struct k_t * pmain_el
Definition: krnl.h:368
nr_task
char nr_task
Definition: krnl.c:296
pSleepSem
struct k_t * pSleepSem
Definition: krnl.h:370
k_millis
unsigned long k_millis(void)
Definition: krnl.c:1443
k_eat_ticks
void k_eat_ticks(int ticks)
Definition: krnl.c:687
k_t::pt
void(* pt)(void)
Definition: krnl.h:338
k_t::next
struct k_t * next
Definition: krnl.h:341
k_msg_t::pBuf
char * pBuf
Definition: krnl.h:360
ki_millis
unsigned long ki_millis(void)
Definition: krnl.c:1434
send_pool
struct k_msg_t * send_pool
Definition: krnl.c:293
k_msg_t::lost_msg
volatile int lost_msg
Definition: krnl.h:361
k_release
void k_release(void)
Definition: krnl.c:1237