Ich kriege folgende LinkerFehler:
Das macht keinen Sinn mtenabled ist vorschriftsmäßig als extern markiert und time kommt in irq.c nichtmal vor.
mt/ts.o: In function `init_task':
/home/martin/git/el_toro_repo/src/mt/ts.c:16: multiple definition of `mtenabled'
driver/timer/timer.o:/home/martin/git/el_toro_repo/src/driver/timer/timer.c:9: first defined here
intr/irq.o: In function `handle_irq':
/home/martin/git/el_toro_repo/src/intr/irq.c:8: multiple definition of `time'
driver/timer/timer.o:/home/martin/git/el_toro_repo/src/driver/timer/timer.c:9: first defined here
Selbst wenn ich timer.c und .h komplett wegkommentiere kommt immernoch:
mt/ts.o: In function `init_task':
/home/martin/git/el_toro_repo/src/mt/ts.c:16: multiple definition of `mtenabled'
driver/timer/timer.o:(.bss+0x0): first defined here
irq.c
#include <console.h>
#include <irq.h>
#include <cpustate.h>
#include "../driver/keyboard/keyboard.h"
#include "../driver/timer/timer.h"
#include<ioport.h>
cpu_state* handle_irq(cpu_state* cpu)
{
cpu_state* new_cpu = cpu;
if (cpu->intr >= 0x28) {
// EOI an Slave-PIC
outb(0xa0, 0x20);
}else if(cpu->intr==0x21){kbc_handler(0x21);}
else if(cpu->intr==0x20){timer_handler(&new_cpu);}
// EOI an Master-PIC
outb(0x20, 0x20);
return new_cpu;
}
timer.c
#include<stdint.h>
#include<cpustate.h>
#include<ts.h>
#include<stdbool.h>
#include"timer.h"
//extern bool mtenabled;
void timer_handler(cpu_state* new_cpu){
time++;
if(mtenabled){
new_cpu=schedule(new_cpu);
}
}
timer.h:
#ifndef TIMER_H
#define TIMER_H
#include<stdint.h>
#include<cpustate.h>
extern bool mtenabled;
uint32_t time=0;
void timer_handler(cpu_state* new_cpu);
#endif
ts.c:
#include <cpustate.h>
#include <stdint.h>
#include <stdbool.h>
#include "ts.h"
static int current_task = -1;
static int num_tasks=0;
static task tasks[MAX_CPUSTATE];
/*
* Jeder Task braucht seinen eigenen Stack, auf dem er beliebig arbeiten kann,
* ohne dass ihm andere Tasks Dinge ueberschreiben. Ausserdem braucht ein Task
* einen Einsprungspunkt.
*/
task* init_task(void* entry)
{
if(!mtenabled){
mtenabled=TRUE;
}
/*
* CPU-Zustand fuer den neuen Task festlegen
*/
cpu_state new_state = {
.eax = 0,
.ebx = 0,
.ecx = 0,
.edx = 0,
.esi = 0,
.edi = 0,
.ebp = 0,
//.esp = unbenutzt (kein Ring-Wechsel)
.eip = (uint32_t) entry,
/* Ring-0-Segmentregister */
.cs = 0x08,
//.ss = unbenutzt (kein Ring-Wechsel)
/* IRQs einschalten (IF = 1) */
.eflags = 0x202,
};
/*
* Stack erstellen
*/
uint8_t new_stack[STDRD_STACKSIZE];
/*
* Den angelegten CPU-Zustand auf den Stack des Tasks kopieren, damit es am
* Ende so aussieht als waere der Task durch einen Interrupt unterbrochen
* worden. So kann man dem Interrupthandler den neuen Task unterschieben
* und er stellt einfach den neuen Prozessorzustand "wieder her".
*/
cpu_state* state = (void*) (&new_stack + STDRD_STACKSIZE - sizeof(new_state));
*state = new_state;
num_tasks++;
/*
* neuen Task struct erstellen, in die Liste eintragen und zurückgeben
*/
task new_task ={state,new_stack,num_tasks};
tasks[num_tasks]=new_task;
return &new_task;
}
/*
* Gibt den Prozessorzustand des naechsten Tasks zurueck. Der aktuelle
* Prozessorzustand wird als Parameter uebergeben und gespeichert, damit er
* beim naechsten Aufruf des Tasks wiederhergestellt werden kann
*/
cpu_state* schedule(cpu_state* cpu)
{
/*
* Wenn schon ein Task laeuft, Zustand sichern. Wenn nicht, springen wir
* gerade zum ersten Mal in einen Task. Diesen Prozessorzustand brauchen
* wir spaeter nicht wieder.
*/
if (current_task >= 0) {
tasks[current_task].state = cpu;
}
/*
* Naechsten Task auswaehlen. Wenn alle durch sind, geht es von vorne los
*/
current_task++;
current_task %= num_tasks;
/* Prozessorzustand des neuen Tasks aktivieren */
cpu = tasks[current_task].state;
return cpu;
}
ts.h
#ifndef TS_H
#define TS_H
#include<stdint.h>
#include<cpustate.h>
#include <stdbool.h>
#define STDRD_STACKSIZE 4096 //Stack größe bei der Initialisierung
#define MAX_CPUSTATE 32 // Maximal zahl an Tasks noch keine malloc() funktion implementiert
bool mtenabled=FALSE;
typedef struct {
cpu_state *state;
uint8_t stack_a[STDRD_STACKSIZE];
uint32_t pid;
} task;
task* init_task(void* entry);
cpu_state* schedule(cpu_state* cpu);
#endif
Vielen Dank für die Hilfe