로그인회원등록 내글장바구니주문조회현재접속자
 상품 검색








 게시판 검색





 
 
회원등록 비번분실


온라인 입금계좌
ㆍ기업은행
ㆍ219-043192-01-028
ㆍ이건영

      거래은행 바로가기
 
  AVR Applications
AVR 자료실
작성자 avrtools™        
작성일 2008/12/03
첨부#1 free_sccavr.zip (126KB) (Down:5)
Link#1 smallc.html (Down:1)
ㆍ추천: 0  ㆍ조회: 177   
  Free SmallC for AVR
 
 
by Ron Kreymborg

SmallC for AVR has been extensively re-written to make it more efficient.
Typical code space savings of over 50% on version 1 have been achieved.
A complete User Manual is now available that puts in one place the details previously scattered throughout my old web pages.
It includes many examples and code snippets on configuring and using the various AVR hardware.

■ 사용자 설명서
The user manual includes a quick start and installation guide,
sections on language implementation, code efficiency issues, startup code,
monitoring stack usage, the runtime library,
and detailed descriptions of the example programs listed below.
Download the SCCAVR User Manual (Revision 3) in PDF format.
http://www.jennaron.com.au/smallc/smallc.pdf

■ 컴파일러 버전 2.4.7 Smallc는 지금 무료이다.
For those with a desire to fiddle,
I have made the source code for SmallC available as well (see below).
I did most of the extra development using DJ Delorie's excellent djgpp MSDOS version of gcc.
This included the RHIDE debugger environment which, while clunky, did the job.

■ 모든기능의 sccavr 내려받기
http://www.jennaron.com.au/smallc/sccavr.zip
Unzip the compiler into a directory called sccavr.
Unzip the example programs below into directories off this,
eg. sccavrchase. Further details are in the User Manual.

■ SCCAVR 소스코드
The source code for sccavr is now available for download as well.
http://www.jennaron.com.au/smallc/source.html

■ 예제 프로그램들
These C programs are available in ZIPped format.
Most assume the STK200 as the vehicle although they work just as well on the STK300.
They demonstrate many of the features of sccavr,
including IO and multi-module program suites. Currently they are:

Simple travelling LED flasher chase.zip
http://www.jennaron.com.au/smallc/chase.zip
Accessing external ram on a 8515 extram.zip
http://www.jennaron.com.au/smallc/extram.zip
Port based LCD driver (revised) lcd.zip
http://www.jennaron.com.au/smallc/lcd.zip
Multi-tasking dispatcher multi.zip
http://www.jennaron.com.au/smallc/multi.zip
Using Interrupts 1 intex1.zip
http://www.jennaron.com.au/smallc/intex1.zip
Using Interrupts 2 intex2.zip
http://www.jennaron.com.au/smallc/intex2.zip

■ 프로그램 지원
Download the AVR Studio debugger source level debugger (ASTUDIO3.EXE)
and IAR assembler/linker/librarian (IAR_ASM.ZIP) from the Atmel site.
http://www.atmel.com/atmel/products/prod203.htm

■ SCCAVR - AVR 마이크로 프로세서용 SmallC 컴파일러 설명서 버전 3 (23-9-99)
Ron Kreymborg Compiler Revision 2 September 1999 Jennaron Research

■ 소개
The original Smallc provided a basic K&R version of C without structures, unions,
and the more complex data types (only unsigned chars and ints).
It also lacked many features such as unsigned variables,
function prototyping, casts, longs,

structures, register variables, etc. It also showed its lineage in the days of single
instruction/data spaces - there was no mechanism to use different instructions for
different data sources.
This was a requirement for most microprocessors using a Harvard architecture like the Atmel AVRs.

However, Smallc looked like what I wanted, a compiler I could modify as necessary to suit my requirements, so I decided to convert it to an ANSI C compiler,
albeit with perhaps a few bits still missing.

For some time I persevered with the Atmel WAVRASM program as my assembler,
using all sorts of contortions to include special assembler files whenever a library
function was called for. Finding the IAR relocating DOS Assembler-Linker-

Librarian in the public domain solved all these problems and now all the little
snippets of code required for C runtime support could be defined as modules in an
already assembled relocatable library and simply linked in at link time. This makes
for very efficient run-time code and simplicity itself to modify. It also provides all
the advantages of being able to modularise a project.

The AVR architecture is not really aimed at emulating a stack machine, whereas
SmallC assumes such a machine. I initially wrote the AVR code generator to use
the AVR push and pop instructions. It worked but was not code space efficient.

Using the Y register pair as the C runtime stack pointer and leaving the hardware
stack pointer to manage subroutines and interrupts is far more efficient. However
this requires two stacks - one for subroutines and one for the C code.

SmallC for AVR now by default implements the top of sram as the start of the hardware stack,
with the C stack (usually) starting lower down.

The command line includes options to set the addresses of these hardware and software stacks.
You must at least estimate how many levels of hardware stack you will need and set that aside.

It is then fairly simple to write some code that monitors hardware stack usage during program development, typically using a sentinel byte at the bottom of the stack. With no standard IO path for reporting this is difficult to include in the compiler.

The SmallC compiler, now called sccavr, has been modified to take as input a C
source file and produces as output an assembly code file using IAR syntax.
The input file is expected to use a .c extension.
The output file will have the same name as the source file but with an .s90 extension.

The IAR tools link the various relocatable objects, thus allowing multi-module projects with all the simplicity and encapsulation that implies.

The IAR linker can be programmed to produce a runtime file in .r90 format
for input to the Atmel AVR Studio debugger,
or in Intel .hex format for downloading to the target AVR microprocessor.

■ 컴파일러 빠른시작
Assuming the compiler and IAR tools are installed (see Installing the Software),
a typical command line would be: sccavr testing.c

An error free compile will produce an output file having the same name with an
s90 extension as required by the IAR assembler.
You then run the IAR assembler (called aa90) with the command:
aa90 testing -L -v1

You do not need to type the s90 extension on the input file name.
The -L produces a listing.
The -vn option specifies a peculiar IAR convention about code and data
sizes, where -v1 defines 64Kbytes of data and 8Kbytes of code.

The relocatable output file will have an r90 extension.
If there are any include files, you can specify their path using the -I parameter.
If the assemble is successful you then run the IAR linker (called xlink) with the one line command:
xlink crti testing libcavr -ca90 -Z(DATA)sdata=60 -Z(CODE)scode=0
-Fintel-standard -o testing.hex -xsem -l map

This links the C run time initialisation file crti.r90 as the first object and then the
assembled compiler output object file testing.r90.
It then examines the runtime library libcavr.r90 for unresolved external names and links their associated modules in as well.

The -ca90 specifies the AVR products, and the -Z(DATA) and -Z(CODE) parameters specify the starting address of the data and code segments respectively.
The compiler names these two segments internally as sdata and scode,
and they represent the AVR SRAM and flash PROM areas respectively.

The –Fintel-standard specifies an Intel hex file as the required output format,
and -o testing.hex specifies the output file name.
The -xsem -l map parameters are optional and produce a cross-referenced linker
listing called map.lst showing exactly where all modules will be loaded within
memory.

Like the aa90 command, you can specify any paths to libraries with the -I
parameter. You are not limited to compiling and linking a single program. One of
the nice features of the IAR assembler/linker programs are relocatable modules.
You can link any number of files simply by entering the above xlink command line
and including the additional file names after the startup filename.
More typically you would be using a make file to simplify all this
and these commands would be in the Makefile file.

Before running the xlink command,
you will need to select a startup file to suit your processor
(see The Runtime Initialisation File),
rename it crti.s90, and assemble it using the command:
makeinit

You will also need to assemble the runtime library (see The Runtime Library) with
the command:
makelib

Both these commands and their use is explained further in the section describing
Some Test Programs.

Command Line Flags
The compiler will automatically run the assembler and linker stages with the
parameters described above if you use the additional -a (run assembler) and -l (run
linker) command line flags.
sccavr -al testing.c

This uses a canned set of parameters to compile the C code, run the assembler,
and then run the linker twice.

The first link produces a hex file ready to download,
the second produces a file called debug.r90 ready for debugging in AVR Studio.
It is the same as typing the commands aa90 testing –r -L -v1
xlink crti testing libcavr -ca90 -Z(DATA)sdata=60 -Z(CODE)scode=0
-Fintel-standard -o testing.hex -xsem -l map
xlink crti testing libcavr –r -ca90 -Z(DATA)sdata=60 –Z(CODE)scode=0 -o debug

The compiler will include for aa90 an -I parameter for each path in your INCLUDE environment,
and an -I parameter for xlink for each path in your LIB environment.
As you can see from the previous section, using the -l flag to force a link will only have meaning
if your program is contained in one C file.

Otherwise just use the -a flag for each module and link separately,
embedding the commands in either a make or batch file.
A batchfile example would be:

sccavr –can robot.c
sccavr –can motors.c
sccavr –can nav.c
xlink crti robot nav motors libcavr -ca90 -Z(DATA)sdata=60
-Z(CODE)scode=0 –Fintel-standard -o robot.hex -xsem -l map

If you include the flag -c in the sccavr command line, the output assembly code
will include the original C code as assembler comments. This can be helpful when
reviewing or debugging at the assembler level. Use the -n flag to prevent including
any include files in the assembler output listing.
By default the assembler -v flag is set to -v1 (see the IAR document AT90S
Assembler, Linker, and Librarian) You can enter any of the four possible values
0, 1, 2 or 3 in the command line and it will be passed verbatim to the assembler.
For the mega103 for example:
sccavr –can -v3 robot.c

In addition the –k flag enables stack checking, the -h flag defines the address of the
top of the hardware stack, and the -s flag defines the address for the top of the
software stack. These are explained in detail below.
Some Helpful Hints
My recommendation for initial experimenting in AVR Studio is to compile with
the command
sccavr -clan -h0xdf -s0xbf filename.c

By default both the assembler and linker are run with the –r flag to include
debugging information in the default debug.r90 output file, ready for loading into
Studio. Ignore this file if you are just using the .hex file.
The -h flag value sets the AVR stack pointer to 0xdf, the top of sram for a 2313
processor. The -s flag value defines the top of the software stack, with the
difference here defining a hardware stack size of 0xdf - 0xbf = 0x20 or 32 bytes.
What really happens is the h and s values become the HARDSTK and SOFTSTK
values respectively. The compiler outputs these as public constants in the module
containing the main function. The startup code (crti) loads the HARDSTK value into
the processor hardware stack pointer (SPH and SPL), and the SOFTSTK value is
loaded into the r29-28 (Y) registers as the top of the C software stack. In this
example the h-s value defines the space available for subroutine, interrupt and push
operations. It is your responsibility to ensure this is a large enough space for any
particular program.

In the case above, the small sram space of the 2313 usually allows you to have on
screen in the Studio debugger a Register window, a Processor window, a Memory
window, and the Program window. This set of windows allows you to see all
machine states without using slide bars, etc.
The default for sccavr is the ram space of the 8515 processor.
When the AVR Studio debugger runs, it checks it can find the source code (s90)
for each module in the executable (usually debug.d90). This means that for each
module your program has included from the libcavr.r90 library, Studio will ask for
a path to the source file (cruntime.s90). This quickly becomes very dreary, so the
simple solution is to copy the cruntime.s90 file into your working directory if you
will be using AVR Studio.

The compiler stores numerical values with the most significant bytes in lower
memory addresses. The reason for this was simply to allow easy interpretation
when examining memory in a debugger. When stored in cpu registers, the most
significant byte will be in the higher numbered registers.

■ 소프트웨어 설치
All the software is available for download from www.jennaron.com/smallc.html.
This includes the runtime libraries, include files, and the code examples discussed
later. For convenience the IAR tools and AVR Studio debugger are also available.
The sccavr compiler downloaded from this site is restricted in the number of global
and local variables that can be defined. The fully featured version is available for
purchase.

■ SCCAVR 설치
1. The compiler as downloaded is a zipped format file.
2. Unzip the sccavr.zip file into a new directory called sccavr. Either specify
this while running a program like WinZip95 or create the directory beforehand.
This will unpack the SmallC files into the sccavr directory.
3. Now for some text editing. You must add the following lines at the end of your
autoexec.bat file in the root of your boot disk. Use any plain text editor. These
lines must be after any other lines where these variables are defined.
set path=%path%;c:sccavr;c:iarexe
set include=%include%;c:sccavr;c:iaraa90
set lib=%lib%;c:sccavr
This appends to your existing environment variables the additional paths
required by the SmallC tools, including the IAR tools (see later).
4. If you intend using long file names (and who doesn't), the C runtime library
used by sccavr requires an additional environment variable. Also add the
following line to your autoexec.bat file:
set lfn=128

■ IAR 어셈블러 설치
1. Download the IAR Assembler tools iarasm13.zip file into a temporary
directory.
2. Unzip the file using a tool like WinZip95 or unzip.
3. Click on the now unpacked install.exe file to run the DOS based install
utility. Accept all the defaults. This will install the IAR tools in a directory
called iar. Note the intent of the reference to the autoexec.iar file has been
completed during sccavr installation above.
4. Make sure you copy the two pdf files from the temporary directory to the iar
directory. These are the manuals for the IAR tools and very informative.

■ AVR Studio 설치
1. Download the astudio2.exe file into a temporary directory.
2. Click on this file to run the DOS based unpacking program.
3. Click on the setup.exe program to run the installation tool. Accept all the
defaults.
When the installations are complete, reboot your machine so the changes to the
environment take effect. You are now ready to use sccavr.
The C Implementation
The SmallC compiler for AVR adds to standard SmallC the following features:
· the long data type
· structures and typedef structures
· casts
· unsigned chars and ints
· stronger typing
· function definitions
· the register storage qualifier
· support for the AVR Harvard architecture
· global variable initialisation
The optimisations in Release 2 of the compiler address many of the stack based
issues associated with SmallC. However, the stack paradigm still applies to
arithmetic and automatic variables. For code space efficiency you should use
global or register variables wherever possible.

SmallC for AVR does not support:
· multi-dimensional arrays
· the float and double data types
· the const data qualifier (ignored)
· enumerated types

Floating Point
The 32-bit data type float should be fairly easy to implement as the symbol table
now allows setting 4 byte variables. As I need transcendental functions in the near
future, and have a number of algorithms ready, this will happen fairly quickly.

■ 구조
Both global and local structures are implemented. Arrays of structures are allowed,
as are arrays within structures and pointers to structures.
Other structures and structure pointers are currently not allowed within structures.
The syntax for structures is standard C. You can define a structure prototype like:
struct t_entry {
int x, y;
char note[6];
int *pntr;
};

This produces no code, just a template that may be used subsequently by
declarations like:
struct t_entry ThisOne;
struct t_entry *eptr;

You could also use typedef to define the structure and its implementations:
typedef struct t_entry {
int x, y;
char note[6];
int *pntr;
} ENTRY;
ENTRY ThisOne;
ENTRY *eptr;

Note that a function definition like this must be global to allow passing function
pointers between functions. You can define a structure prototype and create
versions of that prototype in the same declaration. A structure pointer would be
declared as for the first case above and can be used with the standard C syntax
eptr = ThisOne;
...
eptr->x = 1256;

Structure pointers can be incremented and decremented. However in this
implementation it is probably easier to use structure arrays.
If you put the structure definition in a global include file it will be available to all C
modules in your program. You can instance this template both globally and locally.
You can of course, define a structure without a template using the standard C
syntax. For example, to define two structures, both with the same internal structure
and one an array, you could write:
struct {
int x,y;
int mode;
} A_Set, B_Set[6];

For the moment structures within structures are not allowed. The possible future
addition of a malloc function would allow dynamic structures like lists, and will
require structure pointers within structures.

■ 광역 초기화
Strings are not implemented in C as a type, but by convention are represented as a
null terminated character array. Currently there are no library functions to support
strings (strcpy, strcat, etc), but these are easily added (see The Runtime Library).
You can declare global strings in two ways. Global definitions for a string constant
use the syntax:
#define pumpWarn "Warning: Pump #231"

The compiler would assign a label to this, add a trailing null, and store it in AVR
program memory (in the scode segment) using the declaration:
L0 db 87,97,114,110,105,110,103,58
db 32,80,117,109,112,32,35,50,51,49,0
Note the compiler has added the trailing null. Subsequent string constants declared
in the same way are appended to this db structure, separated by the nulls. The
addressing is handled from within the compiler. You could also declare this same
string as:
char pumpWarn = "Warning: Pump #231";

This would also be stored in program memory but would use the defined label for
access and would declare the character array as a string:
pumpWarn db "Warning: Pump #231"
Note that here the assembler automatically adds a trailing null to the string - one is
not supplied by the compiler. Unsigned chars can be defined using the syntax:
unsigned char keys = { 1,2,0x3c, 4, 56,2 };
The types int, unsigned int and long can all be declared using similar syntax:
int CrossData = { 12, 234, 876, 237, 345, 1211,
980, 30, 356, 1587, 66 };

Note that while no action is taken if the const keyword is used (it is simply
skipped), variables declared as above are very much constant and read only, as they
are written into the eeprom along with the executable code!
The changes I have made allow access to this data via the lpm instruction for
accessing constant data in program memory. You need not worry about this of
course and can subsequently treat the declaration like any other global variable:
char *pt;
pt = pumpWarn;

I have not yet found a low cost way to flag the fact that a pointer passed between
functions may point to either data or program memory at run time. However the
compiler keeps track of this difference within the function in which the pointer is
assigned. Thus to use a pointer that you have pointed at a constant in
program memory you must use it within that same function. In all other
cases the pointer is assumed to point to data memory. To simplify handling this

special case, a library function called romcpy exists for moving a string constant
out of prom into ram for subsequent processing. Using the constant defined above
as an example, the function will copy the string from prom to a ram based char
array, eg
char RamTextString[20];
...
romcpy(RamTextString, pumpWarn);
You can define the string within the function if required:
romcpy(RamTextString, “Closing door”);
Remember to include the avrstdio.h header file. String constants are collected by
the compiler and output as a block at the end of scode space.

■ 함수
Functions require prototypes. If the compiler encounters a function without a
previous definition it assigns a return type of int and assumes there will be no
parameters. If there are parameters or it is subsequently used as another type the
use is flagged as an error. It is good programming practice to use function
prototypes, either as a list at the start of a single file program, or in an include file
for multi-file programs. In the latter case use the include file for global function
prototypes, and in each program the static qualifier for the list of local function
prototypes that are only used in that file. This is C's small contribution to data
hiding.

A function prototype should type both the return value and any parameters. Named
parameters are optional in declarations, ie both these declarations are equivalent:
long Accumulate(long *sum, int count);
long Accumulate(long*, int);
The syntax of a function declaration has been changed to the more modern form:
int GetTime(int (*timer)(), int offset) {
<body of function>
}

인터럽트 함수
I have added the interrupt qualifier to function names:
interrupt clock0(void);
The function cannot have a type and it makes no sense to include function
parameters. You will need to add this function name at the correct place in the
startup file crti.s90, either as a vector in the interrupt table, or via a jump from the
interrupt handler. An interrupt routine can have local variables and can address
global variables. However a C interrupt routine is an expensive device, as the entire

C register set is pushed at the beginning and popped at the end for a total of around 60 additional instructions, or about 16uS with a 4Mhz crystal.
I have added two pseudo C instructions gintoff and ginton for issuing the AVR
global interrupt control instructions cli and sei respectively.

레지스터 저장 Qualifier
The compiler can use the fourteen registers r2 through r15 for local variable
storage. All supported data types are allowed. This offers a considerable speed
advantage over local variables on the stack, particularly for variables that are
accessed repeatedly like loop counters. The only disadvantage is that they are
pushed onto the hardware stack whenever the function in which they are defined
calls another function. This presents an additional hardware stack size requirement,
particularly if you are using recursive functions.
Note: You should always carefully consider the hardware and
software stack size requirements in your design.

데이터 종류 long
The 32-bit signed long data type is available for all operations. Long constants use
the "L" affix (123456L). Data typing is strictly enforced and you must use casts to
convert between types. In some cases variables are promoted and demoted based
on context, but it is always wise to check. If in doubt, cast.
Unless otherwise specified, all variables are signed, so casts to a larger data type
automatically do sign extend.
char a;
long b;
a = -5;
b = (long)a;
Thus b will have the value -5L.

산술
The language supports signed and unsigned add, subtract, multiply and divide on
chars, integers and longs. There is no automatic error handling. For situations
where you are uncertain of the range of variables, four C library functions allow
your program to dig itself out of arithmetic errors.
Int CheckDivZero() Call immediately after a division. Returns zero
for no error.

Int CheckLongOverflow() Call immediately after a multiply operation
using longs. Returns non-zero if the result
exceeded 32 bits.
Long GetLongOverflow() If the CheckLongOverflow function returns
true, this function will return the upper 32-bits
of the 64-bit product. You could thus define an
array: long value[2] and implement a subset of
64-bit integer arithmetic.
int CheckIntOverflow() Call immediately after a multiply operation
using ints. Returns non-zero if the result
exceeded 16 bits. Just do it again after casting to
longs.
The 8-bit variables char and unsigned char are always promoted to 16-bits for
arithmetic, including the arithmetic in comparisons.

입출력
Port input and output is one of the main functions of microcontrollers such as the
AVRs. I have implemented the IO standard in, out, sbi and cbi functions as inp,
outp, sbip and cbip respectively. The port addresses and function definitions are
defined in the avrstdio.h header file. Although their implementation is of necessity
indirect, their use in C is close to the hardware and is somewhat easier to remember
than a specific function per IO function. Typical use is
outp(DDRB, 0xff);
outp(PORTB, 0xc7);
sbip(PORTB,1);
val = inp(PORTB);
The function definitions are:
char inp(int addr);
void outp(int addr, int val);
void sbip(int addr, int bit);
void cbip(int addr, int bit);

The addresses associated with the mnemonics are the IO addresses. The conversion
to a memory mapped address is done at run time. Thus you can mix assembler with
C code when speed is necessary without address worries and the compiler will
manage the offsets, ie:
code = 0x05;
outp(PORTB, code); // send command
#asm
ldi r31,0x01 ; motion stop command
in r30,PINB ; wait for bit 7 set
sbrs r30,7 ; skip when it is
rjmp $-4 ; otherwise loop
out PORTC,r31 ; must stop quickly
#endasm
val = inp(PINB); // get input byte

You may need to ensure the correct header definition file for the processor you are
using is included for the assembler. Use the compiler –I flag for this:
sccavr –clan –Iio8515.h myprogram.c

This will insert an include line for this file in the assembly output.

코드효율
SmallC writes the output assembler file as it processes each C token. It therefore
has no memory of what has been done and thus cannot review its representation at
the end of the line or function. SmallC originally used the primary register
concept, which was fine in the days where registers were scarce but hardly applies
to processors like the AVR series. In this version I have incorporated some look
ahead to take sccavr out of the simple stack machine class. It also freely uses the
index registers for variable management. However sccavr still uses the stack
paradigm for automatic stack variables and all simple arithmetic. For most control
applications the AVR processors are fast enough that code efficiencies are not a
problem. When they are I simply move to assembler. In this section I will show
three examples of how sccavr manages a simple integer assignment, where the
variables are stack, global and register based.

The first example shows a function with two local integer variables and an
assignment between them.

test {
int a, b;
...
a = b;
}

The resulting assembler code with my comments is:
;test() {
test
; int a, b;
;
; a = b;
sbiw r28,4 ; create a local stack frame
mov r26,r28 ; stack pointer to X index
mov r27,r29
adiw r26,2 ; offset to a
st -y,r26 ; store address on stack
st -y,r27
mov r26,r28 ; stack pointer to X index
mov r27,r29
adiw r26,2 ; offset to b
ld r31,x+ ; get b value into Z
ld r30,x+
ld r27,y+ ; get a address into X
ld r26,y+
st x+,r31 ; store b value into a address
st x+,r30
;}
adiw r28,4 ; clear stack frame
ret

This is the most expensive method and you can see how the code is built up by
scanning from left to right in the line. Now the same function but with global
variables:
int a, b;
...
test {
...
a = b;
}

This uses the AVR direct access instructions lds and sts for a considerable
saving in code space.
;test() {
test
;
; a = b;
lds r27,_b ; get b contents into X
lds r26,_b+1
sts _a,r27 ; store X into a
sts _a+1,r26
;}
ret

This is about as efficient as it gets. When used in a module and flagged with the
static qualifier, the main problem with global variables (ie name conflicts and
that anyone can alter them) tend to go away, as this makes them invisible from
outside the module. So this can sometimes be a good solution although recursion is
not possible and internal module name conflicts are still a problem. The last
example uses the register qualifier on local variables.
test {
register int a, b;
...
a = b;
}
And this produces the quite efficient code:
;test() {
test
; register int a, b;
;
; a = b;
mov r31,r13 ; b to Z
mov r30,r12
mov r15,r31 ; Z to a
mov r14,r30
;}
ret

There are 14 bytes of register storage available to every function (r15-r2).
However, their use comes with the time and space penalty associated with pushing
and popping the relevant registers when the owning function calls another.

For me (and I’m sure for others) the main advantage of C in the embedded world is
that the algorithms get written quickly, without worrying about the minutiae of data
movement associated with programming in assembler.

In nearly every case I have found the C implementation is all I need, and that is the way the product gets shipped. Only occasionally, typically when handling data streams originating from or destined for external peripherals, was it necessary to move to assembler in the interests of speed.

The Runtime Initialization File SmallC is intended for those people who are quite happy working with assembly code but just want the convenience of writing the majority of processing code in C.

Thus the startup code is external to the compiler and can be modified and
elaborated on as required to suit each new project.
The compiler is shipped with a number of processor specific startup files as demonstrations.
The xxxx_1.s90 versions assume that interrupts will not be used.
The version for the 8515 processor is i8515_1.s90:

; startup.s90 for no interrupts AVR micro 8515.
col 120
lstexp- ; no macro listing

#include <avr.inc>
#include <io8515.h>

; CODE SEGMENT
name startup
rseg scode
extern SOFTSTK, HARDSTK

extern _main
rjmp _prep

_prep ldiz HARDSTK
out SPH,r31
out SPL,r30
rcall _rmclr
ldiy SOFTSTK+1
rcall _main
rjmp $

_rmclr clr r27
sbiw r30,1

_rcl1 st -z,r27
cpi r30,0x60
brne _rcl1
tst r31
brne _rcl1
ret

end

By convention sccavr prefixes the names of all functions, globals and compiler
related and library functions with an underscore. The main reason for this is to
prevent the assembler confusing a variable like x with the register x.

Note: The startup file eventually jumps to a label called _main. Thus somewhere in the files that make up your application you must use main as the name of your initialisation function.

Sccavr uses a two stack paradigm for the C code, where interrupts, calls, pushes
and pops use the hardware stack, and C code uses the Y register pair (r29-28) as a
more code efficient software stack pointer.

Both stack pointers decrement down into memory for pushes, and increment for pops. It is worth noting that the software stack pointer (Y) will always be pointing at the last byte pushed ie, it decrements before pushing.

By default the software and hardware stacks are initialised to 575 (0x23F) and 607
(0x25F) respectively (the 8515).
The difference allows for a hardware stack depth of 32 bytes or a function call depth of 16 before the hardware stack starts overwriting the software stack.

Note: This default is not enough room if somewhere in your code you use the interrupt qualifier for a C based interrupt function.
All interrupt stack pushes and programmatic pushes also go on this stack. The
default values can be easily changed in the compiler command line.

For a 2313 for example, using a hardware stack call depth of only 8 (16 bytes),
the command would be:
sccavr -h223 -s207 testing.c

This sets the hardware stack top to 0xdf and the software stack top to 0xcf.
Note you can use either hex or decimal notation.

There is no reason why the software stack should be lower in memory than the
hardware stack. For example if you are using external ram you could keep the
hardware stack constrained to the bottom section of the internal sram and leave the
software stack at the top of external ram, allowing lots of room for recursive
functions and saving cycles on hardware stack access. As an example, suppose you
had 32K of external ram connected to an 8515, and you wanted 128 bytes of
hardware stack at the bottom of internal ram, and the C stack at the top of the
external ram. To set the hardware stack top at 0xdf (223) in the internal sram, and
the C software stack to the top of external ram, the command would be:
sccavr -h223 -s0x7fff test.c

Remember you would need to reset the xlink parameter -Z(DATA)sdata= to the
next byte after the hardware stack top so global data starts there rather than at the

bottom of sram. In this example it would be -Z(DATA)sdata=e0 (ie 224). You
would also need to modify the global memory clear routine in the startup code.
One of the example programs demonstrates a similar configuration.
You need not worry if your global data definitions spill over into the external ram.
All that will happen is access to these variables will take one extra cycle. As global
memory is assigned by the linker on a first come first served basis, you can assign
highly accessed global data early, perhaps in a special data.c file.

A more elaborate startup file where interrupts are used could include the
initialisation code initially described by David VanHorn. Here all interrupt vectors
are included along with the individual handlers, all bogus reset generated interrupts
harmlessly cleared, and the processor state completely set up before calling the C
main function.
The examples have the name format xxxx_2.s90 with the version for the 8515 called i8515_2.s90.
This starts off like:

; Interrupt enabled startup code for sccavr.
; David VanHorn & Ron Kreymborg
#include <avr.inc>
#include <avrmacro.inc>
name startup
rseg scode ; must be first code segment
extern SOFTSTK ; defined in compiler
extern HARDSTK
extern _main ; entry point to user's code

rjmp _start ; reset jump
; Interrupt vectors
rjmp ext_int0
rjmp ext_int1
rjmp tim1_capt
rjmp tim1_compa
rjmp tim1_compb
rjmp tim1_ovf
rjmp tim0_ovf
rjmp spi_handler
rjmp uart_rxc
rjmp uart_dre
rjmp uart_txc
rjmp ana_comp
;***********************************************

; Startup routine begins
_start ldiz HARDSTK ; init hardware stack
out 0x3e,r31
out 0x3d,r30
rcall _init ; go clear all interrupts, setup the
; ports, start the timers, all that
; hardware stuff
rcall _ramclear ; global data area must be zeroed
ldiy SOFTSTK+1 ; init the C runtime stack
sei ; and hello world
rjmp _main

If you use interrupts, register r16 has been set aside as the only register not used by the C runtime environment. Use this to save and restore the flags register (SREG)
on entry and exit. Many interrupt routines can be serviced with just this register.
Other registers can be used after first pushing them to the hardware stack.

Note: If you use the –l option in sccavr to run xlink, it assumes the startup file is called crti.r90. Thus you must be sure to name your startup file crti.s90, or else copy one of the examples from the sccavr directory, and then run the batch file called
makeinit.bat. Read the comments in this batch file concerning the aa90 -v flag.

You can have any number of startup files, one for each project if required, all with
different names. You just need to change the xlink line in your make file. A much
simpler technique is to use a separate directory for each project, a system I highly
recommend.

■ 사용된 Stack의 감시
Stack overflow is an ever present problem in embedded systems.
Stack usage is always difficult to estimate and there is little that can be done in the way of error recovery when it occurs.

To guard against the situation occurring, the sccavr compiler provides a flag that if set will provide code to check both stacks prior to and immediately after calling every function (except the library outp function).

While this does not cover events that obliterate the return address on the hardware
stack or events which overwrite data neighbours by a few bytes, it will catch most
other events. It works by writing a two byte integer sentinel (0x5555) into user specified addresses at the bottom of the software and hardware stacks.

While these bytes continue to match normal processing proceeds. Otherwise one of two possible outputs on one of four possible output ports will be driven low and the
processor will stop in a loop. If connected to LEDs, these port outputs can be used to indicate a hardware or software stack overflow respectively. You enable stack checking with the –k command line flag
sccavr –clank myprogram.c

This flag works with a new file you must create (or add to) in the /sccavr directory
called sccavr.ini that defines a number of stack checking parameters. These define
the addresses to write the sentinel words to in memory and the port definitions for
overflow indication. You must always define both stack limits. The three
associated variables are called hardstklimit, softstklimit and stkerr.

Typical entries for an 8515 processor using the default sccavr stack settings would
be:
softstklimit=0x212
hardstklimit = 0x242
stkerr=portb, 3,0

Blank lines and spaces are ignored.
Recapping, the sccavr default stack settings give a hardware stack top of 0x25f and a software stack top of 0x23f.
The hardware stack limit setting above is therefore three bytes above the top of the software stack. At startup this would look like:
00
55
55 <- sentinel address (0x242)
00
00
00 <- Y register address (0x23f)
00

The address for these sentinels will depend on your application.
Perhaps in this case an address of 0x240 would be adequate.
If you are particularly worried you might put it sixteen or so bytes above the top of the software stack.
The sentinel for the software stack is constrained to be at least above the top of the globally defined variable area.

The stkerr entry defines the port and bit positions that will be used to indicate an
overflow. In the above example, bit position 3 of PORTB will be used for hardware

stack indication, and bit position 0 for the software stack.
In both cases the code that is executed is:
in r20,<port>
cbr r20,<respective_bit_position>
out <port>,r20
rjmp $

For a hardware stack overflow in the case defined above,
the actual code would be:
in r20,PORTB ; get PORTB levels
cbr r20,4 ; 1<<3
out PORTB,r20 ; light the LED
rjmp $ ; error

Note this means the other bit positions on the port are unaffected, providing a
minimum impact on other peripherals connected to this port when an error occurs.
The check functions are inserted just before the main function. The code to insert
the sentinels is inserted immediately after the main label and before your code is
started. Before calling any functions (apart from outp) you should configure the
port for the two chosen output positions.

There is a speed penalty of course, but if your application is not affected by this,
there is nothing wrong with leaving the code in production equipment, with the two
LEDs mounted on the board and used for system debugging when and if an error
occurs.

   
윗글 cvAVR 직렬포트와 LCD 시험용 소스
아래글 AVR910-ISP용 AVR-OSP2 Ver5.43
    N         제목    글쓴이 작성일 조회 추천
AVR 자료실 안내 avrtools™ 2008/09/02 (화) 175 0
97 AVR Basic Compiler (4K Free) avrtools™ 2008/12/03 (수) 214 0
96 코드비젼 V2.05.0 평가판 avrtools™ 2011/07/17 (일) 134 0
95 8x8 LED Audio Spectrum Display avrtools™ 2009/10/18 (일) 259 0
94 AVR 펌웨어로 만드는 USB 드라이버 avrtools™ 2009/10/07 (수) 443 0
93 AVR-CDC and V-USB avrtools™ 2009/10/06 (화) 231 0
92 AVR USB-HID-Bootloader의 제작 avrtools™ 2009/10/01 (목) 267 0
91 AT91SAM7S256 개발환경과 컴파일러 [2] avrtools™ 2008/11/03 (월) 2186 0
90 SAM7S256 USB 드라이버와 AT91-ISP avrtools™ 2008/11/01 (토) 1172 0
89 AT91SAM7S256 공부를 시작합니다. avrtools™ 2008/11/01 (토) 586 1
88 ICCAVR V7.16A AVR 컴파일러 45일판 avrtools™ 2009/03/09 (월) 138 0
87 CodeVisionAVR1248b 最新版下载 leeky 2008/11/08 (토) 311 0
86 AVR UART 소스 (ICC AVR V6) avrtools™ 2008/12/03 (수) 187 0
85 cvAVR Soft Uart Source avrtools™ 2008/12/03 (수) 156 0
84 cvAVR 직렬포트와 LCD 시험용 소스 avrtools™ 2008/12/03 (수) 155 0
83 Free SmallC for AVR avrtools™ 2008/12/03 (수) 177 0
82 AVR910-ISP용 AVR-OSP2 Ver5.43 avrtools™ 2008/12/03 (수) 178 0
81 Code Vision AVR 컴파일러 2K 데모버전 avrtools™ 2008/12/02 (화) 111 0
80 AVR delay loop generator avrtools™ 2008/12/02 (화) 164 0
79 ICC tiny C컴파일러 V6 데모버전 (30일 제한판) avrtools™ 2008/12/02 (화) 75 0
78 ICC AVR C 컴파일러 V6 (4K 제한판) avrtools™ 2008/12/02 (화) 100 0
77 DasmAVR (Windows용 AVR 역어셈블러) avrtools™ 2008/12/02 (화) 150 0
76 AVR PROG KIT avrtools™ 2008/12/02 (화) 185 0
75 AVR JTAG ICE KIT avrtools™ 2008/12/02 (화) 264 0
74 AVR 부동소수점, 지연시간 계산기 avrtools™ 2008/12/02 (화) 170 0
73 ATtiny45 USB to RS232 인터페이스 avrtools™ 2008/09/26 (금) 210 0
72 MEGA32 128x64 GLCD Scope 제작 avrtools™ 2008/09/22 (월) 319 0
71 PC송신방식 Tiny2313 50x7 LED 전광판 avrtools™ 2008/09/10 (수) 274 0
70 mega8 적외선 거리측정 레이더 leeky 2006/05/07 (일) 1383 0
69 ATmega16 RFID #3 소프트웨어 leeky 2006/12/27 (수) 894 0
68 ATmega16 RFID #2 하드웨어 leeky 2006/12/27 (수) 1142 0
67 ATmega16 RFID #1 태그 leeky 2006/12/27 (수) 873 0
66 ISO 14443A RFID 카드의 읽기/쓰기 방법 [1] leeky 2007/02/25 (일) 1505 1
65 ATmega8 PSK31 RF Modem의 제작 leeky 2006/03/07 (화) 1390 21
64 T89C51SND1C 64M USB MP3 플레이어 avrtools 2006/03/04 (토) 995 8
63 AVR 13.56MHz RFID 읽기/쓰기 장치의 제작 [7] leeky 2007/02/19 (월) 1040 4
62 WhereAVR for APRS GPS/Telemetry avrtools 2006/05/05 (금) 402 2
61 ATmega8 UI-TNC 무선모뎀의 제작 avrtools 2006/03/07 (화) 409 0
60 AVR APRS(GPS) Packet 무선모뎀 avrtools 2006/03/07 (화) 395 0
59 AT90PWM3 교류모터 속도제어 leeky 2006/04/07 (금) 942 1
58 M128 MMC LED 전광판 leeky 2006/03/07 (화) 930 0
57 Charon 2 이더넷 모듈의 소개 avrtools 2006/04/04 (화) 491 0
56 S2313 LED 회전계 (TACHO METER) avrtools 2006/03/28 (화) 611 0
55 Mega8 + 128x128 LCD 스코프 avrtools 2006/03/28 (화) 1199 0
54 Mega8 + OV6630 Treva 모바일용 카메라의 화상처리 leeky 2006/03/19 (일) 799 0
53 YUKI Mega8 MP3 Player #3 avrtools 2006/03/11 (토) 855 0
52 AVR JTAG 에뮬레이터의 제작 avrtools 2006/03/07 (화) 851 0
51 USB AVR 프로그래머 AvrUsb500 avrtools 2006/03/07 (화) 743 1
50 Mega88 USB 버스 모니터 avrtools 2006/03/07 (화) 398 0
49 M16 MMC Flash Memory leeky 2006/03/07 (화) 470 1
48 M163 SD,MMC Interface leeky 2006/03/07 (화) 455 0
47 S2313 MMC to Serial leeky 2006/03/07 (화) 329 0
46 ATmega48 UDP/IP 적외선 리모콘 수신장치 avrtools 2006/03/07 (화) 433 0
45 HDD MP3 플레이어 leeky 2006/03/07 (화) 611 0
44 MP3 yampp-3/USB leeky 2006/03/07 (화) 304 0
43 MP3 Player yampp-3 leeky 2006/03/07 (화) 269 0
42 YUKI MP3 플레이어2의 제작 (ATmega8 + SD Card) avrtools 2006/03/07 (화) 388 0
41 AVR CD 플레이어 leeky 2006/03/07 (화) 546 0
40 S2313 초음파 거리계 (미터, TV 스크린, LED 표시) avrtools 2006/03/07 (화) 563 0
39 RF Spectrum Monitor avrtools 2006/03/07 (화) 397 0
38 Easy Ethernet AVR 웹서버 leeky 2006/03/07 (화) 470 0
37 90S4433 LCD표시 100Mhz 주파수 카운터 leeky 2006/03/07 (화) 263 0
36 ELM Audio Spectrum Monitor avrtools 2006/03/07 (화) 376 0
35 Mega8 Door Bell leeky 2006/03/07 (화) 291 0
34 AVR 휴대용 DVM leeky 2006/03/07 (화) 506 0
33 Minimum Mass Waveform Capture and Display leeky 2006/03/07 (화) 274 0
32 AT90S2313 디지털 용량계 avrtools 2006/03/07 (화) 379 0
31 SLO2016 Alphanumeric Intelligent Display leeky 2006/03/07 (화) 187 0
30 AT90S2313 흔드는 LED 전광판 (POV) leeky 2006/03/07 (화) 440 0
29 ATtiny2313 Scrolling LED Sign avrtools 2006/03/07 (화) 375 0
28 Tiny22,S1200 나이트 라이더 avrtools 2006/03/07 (화) 326 0
27 ATtiny26L의 AD 변환과 PWM 출력제어 leeky 2006/03/07 (화) 497 0
26 S2313을 사용한 DS1820 온도계 leeky 2006/03/07 (화) 278 0
25 ATmega8535 온도센서 leeky 2006/03/07 (화) 306 0
24 AVR2313 100MHz RF연결 주파수 측정메터 avrtools 2006/03/07 (화) 209 0
23 VHF 무선 데이터 송신기 leeky 2006/03/07 (화) 514 0
22 90S2313 1MHz 파형 포착기 leeky 2006/03/07 (화) 245 0
21 VHF 무선 데이터 수신기 avrtools 2006/03/07 (화) 390 0
20 AVR 5x7 Dotmatrix LED leeky 2006/03/07 (화) 249 0
19 Mega163 웹 LCD leeky 2006/03/07 (화) 404 0
18 AVR 이더넷 시험소프트 avrtools 2006/03/07 (화) 320 0
17 AVR 넷트웍 시계 (타임 프로토콜) avrtools 2006/03/07 (화) 392 0
16 RS-232 to 100 MHz RF desktop avrtools 2006/03/07 (화) 249 0
15 AVR 6디지트 50MHz 주파수 카운터 leeky 2006/03/07 (화) 224 0
14 AVR DS1820 온도센서 avrtools 2006/03/07 (화) 268 0
13 AVR 직접주파수 발생기 (AT90S2313 DDS) avrtools 2006/03/07 (화) 400 0
12 프로그래머블 PLL 제어 avrtools 2006/03/07 (화) 243 0
11 AVR AT90S2313 7Segment LED Display leeky 2006/03/07 (화) 225 0
10 TINY15L 무전원 4채널 온도계 avrtools 2006/03/07 (화) 338 0
9 8PIN AVR을 사용한 풀컬러 LED leeky 2006/03/07 (화) 368 0
8 DS1820 고분해능 온도계 avrtools 2006/03/07 (화) 352 0
7 S2313 디지털 전압계 avrtools 2006/03/07 (화) 473 0
6 S2313 적외선 USB 모듈 avrtools 2006/03/07 (화) 337 0
5 S2313 주파수 카운터 avrtools 2006/03/07 (화) 272 0
4 AVR90S2313과 Treva 카메라의 연결 leeky 2006/03/07 (화) 314 0
3 Mega8 PID 온도제어 leeky 2006/02/24 (금) 691 1
2 90S2333 3채널 다이오드 온도계 avrtools 2006/02/24 (금) 249 0
1 AT89S8252로 만드는 1~40MHz DDS leeky 2006/02/14 (화) 320 0
1

바구니 : 0
 보관함 : 0
오늘뷰 : 0
HOME   |   회사소개   |   제휴안내   |   회사위치   |   서비스이용 약관   |   개인정보 보호정책   |   사이트맵
17015 경기도 용인시 기흥구 동백중앙로16번길 16-25, 508호. 전화 : 031-282-3310
사업자 등록번호 : 697-47-00075 / 대표 : 이건영 / 업태 : 제조업 / 종목 : LED조명, LED전원, 제어장치.
개인정보 관리책임자 : 홈페이지 관리자 . Copyright ⓒ2016 아크레즈 (ACLEDS INC.)
HOME TOP PREVNEXT 0 0 0