ImageCraft下的AVR启动代码

发布者:泉趣人最新更新时间:2020-07-24 来源: 51hei关键字:ImageCraft  AVR  启动代码 手机看文章 扫描二维码
随时随地手机看文章

        以前经常想自己使用编译器编写MCU的C代码,编译器帮我们做了什么。编译器是如何分配变量和代码的。所以就闲着没事去看编译器的安装路径下有什么东东。工作中使用的是ICCAVR编译器和Atmel的atmega64.所以我倒腾的就是这款编译器和MCU~~~。


        说实话ICCAVR编译器确实非常简捷方便,但是功能强大(当然了,我没用过其它的编译器o(╯□╰)o)。对于它的基本使用再次不再赘述。在编译器环境中点击帮助菜单会弹出Show Library Source Code passwd,然后点击会弹出一个小提示框:password is ICCAVR.来到ICCAVR的安装目录中会看到有一个压缩包libsrc.zip,它在libsrc.avr文件夹内。呵呵想必你已经知道这个压缩包的解压密码了。里边有常用的C库函数源代码和常用函数的汇编代码。


       在libsrc.avr文件夹下有个init.s文件,这个文件是mega系列mcu初始化的通用文件。里边是几十行汇编代码。在MCU上电时首先执行的代码就是这些代码,而并不是你编写的代码~~~代码如下:


; init.s

;

; to be included by the crt*.s files

;

; initialize stacks

;

; set the hardware stack to ram_end, and the software stack some

; bytes below that

ldi R28,ldi R29,>ram_end

out $3D,R28

out $3E,R29

subi R28,sbci R29,>hwstk_size



ldi R16,0xAA  ; sentenial

std Y+0,R16

; put sentenial at bottom of HW stack



clr R0

ldi R30,<__bss_start

ldi R31,>__bss_start

ldi R17,>__bss_end



; this loop zeros out all the data in the bss area

;

init_loop:

cpi R30,<__bss_end

cpc R31,R17

breq init_done

st Z+,R0

rjmp init_loop

init_done:



std Z+0,R16  ; put sentenial at bottom of SW stack



; copy data from idata to data

; idata contains the initialized values of the global variables



ldi R30,<__idata_start

ldi R31,>__idata_start

ldi R26,<__data_start

ldi R27,>__data_start

ldi R17,>__idata_end



  ; set RAMPZ always. If this is a main app, then RAMPZ needs to reset to

  ; zero if invoked through the bootloader

ldi R16,USE_ELPM


out 0x3B,R16

copy_loop:

cpi R30,<__idata_end

cpc R31,R17

breq copy_done

  .if USE_ELPM

elpm ; load (RAMPZ:Z)

  .else

lpm ; load (Z) byte into R0

  .endif

adiw R30,1

st X+,R0

rjmp copy_loop

copy_done:

        不熟悉汇编的请自己去补充,这段代码中也使用了一些ICC自己的编译器伪指令:<、>分别是对$FF进行取余和取整运算。而ram_end、hwstk_size等常量是我们在新建工程的时候选择芯片类型的时候决定的,或者可以在project的option选项中进行更改。通常下默认的hwstk_size硬件堆栈的大小为30,ram_end的大小取决于你使用的芯片AVR64则该值是10ff.这与芯片内部的存储器组织相关,它标记了MCU的sram的终端地址。.text伪指令标定了以下生成的是位于代码区,_start::标号是编译器内部开始标号,而_main才是我们的程序入口。Note:ICC编译器中的::表示外部标号,:表示内部标号。


        首先使用立即数加载ldi将RAM的高端地址存入Y指针,同时将Y指针赋值给SP堆栈指针out  $3D,R28中的0x3D就是SPL的地址。这样通过前四条指令就设置好了堆栈指针。然后采用相同的办法设置好堆栈尺寸。由于Y指针指向了堆栈的高端地址,然后使用subi指令减掉你在编译器环境下设置的堆栈尺寸,将Y指针指向硬件堆栈的栈底,同时硬件堆栈的栈底紧邻软件堆栈的栈顶。为了防止堆栈溢出,ICC编译器专门在该处存放了0xAA作为标记(ldi  R16,0xAA      std  Y+0,R16)。其实你去看头文件中的宏函数检查堆栈是否溢出,它就是判断该处存放的0XAA是否给覆盖掉。


        设置好堆栈之后,再进行变量的内存分配。对于变量内存的分配,编译器是这样操作的:先定义先分配,同时不会对内存进行速度优化(偶字节对其什么的都不会,因为Sram非常稀缺)。变量又分为有初值的变量和无初值的变量(变量的定义和声明),ICC将这两类变量分别存储到bss区和data区。bss区存放没有初值的变量(只有声明,没有定义的全局变量等),data区存放有初值的全局性变量(全局变量和static修饰的有初值的变量).对于bss区的处理自然非常简单


        clr R0

ldi R30,<__bss_start

ldi R31,>__bss_start

ldi R17,>__bss_end


init_loop:

cpi R30,<__bss_end

cpc R31,R17

breq init_done

st Z+,R0

rjmp init_loop

利用处理器特性指令,设置好Z指针,使用指针自增存储配合跳转,将你编写的C工程中bss变量进行全部默认清零。此时执行std   z+0,R16依然将0xAA标记存放到bss区顶部,在bss区和硬件堆栈区之间是软件堆栈区。是这样的:编译器在帮你规划存储器的时候,你的变量空间是先从低地址开始的,首先规划data区,然后划分bss区,剩余的就是软件堆栈区,最后是硬件堆栈区。所以当你的全局性变量太多时,硬件堆栈是一定的,那么软件堆栈势必会被挤压过小,软件堆栈用来函数调用时的入栈出栈,中断现场保护等操作。所以该情况下特别容易引起堆栈溢出~~~!!!



ldi R30,<__idata_start

ldi R31,>__idata_start

ldi R26,<__data_start

ldi R27,>__data_start

ldi R17,>__idata_end

此时又出现了idata区和data区的分别。idata区指定了你的有初值的全局变量在Flash中的存放位置,不然MCU如何记住你定义的变量初值呢?



copy_loop:

cpi R30,<__idata_end

cpc R31,R17

breq copy_done

  .if USE_ELPM

elpm ; load (RAMPZ:Z)

  .else

lpm ; load (Z) byte into R0

  .endif

adiw R30,1

st X+,R0

rjmp copy_loop

copy_done:

这段代码就是将初值全部copy到RAM中的data区对应位置,根据芯片类型来确定是否需要elpm。



        整个init.s代码就是这样,前边注释中也提到了;to be included by the crt*.s files。这段通用代码会被引用到crtxxboot.s代码中。通用的boot代码如下所示:


; make sure to assemble w/ -n flag, e.g.

; iasavr -n crt...

;

; bootloader startup file, same as crtavr.s except that vectors are routed

; to the bootloader section and use jmp for the vector

;

.include "area.s"



.text

__start:: ; entry point

; route vector

ldi R16,1

out 0x35,R16  ; MCUCR = 1, unlock IVSEL

ldi R16,2

out 0x35,R16  ; MCUCR = 2, set ivsel        以上的代码用来设置中断向量表位置,是位于Flash的起始位置,还是bls区(这个以后讨论)



USE_ELPM = 0;

.include "init.s"



; call user main routine

call _main                                                            寻找你的main函数,现在编译器已经帮你把所有的都准备好了,将MCU交给你。

_exit::

rjmp _exit



; interrupt vectors. The first entry is the reset vector

;

.area vector(abs)                                              标定中断向量绝对地址,位于00000H处,进行一次跳转,寻找__start

.org 0

jmp __start


额,这样对于ICCAVR对MCU的初始化就完成了,这是我的理解。希望批评指正。

关键字:ImageCraft  AVR  启动代码 引用地址:ImageCraft下的AVR启动代码

上一篇:AVR开发 Arduino方法(二) 中断子系统
下一篇:AVR第8课:独立按键

推荐阅读最新更新时间:2024-11-07 15:30

AVR单片机ATmega8内部晶振使用
ATmega8在使用内部晶振的时候,需要进行烧写方式的选择,来选择不同内部晶振大小。 对应UART的波特率设置和使用外部晶振的方式是一样的。 但是一般情况下,不建议使用内部晶振,因为内部晶振的精度不高,会因为温度等外部环境的影响,使得不准确。
[单片机]
数控电源AVR单片机C程序
编译环境为CodeWizardAVR #include mega8.h #include delay.h #include stdio.h #include stdlib.h #define Voltage_UP PINB.0 #define Voltage_Down PINB.2 #define UD PORTB.3 #define CS PORTB.5 #define INC PORTB.4 #define Voltage_LED PORTB.6 #define Current_LED PORTB.7 #define Current_Detect 0 #define Out_Detect 1 #define
[单片机]
AVR单片机中断实现
中断嵌套 对于中断嵌套的处理,不同的单片机处理的方式是不同的,应根据所使用单片机的特点正确实现中断嵌套的处理。 按照通常的规则,当MCU正在响应一个中断B的过程中,又产生一个其它的中断A申请时,如果这个新产生中断A的优先级比正在响应的中断B优先级高的话,就应该暂停当前的中断B的处理,转入响应高优先级的中断A,待高优先级中断A处理完成后,再返回原来的中断B的处理过程。如果新产生中断A的优先级比正在处理中断B的优先级低(或相同),则应在处理完当前的中断B后,再响应那个后产生的中断A申请(如果中断A条件还成立的话)。 一些单片机(如8051结构)的硬件能够自动实现中断嵌套的处理,既单片机内部的硬件电路能够识别中断的优先级,并根据优先
[单片机]
采用AVR Flash微控制器的电动车窗防夹系统
汽车上可自动关闭的电动车窗或车门设备潜藏着卡死,挤压以及可能伤人的危险。它们必须能够反向移动以防止马达所施加的力超出正常限制。这种特性意味着必须持续监视速度、电流和玻璃的位置。 由于成本和简化的原因,本文所描述的系统使用普通的带有霍尔效应传感器的刷式马达。基于速度和扭矩导数的检测算法已通过健壮性和容错性的验证。该算法可用于所有带有A/D 转换器和通过变化引发中断的I/O 口的AtmelAVR Flash 微控制器。本文描述的是基本原理,Atmel网站上的应用笔记有关于实现的详细描述。 现代汽车中的电动设备 目前,在高端客用汽车中电子组件和系统在成本中已占20%以上。增加电子设备的数目可以更好的控制传感器和致动器,从而增
[单片机]
Atmel推出用于工业电机控制的AVR微控制器
  爱特梅尔公司( Atmel ® Corporation)宣布推出专为满足具有CAN和LIN连接能力的先进电机控制应用对高精度脉宽调制( PWM )的需求而开发的全新 AVR ® 微控制器系列ATmega16M1、ATmega32M1和ATmega64M1,瞄准工业控制市场。新器件系列具有16、32和64KB闪存、通用IO引脚、模数转换器、模拟比较器、功率级控制器,以及8位和16位定时器,是需要CAN和LIN连接能力之工业控制应用的理想选择。   ATmega16M1、ATmega32M1和ATmega64M1基于高性能 AVR 8位RISC架构,集成了复杂电机控制算法所有必须的基础功能。这些器件提供了独特的功能组合,能够
[单片机]
stm32笔记:启动代码startup_stm32f10x_hd.s注解(1)stm32笔记:启动代码s
;******************** (C) COPYRIGHT 2010 STMicroelectronics ******************** ;* File Name : startup_stm32f10x_hd.s ;* Author : MCD Application Team ;* Version : V3.4.0 ;* Date : 10/15/2010 Stack_Size EQU 0x00000400 //定义1KB大小的栈空间 AREA STACK, NOINIT, READWRITE, ALIGN=3 //定义一个段,8(2的3次方)字节对齐 的空间作为栈 S
[单片机]
基于AVR和FPGA高精度数字式移相发生器的设计
1引 言   语音编码算法利用语音信号的冗余信息及某些人耳不敏感的信息,可以在低比特率上获得较高质量的重建语音,压缩编码一直是通信中的关键技术。语音信号研究者们一直在寻求一种在保持语音质量不显著下降的情况下使语音信号的编码比特率最小的方法,特别地,低比特率语音编码体制(比特率在4.8 kb/s以下)因其广泛的需求而得到研究者的重视。   语音编码器的性能常常用比特率、延时、复杂度和质量4个属性来进行衡量,因此,在分析语音编码器的性能时,主要应该考虑这些属性。值得注意的是,这些属性之间不是孤立的,而是相互紧密联系的,例如,低比特率的编码器一般比高比特率的编码器有更大的延时、更高的算法复杂度和较低的语音质量。因此在对各种编码算法进
[应用]
基于AVR单片机的中频电源测试系统的设计
1 引言   电参数的测量和监控是电力系统的重要组成部分,本文从测试系统的工程学实际出发,完成了对中频电源系统的电压、电流、频率、功率因数、有功功率等参数的测量和实时监控,较好的实现了中频电源测试系统的功能和工程要求。   AVR单片机相对传统的 51系列单片机,具有更高的集成度和更强的功能,与 C语言有很好的兼容性,RISC指令架构使其运行速度可达 1MIPS/MHZ。随着其越来越广泛的应用,必将取代 51系列成为单片机的主流。其主要功能包括看门狗、FLASH程序存储器、 E2PROM、 A/D转换器、定时器、计数器、USART接口等多种功能,这使得本测试系统的硬件实现变得简单,可靠。   2 硬件结构设计与实现  
[单片机]
热门资源推荐
热门放大器推荐
  •  pdf文件单片机原理及应用 第3版 (张毅刚)
  •  pdf文件Metronom实时操作系统面向AVR微控制器的RTOS
  •  pdf文件构建实时机器学习系统
  •  pdf文件爱上Arduino 第4版(英文版)
  • 系统发生错误

    系统发生错误

    您可以选择 [ 重试 ] [ 返回 ] 或者 [ 回到首页 ]

    [ 错误信息 ]

    页面错误!请稍后再试~

小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved