Hallo, ich hatte alle Funktionen in einem main.c File. Aus Übersichtsgründen habe ich nun die Funktionen auf mehrere c Files verteilt. Nun bemängelt der Compiler, dass die Main Funkion nicht aufgerufen wird. *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?MAIN?MAIN Aber die MAin FUnktion wird doch nie von einer anderen aufgerufen, ist ja schließlich die Hauptfunktion Muss man den Compiler sagen, welche die Main Funktion ist die zuerst aufgerufen werden soll? Oder was kann sonst der Fehler sein? Grüße Florian
Dein main.c ist auch in der Liste der zu compilierenden Dateien mit drin?
@Keiler: Nein das ist die einzige Main Funktion in meinem Projekt. @Rober Weber: Also ich hab die Datei nicht explizit eingetragen, aber die main.c wurde bevor ich andere c Files angelegt habe ja auch immer kompiliert. In der Dateiansicht links ist auf dem Weissen Papier Symbol ein blauer Pfeil. Heisst das, dass es mitkompiliert wird?
Klick do einfach auf Project->Rebuild all Target files und schau im Build Fenster nach, was alles übersetzt wird.
Ahh ok, also dann wird das File mitkompiliert. Die Meldungen sehen wie folgt aus: Build target 'Target 1' compiling Main.c... assembling STARTUP.A51... assembling flash_lib.a51... compiling RS232.c... linking... *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?MAIN?MAIN Program Size: data=45.2 xdata=0 code=429
Hallo Florian Also erstmal bedeutet die Warnung, dass die Funktion main() nicht eingebunden wird, weil sie nicht verwendet wird. Das Assemblerfile Startup.a51 muss ganz unten main aufrufen. Ab dann übernimmt "C" das Kommando. Hast Du eine eigene Startup verwendet oder was daran geändert? Es gibt eine Einstellung in der Projektverwaltung, wo uVision 2/3 gesagt wird, ob eine Startup dazugebunden werden soll. Fehlt dort ein Häckchen? Mfg. Bernd
Hallo Bernd, ich verwende die vom Keil erzeugt Datei STARTUP.A51 . Änderungen habe ich keine vorgenommen. Die einzige Änderung war, dass ich zu dem einzigen c file main.c ein zweites c File erzeugt habe und einige Funktionen ausgelagert habe. Sonst habe ich keine Einstellungen verändert. Grüße Florian
Ich habe gerade Testhalber die 2te c Datei wieder aus dem Projekt rausgenommen und die entsprechenden Funnktionen im main.c file auskommentiert. Dann ist die Warning wieder verschwunden. Ich hab den Eindruck, dass der Keil einfach net checkt, dass die main() meine Hauptfunktion ist.
Das ist die Datei main.c #include "main.h" #include "definitions.h" #include "RS232.h" #include <at89c51RC2.h> // GLOBAL VARIABLES // Timer 1 counter unsigned char time_counter; // Baudrate unsigned char baudrate; // Eingangspuffer unsigned char data input_buffer[MAX_INPUT]; bit new_input_data; unsigned char input_len; void main (void) { // int i; EnterBootLoader(); init(); while (1) { ES = 0; // lock serial interrupt during input buffer analysis if (new_input_data) // check flag if new data is in input buffer { new_input_data = 0; // reset flag if((input_len>=MAX_INPUT)&&(input_buffer[MAX_INPUT-1]==13)) // check length of input data buffer { input_buffer[MAX_INPUT-1] = 0; // clear last char in buffer, this replaces the <CR> with the termination zero -> more practical for string processing //send_error_message(ERROR_NUMBER_BUF_OVERFLOW); // generate a overflow error message input_len=0; // reset length of input buffer->clear input buffer } else { if(input_buffer[input_len-1]==13) // check if <CR> was received as last { input_buffer[input_len-1]=0; // replace the <CR> with a terminating zero which makes it easier in further string processing //analyse_input_buffer(); // call the command processing function send_string_with_cr(input_buffer); } } } ES = 1; // unlock the serial interrupt again //send_char('A'); } } void EnterBootLoader(void) { int i; bit ea_save; ea_save = EA; EA = 0; DPH = 0x00; DPL = 0x00; ACC = 0x04; ASM_MOV_R1_A(); ACC = 0x00; MAP_BOOT; __API_FLASH_ENTRY_POINT(); UNMAP_BOOT; EA = ea_save; // restore interrupt state for(i=0;i<=2000;i++) {;} // send_string("Programmiermodus aktiv"); // send_char(0x0D); for(i=0;i<=2000;i++) {;} } ////////////////////////////////////////////////////// // Name: timer1_interrupt // //--------------------------------------------------// // Parameter: // // none // //--------------------------------------------------// // Timer 1 Interrupt Routine // // Wird zur Read-Timeout Erkennung, Torzeit // // und für das Blinken der OP-LED verwendet // // hierfür wird die Routine normalerweise // // alle 50ms aufgerufen // ////////////////////////////////////////////////////// void timer1_interrupt(void) interrupt 3 using 2 { TF1 = 0; // reset timer 1 interrupt-flag time_counter++; // Zähler für Timeout und OP-Signal if (time_counter>=7) // 500ms sind verstrichen ? { time_counter=0; // Timeout Zähler rücksetzen LED5 = ~LED5; // OP-Signal umschalten } /* if (time_counter%2 == 0) { Relais1 } else { Relais2 } */ } void init(void) { EX0 = 0; // disable external interrupt0 for digital in detection EA = 0; // disable interrupts Relais0 baudrate = 2; time_counter=0; input_len=0; new_input_data=0; init_communication(); ET1 = 0; // disable timer1 interrupt TR1 = 0; // disable timer1 TF1 = 0; // reset timer 1 interrupt-flag TL1 = 0; // reset timer value TH1 = 0; // TMOD = 0x10; // clear timer1 mode bits ET1 = 1; // enable timer1 overflow interrupt TR1 = 1; // enable timer1 again EX0 = 0; // disable external interrupt0 for digital in detection EA = 1; // enable interrupts } Das ist die Datei RS232.c #include "RS232.h" #include "Definitions.h" #include <at89c51RC2.h> extern unsigned char baudrate; extern unsigned char data input_buffer[MAX_INPUT]; extern bit new_input_data; extern unsigned char input_len; void init_communication(void) { ES = 0; // Disable serial interrupt SCON = 0x52; // Set to 8-Bit UART T2CON = 0x30; // set timer 2 control register for use as baudrate generator RCAP2H = 0xFF; // preset the timer 2 register for correct rollover switch(baudrate) { case 0: { RCAP2L = 0xB8; //4800 RCAP2 = 0xFF98 break; } case 1: { RCAP2L = 0xDC; //9600 RCAP2 = 0xFFCC break; } case 2: { RCAP2L = 0xEE; //19200 RCAP2 = 0xFFE6 break; } case 3: { RCAP2L = 0xF7; //38400 RCAP2 = 0xFFF3 break; } default: { RCAP2L = 0xEE; //19200 break; } } TR2 = 1; // start timer 2 IPL0 = 0x10;//&=0xEF IPH0 |= 0x18;//|=0x10 // Serieller Interrupt hat hohe priority RI = 0; TI = 0; ES = 1; } ////////////////////////////////////////////////////// // Name: send_char // //--------------------------------------------------// // Parameter: // // char Text - The char which is to output // //--------------------------------------------------// // Purpose: // // Routine to write a single char // // to the serial port // ////////////////////////////////////////////////////// void send_char(char single_char) //reentrant //reentrant because could be executed from interrupt { // while (!TI); // Wait until Char has send // TI=0; SBUF = single_char; // Write Char to serial Buffer while (!TI); // Wait until Char has send TI=0; } ////////////////////////////////////////////////////// // Name: send_string_with_cr // //--------------------------------------------------// // Parameter: // // char* Text - The string which is to output // //--------------------------------------------------// // Purpose: // // Routine to write a zero terminated char_string // // to the serial port // ////////////////////////////////////////////////////// void send_string_with_cr(char* string) { send_string(string); send_char(0x0D); } ////////////////////////////////////////////////////// // Name: send_string // //--------------------------------------------------// // Parameter: // // char* Text - The string which is to output // //--------------------------------------------------// // Purpose: // // Routine to write a zero terminated char_string // // to the serial port // ////////////////////////////////////////////////////// void send_string(char* string) // reentrant //reentrant because could be executed from interrupt { unsigned char i=0; while (string[i]!=0) // Countinue until zero termination { send_char(string[i]); i++; // next Character } } ////////////////////////////////////////////////////// // Name: Serial_Interrupt0 // //--------------------------------------------------// // Parameter: // // none // //--------------------------------------------------// // Purpose: // // A Routine to handle Serial Interrupt // // Supports serial ASB Commands // ////////////////////////////////////////////////////// void Serial_Interrupt0(void) interrupt 4 { char c = 0; if (RI != 0) { c = SBUF; // Lese das Zeichen aus dem Schnittstellepuffer RI=0; // Clear the existing interrupt request new_input_data=1; // new_input_data ist ein verlängerte Interrupt Flag if (input_len<MAX_INPUT) // Check if Input Buffer is Full input_buffer[input_len] = c; // store the Char in the Input Buffer Array else input_buffer[MAX_INPUT-1] = c; // und speichere es am Ende des Einagebpuffers input_len++; // Next Array Position } } Das ist die Datei STARTUP.A51 $NOMOD51 ;----------------------------------------------------------------------- ------- ; This file is part of the C51 Compiler package ; Copyright (c) 1988-2005 Keil Elektronik GmbH and Keil Software, Inc. ; Version 8.01 ; ; *** <<< Use Configuration Wizard in Context Menu >>> *** ;----------------------------------------------------------------------- ------- ; STARTUP.A51: This code is executed after processor reset. ; ; To translate this file use A51 with the following invocation: ; ; A51 STARTUP.A51 ; ; To link the modified STARTUP.OBJ file to your application use the following ; Lx51 invocation: ; ; Lx51 your object file list, STARTUP.OBJ controls ; ;----------------------------------------------------------------------- ------- ; ; User-defined <h> Power-On Initialization of Memory ; ; With the following EQU statements the initialization of memory ; at processor reset can be defined: ; ; <o> IDATALEN: IDATA memory size <0x0-0x100> ; <i> Note: The absolute start-address of IDATA memory is always 0 ; <i> The IDATA space overlaps physically the DATA and BIT areas. IDATALEN EQU 80H ; ; <o> XDATASTART: XDATA memory start address <0x0-0xFFFF> ; <i> The absolute start address of XDATA memory XDATASTART EQU 0 ; ; <o> XDATALEN: XDATA memory size <0x0-0xFFFF> ; <i> The length of XDATA memory in bytes. XDATALEN EQU 0 ; ; <o> PDATASTART: PDATA memory start address <0x0-0xFFFF> ; <i> The absolute start address of PDATA memory PDATASTART EQU 0H ; ; <o> PDATALEN: PDATA memory size <0x0-0xFF> ; <i> The length of PDATA memory in bytes. PDATALEN EQU 0H ; ;</h> ;----------------------------------------------------------------------- ------- ; ;<h> Reentrant Stack Initialization ; ; The following EQU statements define the stack pointer for reentrant ; functions and initialized it: ; ; <h> Stack Space for reentrant functions in the SMALL model. ; <q> IBPSTACK: Enable SMALL model reentrant stack ; <i> Stack space for reentrant functions in the SMALL model. IBPSTACK EQU 0 ; set to 1 if small reentrant is used. ; <o> IBPSTACKTOP: End address of SMALL model stack <0x0-0xFF> ; <i> Set the top of the stack to the highest location. IBPSTACKTOP EQU 0xFF +1 ; default 0FFH+1 ; </h> ; ; <h> Stack Space for reentrant functions in the LARGE model. ; <q> XBPSTACK: Enable LARGE model reentrant stack ; <i> Stack space for reentrant functions in the LARGE model. XBPSTACK EQU 0 ; set to 1 if large reentrant is used. ; <o> XBPSTACKTOP: End address of LARGE model stack <0x0-0xFFFF> ; <i> Set the top of the stack to the highest location. XBPSTACKTOP EQU 0xFFFF +1 ; default 0FFFFH+1 ; </h> ; ; <h> Stack Space for reentrant functions in the COMPACT model. ; <q> PBPSTACK: Enable COMPACT model reentrant stack ; <i> Stack space for reentrant functions in the COMPACT model. PBPSTACK EQU 0 ; set to 1 if compact reentrant is used. ; ; <o> PBPSTACKTOP: End address of COMPACT model stack <0x0-0xFFFF> ; <i> Set the top of the stack to the highest location. PBPSTACKTOP EQU 0xFF +1 ; default 0FFH+1 ; </h> ;</h> ;----------------------------------------------------------------------- ------- ; ; Memory Page for Using the Compact Model with 64 KByte xdata RAM ; <e>Compact Model Page Definition ; ; <i>Define the XDATA page used for PDATA variables. ; <i>PPAGE must conform with the PPAGE set in the linker invocation. ; ; Enable pdata memory page initalization PPAGEENABLE EQU 0 ; set to 1 if pdata object are used. ; ; <o> PPAGE number <0x0-0xFF> ; <i> uppermost 256-byte address of the page used for PDATA variables. PPAGE EQU 0 ; ; <o> SFR address which supplies uppermost address byte <0x0-0xFF> ; <i> most 8051 variants use P2 as uppermost address byte PPAGE_SFR DATA 0A0H ; ; </e> ;----------------------------------------------------------------------- ------- ; Standard SFR Symbols ACC DATA 0E0H B DATA 0F0H SP DATA 81H DPL DATA 82H DPH DATA 83H NAME ?C_STARTUP ?C_C51STARTUP SEGMENT CODE ?STACK SEGMENT IDATA RSEG ?STACK DS 1 EXTRN CODE (?C_START) PUBLIC ?C_STARTUP CSEG AT 0 ?C_STARTUP: LJMP STARTUP1 RSEG ?C_C51STARTUP STARTUP1: IF IDATALEN <> 0 MOV R0,#IDATALEN - 1 CLR A IDATALOOP: MOV @R0,A DJNZ R0,IDATALOOP ENDIF IF XDATALEN <> 0 MOV DPTR,#XDATASTART MOV R7,#LOW (XDATALEN) IF (LOW (XDATALEN)) <> 0 MOV R6,#(HIGH (XDATALEN)) +1 ELSE MOV R6,#HIGH (XDATALEN) ENDIF CLR A XDATALOOP: MOVX @DPTR,A INC DPTR DJNZ R7,XDATALOOP DJNZ R6,XDATALOOP ENDIF IF PPAGEENABLE <> 0 MOV PPAGE_SFR,#PPAGE ENDIF IF PDATALEN <> 0 MOV R0,#LOW (PDATASTART) MOV R7,#LOW (PDATALEN) CLR A PDATALOOP: MOVX @R0,A INC R0 DJNZ R7,PDATALOOP ENDIF IF IBPSTACK <> 0 EXTRN DATA (?C_IBP) MOV ?C_IBP,#LOW IBPSTACKTOP ENDIF IF XBPSTACK <> 0 EXTRN DATA (?C_XBP) MOV ?C_XBP,#HIGH XBPSTACKTOP MOV ?C_XBP+1,#LOW XBPSTACKTOP ENDIF IF PBPSTACK <> 0 EXTRN DATA (?C_PBP) MOV ?C_PBP,#LOW PBPSTACKTOP ENDIF MOV SP,#?STACK-1 ; This code is required if you use L51_BANK.A51 with Banking Mode 4 ;<h> Code Banking ; <q> Select Bank 0 for L51_BANK.A51 Mode 4 #if 0 ; <i> Initialize bank mechanism to code bank 0 when using L51_BANK.A51 with Banking Mode 4. EXTRN CODE (?B_SWITCH0) CALL ?B_SWITCH0 ; init bank mechanism to code bank 0 #endif ;</h> LJMP ?C_START END Die Headerdateien habe ich mir mal gespart. Wenn ich sie auch posten soll bitte Bescheid geben. Grüße
Hallo Florian Also bei mir gehts. War wohl irgendwas am Projektfile. Gruß, Bernd
Hi Bernd, sry für die späte Antwort, war eine Woche ausser Haus. Das ist komisch, ich hab mir die Zip Datei nochmal geladen aber die Warning ist wie gehabt. Hast Du noch eine Idee was für eine Einstellung bei mir falsch sein könnte? Grüße Florian
Hallo Florian, bei dir wird alles ohne Fehler kompiliert, nur das Linken klappt nicht. Versuch mal aus irgend einem Example die Scriptdatei für den Linker zu kopieren. Verwendest du GCC? Falls ja, kann es sein, dass der GCC-Script für den Linker nicht richtig installiert wurde... Gruß Max
Hallo, ich habe folgendes Problem und ich brauche eine Unterstützung: Ich versuche eine CAN-Kommunikation zwischen zwei Keil/MCB2100 aufzubauen und daraus eine Anzeige zu machen. Die Hardware habe beSTELLT, hat jemand da schon Erfahrung? Bitte um Unterstützung
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.