⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c519.txt

📁 dsp&c51的编程,从小百合上down的
💻 TXT
📖 第 1 页 / 共 2 页
字号:
  +_> ?PR?_EXECUTE?MAIN 

?PR?FUNC1?MAIN                         0025H    000BH 

                                -                        - 

?PR?FUNC2?MAIN                         0025H    000BH 

                                -                        - 

?PR?FUNC3?MAIN                         0025H    000BH 

                                -                        - 

?PR?_EXECUTE?MAIN                      0025H    000EH 

  +_> ?C_LIB_CODE 

D:0028H         SYMBOL        tex    // Execute's variables 

                                         no longer 

D:0029H         SYMBOL        arrex  // overlaid with func4/ 

                                         5's 

D:0008H         SYMBOL        y 

D:0009H         SYMBOL        arr4 

D:0013H         SYMBOL        y5 

D:0014H         SYMBOL        arr5 

*** WARNING 16: UNCALLED SEGMENT,IGNORED FOR OVERLAY     PROCESS 

    SEGMENT: ?PR?FUNC4?MAIN 

*** WARNING 16: UNCALLED SEGMENT,IGNORED FOR OVERLAY PROCESS 

    SEGMENT: ?PR?FUNC5?MAIN 

Note: The WARNING 16's show that func4/5 have been removed from the overlay 

process to remove the hazard. See section 8.4.2.6 on the "UNCALLED SEGMENT, 

IGNORED FOR OVERLAY 

PROCESS" warning. 

8.4.2.3 Function Jump Table Warning 

(Non-hazardous) 

Here two functions are called an array of function pointers. The array "jump 

_table" exists in a segment called "?CO?MAIN1, i.e. the constant area assign 

ed to module main. The problem arises that the two message string arguments 

to the printf 's are also sited here. This leads to a recursive definition o 

f the function start addresses in the jump table. 

While this is not in itself dangerous, it prevents the real function referen 

ces from being established and hence the overlaying process is inhibited. 

***********************************************************; 

*<<<<<<<<<<<<<Recursive Call To Segment Error>>>>>>>>>>>>>>* 

***********************************************************; 

#include <stdio.h> 

#include <reg517.h> 

void func1(void) { 

   unsigned char i1 ; 

   for(i1 = 0 ; i1 < 10 ; i1++) { 

      printf("THIS IS FUNCTION 1\n") ;  // String stored in 

                                          ?CO?MAIN1 segment 

      } 

   } 

void func2(void) { 

   unsigned char i2 ; 

   for(i2 = 0 ; i2 < 10 ; i2++) { 

      printf("THIS IS FUNCTION 2\n") ;  // String stored in 

                                          ?CO?MAIN1 segment 

      } 

   } 

code void(*jump_table[])()={func1,func2}; //Jump table to 

                                            functions, 

                                          // table stored in 

                                            ?CO?MAIN1 

                                          // segment. 

/*** Calling Function ***/ 

main() { 

   (*jump_table[P1 & 0x01])() ;   // Call function via jump 

                                         table in ?CO?MAIN1 

    } 

    ^^^^^^^^^^^^^^^^^^^^^^^ End of Module 

The resulting link output is: 

Note: No reference exists between main and func1/2 so the overlay process ca 

nnot occur, resulting in wasted RAM. 

OVERLAY MAP OF MODULE:   MAIN1 (MAIN1) 

MCS-51 LINKER / LOCATER  L51 V2.8 

DATE  04/08/92   PAGE    2 

SEGMENT                    BIT-GROUP          DATA-GROUP 

  +_> CALLED SEGMENT   START    LENGTH     START    LENGTH 

________________________________________________________________ 

?C_C51STARTUP            -        -          -         - 

  +_> ?PR?MAIN?MAIN1 

?PR?MAIN?MAIN1           -        -          -         - 

  +_> ?CO?MAIN1 

  +_> ?C_LIB_CODE 

?CO?MAIN1                -        -          -         - 

  +_> ?PR?FUNC1?MAIN1 

  +_> ?PR?FUNC2?MAIN1 

?PR?FUNC1?MAIN1          -        -        0008H    0001H 

  +_> ?PR?PRINTF?PRINTF 

?PR?PRINTF?PRINTF      0020H.0  0001H.1    0009H    0014H 

  +_> ?C_LIB_CODE 

  +_> ?PR?PUTCHAR?PUTCHAR 

?PR?FUNC2?MAIN1         -         -       0008H    0001H 

  +_> ?PR?PRINTF?PRINTF 

*** WARNING 13: RECURSIVE CALL TO SEGMENT 

    SEGMENT: ?CO?MAIN1 

    CALLER:  ?PR?FUNC1?MAIN1 

*** WARNING 13: RECURSIVE CALL TO SEGMENT 

    SEGMENT: ?CO?MAIN1 

    CALLER:  ?PR?FUNC2?MAIN1 

8.4.2.4 Function Jump Table Warning Solution 

The solution is to use the OVERLAY command when linking thus 

main1.obj & 

to main1.abs & 

OVERLAY(?CO?MAIN1 ~ (func1,func2), main ! (func1,func2)) 

This deletes the reference to func1 & 2 from the ?CO?MAIN1 segment and inser 

ts the true reference from main to func1 & func2. 

The linker output is now thus: 

OVERLAY MAP OF MODULE:   MAIN1.ABS (MAIN1) 

SEGMENT                   BIT-GROUP          DATA-GROUP 

  +_> CALLED SEGMENT    START    LENGTH     START    LENGTH 

________________________________________________________________ 

?C_C51STARTUP             -         -          -        - 

  +_> ?PR?MAIN?MAIN1 

?PR?MAIN?MAIN1            -         -          -        - 

  +_> ?CO?MAIN1 

  +_> ?C_LIB_CODE 

  +_> ?PR?FUNC1?MAIN1 

  +_> ?PR?FUNC2?MAIN1 

?PR?FUNC1?MAIN1           -         -        0008H    0001H 

  +_> ?CO?MAIN1 

  +_> ?PR?PRINTF?PRINTF 

?PR?PRINTF?PRINTF        0020H.0  0001H.1    0009H    0014H 

  +_> ?C_LIB_CODE 

  +_> ?PR?PUTCHAR?PUTCHAR 

?PR?FUNC2?MAIN1           -         -        0008H    0001H 

  +_> ?CO?MAIN1 

  +_> ?PR?PRINTF?PRINTF 

8.4.2.5 Multiple Call To Segment Warning 

(Hazardous) 

This warning generally occurs when a function is called from both the backgr 

ound and an interrupt. This means that potentially the interrupt may call th 

e function whilst it is still running, as a result of a background level cal 

l. The result could be the over-writing of the local data in the background. 

 The fact that the offending function is also overlaid with other background 

 functions makes the chances of failure very high. The simplest solution is 

to declare the function as REENTRANT so that the compiler will generate a lo 

cal stack for parameters and variables. Thus on each call to the function, a 

 new set of parameters and local variables are created without destroying an 

y existing ones from the current call. 

Unfortunately this significantly increases the run time and code produced. A 

nother possibility is to make a second and renamed version of the function, 

one for background use and one for interrupt. This is somewhat wasteful and 

presents a maintenance problem, as you now have effectively two versions of 

the same piece of code. 

In many cases the situation is not a problem, as the user may have ensured t 

hat the reentrant use could never occur, but is left with the linker warning 

. However this must be viewed as dangerous, particularly if more than one pr 

ogrammer is involved. 

#include <stdio.h> 

#include <reg517.h> 

void func1(void) { 

   unsigned char i1,a1[15] ; 

   for(i1 = 0 ; i1 < 10 ; i1++) { 

      a1[i1] = i1 ; 

      } 

   } 

void func2(void) { 

   unsigned char i2,a2[15] ; 

   for(i2 = 0 ; i2 < 10 ; i2++) { 

      a2[15] = i2 ; 

      } 

   } 

main() { 

   func1() ; 

   func2() ; 

   } 

void timer0_int(void) interrupt 1 { 

   func1() ; 

   } ^^^^^^^^^^^^^^^^^^^^^^^ End of Module 

This produces the linker map: 

OVERLAY MAP OF MODULE:   MAIN2 (MAIN2) 

SEGMENT                          DATA-GROUP 

  +_> CALLED SEGMENT          START    LENGTH 

?PR?TIMER0_INT?MAIN2 

  +_> ?PR?FUNC1?MAIN2 

?PR?FUNC1?MAIN2               0017H    000FH 

?C_C51STARTUP 

  +_> ?PR?MAIN?MAIN2 

?PR?MAIN?MAIN2 

  +_> ?PR?FUNC1?MAIN2 

  +_> ?PR?FUNC2?MAIN2 

?PR?FUNC2?MAIN2               0017H    000FH 

D:0007H         SYMBOL        i1  // Danger! 

D:0017H         SYMBOL        a1 

D:0007H         SYMBOL        i2 

D:0017H         SYMBOL        a2 

*** WARNING 15: MULTIPLE CALL TO SEGMENT 

    SEGMENT: ?PR?FUNC1?MAIN2 

    CALLER1: ?PR?TIMER0_INT?MAIN2 

    CALLER2: ?C_C51STARTUP 

8.4.2.6 Multiple Call To Segment Solution 

The solution is to 

(i) Declare func1 as REENTRANT thus: 

void func1(void) reentrant {  } 

(ii) Use OVERLAY linker option thus: 

main2.obj & 

to main2.abs & 

OVERLAY(main ~ func1,timer0_int ~ func1) 

to break connection between main and func1 and timer0_int and func1. 

OVERLAY MAP OF MODULE:   MAIN2.ABS (MAIN2) 

SEGMENT                          DATA-GROUP 

  +_> CALLED SEGMENT          START    LENGTH 

___________________________________________________ 

?C_C51STARTUP                   -         - 

  +_> ?PR?MAIN?MAIN2 

?PR?MAIN?MAIN2                  -         - 

  +_> ?PR?FUNC2?MAIN2 

?PR?FUNC2?MAIN2               0017H    000FH 

*** WARNING 16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS 

    SEGMENT: ?PR?FUNC1?MAIN2 

This means that the safe overlaying of func1 with other background functions 

 will not occur. Removing the link only with the interrupt would solve this: 

  

main2.obj & 

to main2.abs & 

OVERLAY(timer0_int ~ func1) 

Another route would be to disable all overlaying but this is likely to eat u 

p large amounts of RAM very quickly and is thus a poor solution. 

main2.obj & to main2.abs & NOOVERLAY 

With the MULTIPLE CALL TO SEGMENT WARNING the only really "safe" solution is 

 to declare func1 as REENTRANT, with the duplicate function a good second. T 

he danger of using the OVERLAY command is that a less experienced programmer 

 new to the system might not realise that the interrupt is restricted as to 

when it can call the function and hence system quality is degraded. 

8.4.3 Overlaying Public Variables 

All the preceding examples deal with the overlaying of locals and parameters 

 at a function level. A case occurred recently in which the program was spli 

t into two distinct halves; the divide taking place very early on. To all in 

tents a_nd purposes the 8051 was able to run one of two completely different 

 application programs, based on some user input during initialisation. 

Each program half had a large number of public variables, some of which were 

 known to both sides but the majority of which were local to one side only. 

This is almost multitasking. 

This type of program structure really needs a new storage class like "GLOBAL 

", with public meaning available to a certain number of modules only. GLOBAL 

 would then be available to all modules. The new C166 supports this type of 

task-based variable scope. Unfortunately C51 does not, so a fix is required. 

  

The linker's OVERLAY command does not help, as it only controls the overlayi 

ng of local and parameter data. One possible solution uses special modules t 

o declare the publics. Module1 declares the publics for program (task1); Mod 

ule2 declares the publics for program2 (task2). Finally, Module3 declares th 

e publics which are available to both sides. 

The trick then is to use the linker to fix the data segments on Module1 and 

Module2 at the same physical address, whilst allowing Module3's variables to 

 be placed automatically by the linker. 

This solution uses three special modules for declaring the publics: 

/* Example of creating two sets of public data */ 

/*in same memory space */ 

extern void main1(void) ; 

extern void main0(void) ; 

/* Main module where system splits into two parts */ 

void main(void) { 

   bit flag ; 

   if(flag) { 

      main0() ;   // Branch 0 

      } 

   else { 

      main1() ;   // Branch 1 

      } 

   } ^^^^^^^^^^^^^^^^^^^^^^^ End of Module 

/* Module that declares publics for branch 2 */ 

/* Publics for branch 2 */ 

unsigned char x2,y2 ; 

unsigned int z2 ; 

char a2[0x30] ; 

/* A variable which is accessible from both branches */ 

extern int common ; 

^^^^^^^^^^^^^^^^^^^^^^^ End of Module 

void main0(void) { 

   unsigned char c0 ; /* Local - gets overlaid with c1 in*/ 

                /*other branch */ 

   x2 = 0x80 ; 

   y2 = x2 ; 

   c0 = y2 ; 

   z2 = x2*y2 ; 

   a2[2] = x2 ; 

   common = z2 ; 

   } 

^^^^^^^^^^^^^^^^^^^^^^^ End of Module 

/* Module that declares publics for branch 1 */ 

/* Publics for branch 1 */ 

unsigned char x1,y1 ; 

unsigned int z1 ; 

char a1[0x30] ; 

/* A variable which is accessible from both branches */ 

extern int common ; 

void main1(void) { 

   char c1 ; 

   x1 = 0x80 ; 

   y1 = x1 ; 

   c1 = y1 ; 

   z1 = x1*y1 ; 

   a1[2] = x1 ; 

   common = z1 ; 

   } 

^^^^^^^^^^^^^^^^^^^^^^^ End of Module 

/* Module that declares variables that both */ 

/*branches can access */ 

int common ; /* A variable common to both branches */ 

^^^^^^^^^^^^^^^^^^^^^^^ End of Module 

/* Linker Input */ 

l51 t.obj,t1.obj,t2.obj,com.obj to t.abs 

DATA(?DT?T1(20H),?DT?T2(20H)) 

The choice of "20H" for the location places the combined segments just above 

 the register banks. 

The main problem with this approach is that a DATA overlay warning is produc 

ed. This is not dangerous but is obviously undesirable. 

---------------------------------------------------------------------------- 

---- 



  

-- 

Ours is essentially a tragic age, so we refuse to take it tragically. 

  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -