Revision 1
Lab2 finished(maybe)
lab2/.vscode/c_cpp_properties.json | ||
---|---|---|
1 |
{ |
|
2 |
"env": { |
|
3 |
"minix.include": "${workspaceFolder}/../.minix-src/include" |
|
4 |
}, |
|
5 |
"configurations": [{ |
|
6 |
"name": "Minix", |
|
7 |
"compilerPath": "", |
|
8 |
"cStandard": "c11", |
|
9 |
"defines": ["__minix", "_MINIX ", "_NETBSD_SOURCE", "__i386__"], |
|
10 |
"includePath": ["${workspaceFolder}", "${env:minix.include}"], |
|
11 |
"browse": { |
|
12 |
"path": ["${workspaceFolder}", "${env:minix.include}"], |
|
13 |
"limitSymbolsToIncludedHeaders": false, |
|
14 |
"databaseFilename": "" |
|
15 |
} |
|
16 |
}], |
|
17 |
"version": 4 |
|
18 |
} |
|
0 | 19 |
lab2/.vscode/extensions.json | ||
---|---|---|
1 |
{ |
|
2 |
// See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations. |
|
3 |
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp |
|
4 |
// List of extensions which should be recommended for users of this workspace. |
|
5 |
"recommendations": [ |
|
6 |
"austin.code-gnu-global", |
|
7 |
"ms-vscode.cpptools", |
|
8 |
"xaver.clang-format" |
|
9 |
], |
|
10 |
// List of extensions recommended by VS Code that should not be recommended for users of this workspace. |
|
11 |
"unwantedRecommendations": [] |
|
12 |
} |
|
0 | 13 |
lab2/.vscode/settings.json | ||
---|---|---|
1 |
{ |
|
2 |
"git.ignoreLimitWarning": true, |
|
3 |
"C_Cpp.clang_format_fallbackStyle": "LLVM", |
|
4 |
"diffEditor.ignoreTrimWhitespace": true, |
|
5 |
"editor.formatOnSave": false, |
|
6 |
"editor.tabSize": 2, |
|
7 |
"editor.wordWrap": "bounded", |
|
8 |
"editor.wordWrapColumn": 100, |
|
9 |
"files.associations": { }, |
|
10 |
} |
|
0 | 11 |
lab2/.clang-format | ||
---|---|---|
1 |
BasedOnStyle: LLVM |
|
2 |
AccessModifierOffset: -2 |
|
3 |
AlignAfterOpenBracket: true |
|
4 |
AlignEscapedNewlinesLeft: false |
|
5 |
AlignOperands: true |
|
6 |
AlignTrailingComments: true |
|
7 |
AllowAllParametersOfDeclarationOnNextLine: true |
|
8 |
AllowShortBlocksOnASingleLine: true |
|
9 |
AllowShortCaseLabelsOnASingleLine: true |
|
10 |
AllowShortFunctionsOnASingleLine: All |
|
11 |
AllowShortIfStatementsOnASingleLine: false |
|
12 |
AllowShortLoopsOnASingleLine: true |
|
13 |
AlwaysBreakAfterDefinitionReturnType: false |
|
14 |
AlwaysBreakBeforeMultilineStrings: false |
|
15 |
AlwaysBreakTemplateDeclarations: false |
|
16 |
BinPackArguments: true |
|
17 |
BinPackParameters: true |
|
18 |
BraceWrapping: |
|
19 |
AfterClass: false |
|
20 |
AfterControlStatement: false |
|
21 |
AfterEnum: false |
|
22 |
AfterFunction: false |
|
23 |
AfterNamespace: false |
|
24 |
AfterObjCDeclaration: true |
|
25 |
AfterStruct: false |
|
26 |
AfterUnion: false |
|
27 |
BeforeCatch: true |
|
28 |
BeforeElse: true |
|
29 |
IndentBraces: false |
|
30 |
BreakBeforeBinaryOperators: None |
|
31 |
BreakBeforeBraces: Custom |
|
32 |
BreakBeforeTernaryOperators: true |
|
33 |
BreakConstructorInitializersBeforeComma: false |
|
34 |
ColumnLimit: 0 |
|
35 |
CommentPragmas: '^ IWYU pragma:' |
|
36 |
ConstructorInitializerAllOnOneLineOrOnePerLine: false |
|
37 |
ConstructorInitializerIndentWidth: 2 |
|
38 |
ContinuationIndentWidth: 2 |
|
39 |
Cpp11BracedListStyle: true |
|
40 |
DerivePointerAlignment: false |
|
41 |
DisableFormat: false |
|
42 |
ExperimentalAutoDetectBinPacking: false |
|
43 |
IndentCaseLabels: true |
|
44 |
IndentPPDirectives: AfterHash |
|
45 |
IndentWidth: 2 |
|
46 |
IndentWrappedFunctionNames: false |
|
47 |
KeepEmptyLinesAtTheStartOfBlocks: true |
|
48 |
Language: Cpp |
|
49 |
MaxEmptyLinesToKeep: 1 |
|
50 |
NamespaceIndentation: None |
|
51 |
ObjCBlockIndentWidth: 2 |
|
52 |
ObjCSpaceAfterProperty: false |
|
53 |
ObjCSpaceBeforeProtocolList: true |
|
54 |
PenaltyBreakBeforeFirstCallParameter: 19 |
|
55 |
PenaltyBreakComment: 300 |
|
56 |
PenaltyBreakFirstLessLess: 120 |
|
57 |
PenaltyBreakString: 1000 |
|
58 |
PenaltyExcessCharacter: 1000000 |
|
59 |
PenaltyReturnTypeOnItsOwnLine: 60 |
|
60 |
PointerAlignment: Right |
|
61 |
SpaceAfterCStyleCast: true |
|
62 |
SpaceBeforeAssignmentOperators: true |
|
63 |
SpaceBeforeParens: ControlStatements |
|
64 |
SpaceInEmptyParentheses: false |
|
65 |
SpacesBeforeTrailingComments: 1 |
|
66 |
SpacesInAngles: false |
|
67 |
SpacesInCStyleCastParentheses: false |
|
68 |
SpacesInContainerLiterals: true |
|
69 |
SpacesInParentheses: false |
|
70 |
SpacesInSquareBrackets: false |
|
71 |
Standard: Cpp11 |
|
72 |
TabWidth: 2 |
|
73 |
UseTab: Never |
|
0 | 74 |
lab2/Makefile | ||
---|---|---|
1 |
# name of the program (Minix service) |
|
2 |
PROG=lab2 |
|
3 |
|
|
4 |
# source code files to be compiled |
|
5 |
SRCS = lab2.c timer.c utils.c |
|
6 |
|
|
7 |
# additional compilation flags |
|
8 |
# "-Wall -Wextra -Werror -I . -std=c11 -Wno-unused-parameter" are already set |
|
9 |
CFLAGS += -pedantic |
|
10 |
|
|
11 |
# list of library dependencies (for Lab 2, only LCF library) |
|
12 |
DPADD += ${LIBLCF} |
|
13 |
LDADD += -llcf |
|
14 |
|
|
15 |
# include LCOM's makefile that does all the "heavy lifting" |
|
16 |
.include <minix.lcom.mk> |
|
0 | 17 |
lab2/i8254.h | ||
---|---|---|
1 |
#ifndef _LCOM_I8254_H_ |
|
2 |
#define _LCOM_I8254_H_ |
|
3 |
|
|
4 |
#include <lcom/lcf.h> |
|
5 |
|
|
6 |
/** @defgroup i8254 i8254 |
|
7 |
* @{ |
|
8 |
* |
|
9 |
* Constants for programming the i8254 Timer. Needs to be completed. |
|
10 |
*/ |
|
11 |
|
|
12 |
|
|
13 |
|
|
14 |
/*IRQ's*/ |
|
15 |
|
|
16 |
#define IRQ_TIMER 0 |
|
17 |
#define DEFAULT_FREQ 60 |
|
18 |
|
|
19 |
|
|
20 |
#define TIMER_FREQ 1193182 /**< @brief clock frequency for timer in PC and AT */ |
|
21 |
#define MIN_FREQ 19 |
|
22 |
#define TIMER0_IRQ 0 /**< @brief Timer 0 IRQ line */ |
|
23 |
|
|
24 |
/* I/O port addresses */ |
|
25 |
|
|
26 |
#define TIMER_0 0x40 /**< @brief Timer 0 count register */ |
|
27 |
#define TIMER_1 0x41 /**< @brief Timer 1 count register */ |
|
28 |
#define TIMER_2 0x42 /**< @brief Timer 2 count register */ |
|
29 |
#define TIMER_CTRL 0x43 /**< @brief Control register */ |
|
30 |
|
|
31 |
#define SPEAKER_CTRL 0x61 /**< @brief Register for speaker control */ |
|
32 |
|
|
33 |
/* Timer control */ |
|
34 |
|
|
35 |
/* Timer selection: bits 7 and 6 */ |
|
36 |
|
|
37 |
#define TIMER_SEL0 0x00 /**< @brief Control Word for Timer 0 */ |
|
38 |
#define TIMER_SEL1 BIT(6) /**< @brief Control Word for Timer 1 */ |
|
39 |
#define TIMER_SEL2 BIT(7) /**< @brief Control Word for Timer 2 */ |
|
40 |
#define TIMER_RB_CMD (BIT(7) | BIT(6)) /**< @brief Read Back Command */ |
|
41 |
|
|
42 |
/* Register selection: bits 5 and 4 */ |
|
43 |
|
|
44 |
#define TIMER_LSB BIT(4) /**< @brief Initialize Counter LSB only */ |
|
45 |
#define TIMER_MSB BIT(5) /**< @brief Initialize Counter MSB only */ |
|
46 |
#define TIMER_LSB_MSB (TIMER_LSB | TIMER_MSB) /**< @brief Initialize LSB first and MSB afterwards */ |
|
47 |
|
|
48 |
/* Operating mode: bits 3, 2 and 1 */ |
|
49 |
|
|
50 |
#define TIMER_SQR_WAVE (BIT(2) | BIT(1)) /**< @brief Mode 3: square wave generator */ |
|
51 |
#define TIMER_RATE_GEN BIT(2) /**< @brief Mode 2: rate generator */ |
|
52 |
|
|
53 |
/* Counting mode: bit 0 */ |
|
54 |
|
|
55 |
#define TIMER_BCD 0x01 /**< @brief Count in BCD */ |
|
56 |
#define TIMER_BIN 0x00 /**< @brief Count in binary */ |
|
57 |
|
|
58 |
/* READ-BACK COMMAND FORMAT */ |
|
59 |
|
|
60 |
#define TIMER_RB_COUNT_ BIT(5) |
|
61 |
#define TIMER_RB_STATUS_ BIT(4) |
|
62 |
#define TIMER_RB_SEL(n) BIT((n) + 1) |
|
63 |
|
|
64 |
/**@}*/ |
|
65 |
|
|
66 |
#endif /* _LCOM_I8254_H */ |
|
0 | 67 |
lab2/lab2.c | ||
---|---|---|
1 |
#include <lcom/lcf.h> |
|
2 |
#include <lcom/lab2.h> |
|
3 |
|
|
4 |
#include <stdbool.h> |
|
5 |
#include <stdint.h> |
|
6 |
|
|
7 |
#include "i8254.h" |
|
8 |
//#include "timer.c" |
|
9 |
extern uint32_t cont; |
|
10 |
|
|
11 |
|
|
12 |
int main(int argc, char *argv[]) { |
|
13 |
|
|
14 |
// sets the language of LCF messages (can be either EN-US or PT-PT) |
|
15 |
lcf_set_language("EN-US"); |
|
16 |
|
|
17 |
// enables to log function invocations that are being "wrapped" by LCF |
|
18 |
// [comment this out if you don't want/need it] |
|
19 |
lcf_trace_calls("/home/lcom/labs/lab2/trace.txt"); |
|
20 |
|
|
21 |
// enables to save the output of printf function calls on a file |
|
22 |
// [comment this out if you don't want/need it] |
|
23 |
lcf_log_output("/home/lcom/labs/lab2/output.txt"); |
|
24 |
|
|
25 |
// handles control over to LCF |
|
26 |
// [LCF handles command line arguments and invokes the right function] |
|
27 |
if (lcf_start(argc, argv)) |
|
28 |
return 1; |
|
29 |
|
|
30 |
// LCF clean up tasks |
|
31 |
// [must be the last statement before return] |
|
32 |
lcf_cleanup(); |
|
33 |
|
|
34 |
return 0; |
|
35 |
} |
|
36 |
|
|
37 |
int(timer_test_read_config)(uint8_t timer, enum timer_status_field field) { |
|
38 |
/* To be implemented by the students */ |
|
39 |
uint8_t st; |
|
40 |
if(timer_get_conf(timer,&st)==1) return 1; |
|
41 |
if(timer_display_conf(timer,st,field)==1) return 1; |
|
42 |
|
|
43 |
return 0; |
|
44 |
// printf("%s is not yet implemented!\n", __func__); |
|
45 |
|
|
46 |
} |
|
47 |
|
|
48 |
int(timer_test_time_base)(uint8_t timer, uint32_t freq) { |
|
49 |
/* To be implemented by the students */ |
|
50 |
if(freq<MIN_FREQ || freq>TIMER_FREQ) |
|
51 |
{ |
|
52 |
printf("OUT OF RANGE FREQUENCY\n"); |
|
53 |
return 1; |
|
54 |
} |
|
55 |
return(timer_set_frequency(timer,freq)); |
|
56 |
//printf("%s is not yet implemented!\n", __func__); |
|
57 |
|
|
58 |
} |
|
59 |
|
|
60 |
int(timer_test_int)(uint8_t time) { |
|
61 |
/* To be implemented by the students */ |
|
62 |
|
|
63 |
if(time<0) return 1; |
|
64 |
|
|
65 |
int ipc_status; |
|
66 |
message msg; |
|
67 |
uint8_t r; |
|
68 |
uint8_t bit_no = 0; |
|
69 |
timer_subscribe_int(&bit_no); |
|
70 |
while( (cont/DEFAULT_FREQ)<time ) |
|
71 |
{ /* You may want to use a different condition */ |
|
72 |
/* Get a request message. */ |
|
73 |
// printf("1\n"); |
|
74 |
//printf("cont:%d, time:%d\n\n",cont/60,time); |
|
75 |
if ( (r = driver_receive(ANY, &msg, &ipc_status)) != 0 ) |
|
76 |
{ |
|
77 |
printf("driver_receive failed with: %d", r); |
|
78 |
continue; |
|
79 |
} |
|
80 |
if (is_ipc_notify(ipc_status)) { /* received notification */ |
|
81 |
switch (_ENDPOINT_P(msg.m_source)) { |
|
82 |
case HARDWARE: /* hardware interrupt notification */ |
|
83 |
if (msg.m_notify.interrupts & BIT(0)) { /* subscribed interrupt */ |
|
84 |
timer_int_handler(); |
|
85 |
if(cont%DEFAULT_FREQ==0) |
|
86 |
timer_print_elapsed_time(); |
|
87 |
//printf("cont:%d\n",cont); |
|
88 |
} |
|
89 |
//printf("msg:%x\n",msg.m_notify.interrupts); |
|
90 |
break; |
|
91 |
default: |
|
92 |
//printf("2\n"); |
|
93 |
break; /* no other notifications expected: do nothing */ |
|
94 |
} |
|
95 |
} else { |
|
96 |
// printf("3\n"); /* received a standard message, not a notification */ |
|
97 |
/* no standard messages expected: do nothing */ |
|
98 |
} |
|
99 |
} |
|
100 |
if(timer_unsubscribe_int()!=0) return 1; |
|
101 |
|
|
102 |
|
|
103 |
//printf("%s is not yet implemented!\n", __func__); |
|
104 |
|
|
105 |
return 0; |
|
106 |
} |
|
107 |
//dois primeiros bits sao 1, (TIMER_RB_CNTRL|BIT(5)) |
|
108 |
//SYS_OUTB para controlo->0x43, Config timer 0, dizer que queremos escrever para o controlo, e depois ler a parte corresponder |
|
109 |
//g9 |
|
0 | 110 |
lab2/timer.c | ||
---|---|---|
1 |
#include <lcom/lcf.h> |
|
2 |
#include <lcom/timer.h> |
|
3 |
|
|
4 |
#include <stdint.h> |
|
5 |
|
|
6 |
#include "i8254.h" |
|
7 |
|
|
8 |
uint32_t cont=0; |
|
9 |
int hook_id; |
|
10 |
|
|
11 |
|
|
12 |
int (timer_set_frequency)(uint8_t timer, uint32_t freq) { |
|
13 |
/* To be implemented by the students */ |
|
14 |
uint8_t conf; |
|
15 |
timer_get_conf(timer,&conf); |
|
16 |
uint32_t tudo; |
|
17 |
uint8_t msb,lsb; |
|
18 |
tudo=(TIMER_FREQ/freq); |
|
19 |
msb=(tudo&0xFF00)>>8; |
|
20 |
lsb=tudo&0xFF; |
|
21 |
//printf("%x\n%x\n%x\n%d\n",tudo,msb,lsb,timer); |
|
22 |
|
|
23 |
|
|
24 |
if(timer==0) |
|
25 |
{ |
|
26 |
conf=(conf&0xF); |
|
27 |
conf = (conf | TIMER_SEL0 | TIMER_LSB_MSB); |
|
28 |
if(sys_outb(TIMER_CTRL, conf)!=0) return 1; |
|
29 |
if(sys_outb(TIMER_0, lsb)!=0) return 1; |
|
30 |
if(sys_outb(TIMER_0, msb)!=0) return 1; |
|
31 |
} |
|
32 |
|
|
33 |
if(timer==1) |
|
34 |
{ |
|
35 |
conf=(conf&0xF); |
|
36 |
conf = (conf | TIMER_SEL1 | TIMER_LSB_MSB); |
|
37 |
if(sys_outb(TIMER_CTRL, conf)!=0) return 1; |
|
38 |
if(sys_outb(TIMER_1, lsb)!=0) return 1; |
|
39 |
if(sys_outb(TIMER_1, msb)!=0) return 1; |
|
40 |
} |
|
41 |
|
|
42 |
if(timer==2) |
|
43 |
{ |
|
44 |
conf=(conf&0xF); |
|
45 |
conf = (conf | TIMER_SEL2 | TIMER_LSB_MSB); |
|
46 |
if(sys_outb(TIMER_CTRL, conf)!=0) return 1; |
|
47 |
if(sys_outb(TIMER_2, lsb)!=0) return 1; |
|
48 |
if(sys_outb(TIMER_2, msb)!=0) return 1; |
|
49 |
} |
|
50 |
return 0; |
|
51 |
|
|
52 |
} |
|
53 |
|
|
54 |
int (timer_subscribe_int)(uint8_t *bit_no) { |
|
55 |
/* To be implemented by the students */ |
|
56 |
//printf("%s is not yet implemented!\n", __func__); |
|
57 |
/* int policy; |
|
58 |
sys_irqrmpolicy(&policy); */ |
|
59 |
hook_id=*bit_no; |
|
60 |
sys_irqsetpolicy(IRQ_TIMER,IRQ_REENABLE,&hook_id); |
|
61 |
|
|
62 |
return 1; |
|
63 |
} |
|
64 |
|
|
65 |
int (timer_unsubscribe_int)() { |
|
66 |
/* To be implemented by the students */ |
|
67 |
// printf("%s is not yet implemented!\n", __func__); |
|
68 |
|
|
69 |
sys_irqrmpolicy(&hook_id); |
|
70 |
|
|
71 |
return 1; |
|
72 |
} |
|
73 |
|
|
74 |
void (timer_int_handler)() { |
|
75 |
/* To be implemented by the students */ |
|
76 |
//printf("%s is not yet implemented!\n", __func__); |
|
77 |
cont=cont+1; |
|
78 |
} |
|
79 |
|
|
80 |
int (timer_get_conf)(uint8_t timer, uint8_t *st) { |
|
81 |
/* To be implemented by the students */ |
|
82 |
|
|
83 |
uint8_t rbc = (TIMER_RB_CMD|TIMER_RB_SEL(4)|TIMER_RB_SEL(timer)); |
|
84 |
if(sys_outb(TIMER_CTRL,rbc)!=0) return 1; |
|
85 |
|
|
86 |
|
|
87 |
if(timer==0) |
|
88 |
return (util_sys_inb(TIMER_0,st)); |
|
89 |
if(timer==1) |
|
90 |
return (util_sys_inb(TIMER_1,st)); |
|
91 |
if(timer==2) |
|
92 |
return (util_sys_inb(TIMER_2,st)); |
|
93 |
|
|
94 |
return 1; |
|
95 |
|
|
96 |
//printf("%s is not yet implemented!\n", __func__); |
|
97 |
|
|
98 |
|
|
99 |
} |
|
100 |
|
|
101 |
int (timer_display_conf)(uint8_t timer, uint8_t st, |
|
102 |
enum timer_status_field field) { |
|
103 |
/* To be implemented by the students */ |
|
104 |
union timer_status_field_val val; |
|
105 |
|
|
106 |
|
|
107 |
if(field==tsf_all) |
|
108 |
{ |
|
109 |
val.byte=st; |
|
110 |
|
|
111 |
} |
|
112 |
if(field==tsf_initial) |
|
113 |
{ |
|
114 |
//printf("%d\n",tsf_initial); |
|
115 |
|
|
116 |
if(((st&0x30)>>4)==0) |
|
117 |
val.in_mode=INVAL_val; |
|
118 |
|
|
119 |
if(((st&0x30)>>4)==1) |
|
120 |
val.in_mode=LSB_only; |
|
121 |
|
|
122 |
if(((st&0x30)>>4)==2) |
|
123 |
val.in_mode=MSB_only; |
|
124 |
|
|
125 |
if(((st&0x30)>>4)==3) |
|
126 |
val.in_mode=MSB_after_LSB; |
|
127 |
} |
|
128 |
|
|
129 |
|
|
130 |
if(field==tsf_mode) |
|
131 |
{ |
|
132 |
//printf("%x\n",st); |
|
133 |
val.count_mode=((st&0xE)>>1); |
|
134 |
|
|
135 |
/* printf("%x\n",val.count_mode); |
|
136 |
val.count_mode=(val.count_mode>>1); |
|
137 |
printf("%x\n",val.count_mode); */ |
|
138 |
//val.count_mode=(st&0x1C)/4; |
|
139 |
|
|
140 |
if (val.count_mode==6) |
|
141 |
val.count_mode=2; |
|
142 |
|
|
143 |
if (val.count_mode==7) |
|
144 |
val.count_mode=3; |
|
145 |
|
|
146 |
|
|
147 |
} |
|
148 |
|
|
149 |
if(field==tsf_base ) //BCD |
|
150 |
{ |
|
151 |
//printf("%d\n",tsf_base); |
|
152 |
if((st&0x1)==1) |
|
153 |
val.bcd=true; |
|
154 |
|
|
155 |
else val.bcd=false; |
|
156 |
} |
|
157 |
|
|
158 |
|
|
159 |
return( timer_print_config(timer, field, val)); |
|
160 |
//printf("%s is not yet implemented!\n", __func__); |
|
161 |
|
|
162 |
//return 0; |
|
163 |
} |
|
0 | 164 |
lab2/utils.c | ||
---|---|---|
1 |
#include <lcom/lcf.h> |
|
2 |
|
|
3 |
#include <stdint.h> |
|
4 |
|
|
5 |
int(util_get_LSB)(uint16_t val, uint8_t *lsb) { |
|
6 |
/* To be implemented by the students */ |
|
7 |
printf("%s is not yet implemented!\n", __func__); |
|
8 |
|
|
9 |
return 1; |
|
10 |
} |
|
11 |
|
|
12 |
int(util_get_MSB)(uint16_t val, uint8_t *msb) { |
|
13 |
/* To be implemented by the students */ |
|
14 |
printf("%s is not yet implemented!\n", __func__); |
|
15 |
|
|
16 |
return 1; |
|
17 |
} |
|
18 |
|
|
19 |
int (util_sys_inb)(int port, uint8_t *value) { |
|
20 |
/* To be implemented by the students */ |
|
21 |
uint32_t b32; |
|
22 |
sys_inb(port,&b32); |
|
23 |
//printf("%x",b32); |
|
24 |
*value=b32&0xFF; |
|
25 |
//printf("%x\n",*value); |
|
26 |
|
|
27 |
|
|
28 |
//printf("%s is not yet implemented!\n", __func__); |
|
29 |
|
|
30 |
return 0; |
|
31 |
} |
|
32 |
|
|
33 |
/* a = 133 |
|
34 |
b = a & 0x0F |
|
35 |
1000 0101 |
|
36 |
*/ |
|
0 | 37 |
Also available in: Unified diff