krnl
1
Loading...
Searching...
No Matches
examples
oldexamples
old-may-not_work
debug
readme
readme.ino
Go to the documentation of this file.
1
/*
2
* >>>> krnl.h <<<<
3
* my own small KeRNeL adapted for Arduino
4
*
5
* this version adapted for Arduino
6
*
7
* (C) 2012
8
*
9
* Jens Dalsgaard Nielsen <jdn@es.aau.dk>
10
* http://www.control.aau.dk/~jdn
11
* Section of Automation & Control
12
* AAU SATLAB
13
* Aalborg University,
14
* Denmark
15
*
16
* "THE BEER-WARE LICENSE"
17
* <jdn@es.aau.dk> wrote this file. As long as you retain this notice and follow GPL v2 you
18
* can do whatever you want with this stuff. If we meet some day, and you think
19
* this stuff is worth it, you can buy me a beer in return :-) or if you are real happy then ...
20
* single malt will be well received :-)
21
*
22
23
24
****
25
*
26
* Background for KeRNeL
27
* - educational purpose and need for an easy open well function preemptive kernel.
28
* - straight easy to read and understand code
29
* - ... which may have a slight impact on performance
30
* - no install circus - just open a sketch
31
* - Minimal impact on std Arduino SW
32
* - "steal" timer2 and therefor pwm 3 and 11
33
* - rest is leaved untouched
34
* - Simple approach: you cant create task, semaphores and msgQ after k_start
35
*
36
* WARNING WARNING WARNING
37
* - WARNING It seems that Serial.print has problems when printing numbers
38
* int i;
39
* Serial.print(i) may fail !!!!
40
* The eror has been reproduced on avr32 + freertos (JAL) - maybe a C++ lib problem ?
41
*
42
* - SUGGESTION
43
* int i;
44
* char s[1];
45
* itoa(i,s,10);
46
* Serial.print(s) seems to work ...
47
*
48
* FOR float USE
49
* http://arduino.cc/forum/index.php/topic,44262.0.html
50
*
51
char *ftoa(char *a, double f, int precision)
52
{
53
long p[] = {0,10,100,1000,10000,100000,1000000,10000000,100000000};
54
55
char *ret = a;
56
long heiltal = (long)f;
57
itoa(heiltal, a, 10);
58
while (*a != '\0') a++;
59
*a++ = '.';
60
long desimal = abs((long)((f - heiltal) * p[precision]));
61
itoa(desimal, a, 10);
62
return ret;
63
}
64
65
* /Jens
66
*
67
*****************************************************************************************
68
*
69
***** KeRNeL calls KeRNeL calls KeRNeL calls KeRNeL calls KeRNeL calls KeRNeL calls ****
70
71
NB NB
72
1. k_init();
73
- init kernel but do not start !
74
2. k_start(msec) starts KeRNeL. Main program will NOT return from k_start
75
- msec(int) timertick in msec.From 1 to more than 32000 msec
76
- To reduce timer2 isr load select timertick as high as possible
77
78
CHECK.
79
- Only check carried out is that the create calls (task, semaphores and mesQs) will not work after k_start.
80
- No control on KeRNeL elements so take care. I you do a k_signal to a thread descriptor then it's your problem
81
82
MEMORY USAGE
83
- Please adjust KeRNeL data structs size by setting defines (mentioned below) so you dont have no more KeRNeL elements than needed.
84
- #define K_USR_TASK 5
85
- #define K_USR_SEM 4
86
- #define K_USR_SENDQ 2
87
88
TIMER2 / tone library (/pwm out ch 3,11
89
- KeRNeLs heartbeat uses Timer2.
90
- So you cant use PWM on pin 3 or 11 and the same goes for sound (tone)
91
- You can ofcourse use another timer or external interrupt.
92
93
COMMENTS IN GENERAL
94
- It seems that millis etc works okay
95
- Take care when using non re-entrant code like Serial.print - do a mutex with a semaphore
96
- Can be a good idea to inspec k_err_cnt after create of tasks etc just to see if there
97
were any errors.
98
99
******
100
101
Some add tech info
102
103
HOW TO GET INFO about your progtram on a linux box
104
jdn@jdn-lat ~ $ cd /tmp
105
jdn@jdn-lat /tmp $ find . -name krnl*elf -print
106
./build6916815778938108877.tmp/krnl01.cpp.elf
107
find: `./pulse-PKdhtXMmr18n': Permission denied
108
jdn@jdn-lat /tmp $ cd build6916815778938108877.tmp/
109
jdn@jdn-lat /tmp/build6916815778938108877.tmp $ avr-size -C krnl01.cpp.elf
110
AVR Memory Usage
111
----------------
112
Device: Unknown
113
114
Program: 4048 bytes
115
(.text + .data + .bootloader)
116
117
Data: 437 bytes
118
(.data + .bss + .noinit)
119
120
TO see the generated codde avr-objdump -S xxx.cpp.elf (xxx your file as above)
121
122
123
***********
124
125
126
127
128
int freeRam(void)
129
130
------------------
131
132
YOUR OWN ISRs
133
See timer interrupt and the NAKED approach. Its important
134
so you keep same stak layout so you can call do your own task shift
135
136
It is not promoted as a good idea to do cascade interrupts, meaning dont enable interrupt
137
inside an ISR routine
138
139
140
*****/
141
142
143
/**** http://arduino.cc/forum/index.php?topic=92664.0
144
145
// FOR INSPIRATION
146
#include <avr/interrupt.h>
147
148
{
149
pinMode(2, INPUT);
150
digitalWrite(2, HIGH); // Enable pullup resistor
151
sei(); // Enable global interrupts
152
EIMSK |= (1 << INT0); // Enable external interrupt INT0
153
EICRA |= (1 << ISC01); // Trigger INT0 on falling edge
154
}
155
//
156
void loop(void)
157
{
158
//
159
}
160
//
161
162
**** To integrate with KeRNeL
163
164
// Interrupt Service Routine attached to INT0 vector
165
ISR(EXT_INT0_vect,ISR_NAKED)
166
{
167
PUSHREGS();
168
digitalWrite(13, !digitalRead(13)); // Toggle LED on pin 13
169
you can do a ki_signal
170
171
POPREGS();
172
reti();
173
}
174
175
*/
176
Generated by
1.15.0