U-BOOT start.s

U-Boot介绍以及start.S解析 什么是U-Boot U-Boot是一个开源的系统引导,是用开引导启动内核的。它的整个工作可以分为两个部分,两部分合力完成把程序加载到内存中启动内核的工作。U-Boot是由根据Linux源代码改变删减发展而来的,所以U-Boot工作的两部分中的第一部分的源代码主要由汇编语言完成硬件的初始化,搭建C语言可以运行的环境,第二部分主要由C语言完成剩余其他工作。这样的系统的移植性会更好。 什么是star... 阅读详情

用的U-BOOT版本是1.1.2,CPU是S3C2410
U-BOOT源码在这里可以下到http://sourceforge.net/projects/u-boot/files/u-boot/
*/

#include <config.h>
#include <version.h>

/*
*************************************************************************
*
* Jump vector table as in table 3.1 in [1]
*
*************************************************************************
*/

.globl _start        ;声明一个全局变量,可以把它当然一个程序标号,不过在整系统中是都可以使用的,globl是一个伪指令,可以查看资料,它不进行数据操作
_start: b       reset      ;跳转到复位异常执行,优先级为1
ldr pc, _undefined_instruction    ;该指令存放地址为0x00000004,是示定义指令异常入口,也就是说当产生未定义异常时,程序寄存器PC会自动给赋值0x00000004,学过单片机的应该明白,优先级为6
ldr pc, _software_interrupt                         ;软件中断入口,存放地址为0x00000008,优先级为6,因为它和未定义指令异常是互斥的,所有可以为同一优先级
ldr pc, _prefetch_abort     ;指令预取终止异常,地址为0x0000000c,十六进制表示,这应该清楚吧
ldr pc, _data_abort                                 ;数据访问终止异常,地址为0x00000010
ldr pc, _not_used      ;未使用异常,地址为0x00000014,还不清楚是做什么的,清楚的请补充
ldr pc, _irq      ;外中断异常,地址为0x00000018
ldr pc, _fiq      ;快速中断异常
/*以上是ARM920T核的9个异常入口地址,其中 b reset不需要返回,好好想下为什么!呵呵。*/
_undefined_instruction: .word undefined_instruction   ;这条指令相当用undefined_instruction对_undefined_instruction赋值,.word也是一个伪指令,它说明赋的值为字!这些值应该都在链接时生成        
_software_interrupt: .word software_interrupt   ;说明下,在ARM中,8位的为字节,十六位的为半字,三十二位的字,下面几条指令一样,不多说
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .word not_used
_irq:   .word irq
_fiq:   .word fiq
.balignl 16,0xdeadbeef     ;没搞明白,不是浪费空间么?还是十六的倍数!可以查看http://haoyeren.blog.sohu.com/84511571.html

/*
*************************************************************************
*
* Startup Code (reset vector)                           这里介绍了整个start.S代码的作用:
*                                   初始化内存,移动代码到内存,设置堆栈等
*************************************************************************
*/
_TEXT_BASE:
.word TEXT_BASE      ;TEXT_BASE对_TEXT_BASE赋值,TEXT_BASE在board/smdk2410/config.mk文件中定义,值为0x33F80000,如果是64M内存的话,它就是内存的最后一个地址,有点意思
.globl _armboot_start      ;声明全局变量
_armboot_start:
.word _start       ;_start对_armboot_start赋值,_start的值由链接文件生成,也是程序的入口地址          

.globl _bss_start       ;声明一个代码段的开始标号
_bss_start:
.word __bss_start      ;并用__bss_start对它赋值,这个值应该是在链接时候生成
.globl _bss_end       ;声明一个代码段的结束标号
_bss_end:
.word _end       ;并用_end对它赋值,也是在链接的时候生成
#ifdef CONFIG_USE_IRQ      ;如果定义了CONFIG_USE_IRQ名,可能是在IRQ(包括FIQ)中断保护时对其有定义,先不理,回头再看它
/* IRQ stack memory (calculated at run-time) */
.globl IRQ_STACK_START      ;声明一个外中断处理程序规堆栈的开始名
IRQ_STACK_START:
.word 0x0badc0de      ;对刚声明的IRQ_STACK_START进行赋值,值为0x0badc0de,不知道为什么设这个值,它影射不到SDRAM的任何地址吧,带着疑问继续
/* IRQ stack memory (calculated at run-time) */
.globl FIQ_STACK_START      ;声明一个快中断程序处理堆栈的开始名
FIQ_STACK_START:
.word 0x0badc0de                                       ;对刚声明的FIQ_STACK_START赋值为0x0badc0de,它跟外中断的堆栈始地址相同
#endif         ;配合#ifdef一起用

/*
* the actual reset code实际的复位代码    ;好了,到这里开始执行CPU初始化工作了,以下用尽量符号表示其指令含义
*/
reset:
/*
* set the cpu to SVC32 mode   设置CPU工作在32位管理模式
*/
mrs r0,cpsr      ;r0<--cpsr,把cpsr送到r0中      ;
bic r0,r0,#0x1f      ;对r0中的01234位清0,把0x1f转换为二进制为0b00011111,明白为什么为012345位了吧,bic是一个位清0指令
orr r0,r0,#0xd3      ;orr是或逻辑运算指令,它的意思是r0 | 0xd3,再把运算结果放到r0中,0xd3转换为二进制0b11010011,这时r0的8位就应该是这个0b11010011了    
msr cpsr,r0      ;再把r0的值送到程序状态寄存器cpsr中,些时cpsr中的值为0b11010011,用这些字符(I F T M4 M3 M2 M1 M0)表示cpsr的低8位,I=1表示禁止IRQ中断,F=1表示禁止FIQ中断,T=0,表示以下的指令是ARM指令集开始执行
         ;也就是32位指令集,(还有一个THUMB是16位指令集)低5位的值使CPU工作在管理模式,这个模式下可以处理软中断SWI。
/* turn off the watchdog */                                   ;关闭看门狗,为什么关呢,这时CPU还没有初始化,没有喂狗信号,时间一长CPU就会自动复位了!
/*下面这段代码主要是关闭看门狗,屏蔽所有中断,设置CPU时钟*/
#if defined(CONFIG_S3C2400)      ;如果定义了CONFIG_S3C2400,那么执行下面三行语句,s3c2410这段没有定义,下面三行不说了
# define pWTCON 0x15300000   
# define INTMSK 0x14400008 /* Interupt-Controller base addresses */
# define CLKDIVN 0x14800014 /* clock divisor register */
#elif defined(CONFIG_S3C2410)     ;如果定义了CONFIG_S3C2410执行下面四行语句
# define pWTCON 0x53000000    ;宏定义,地球人都知道了 ~_~ ,0x53000000是看门狗控制寄存器,以后再用它的时候是不是很方便,查下DATASHEET就知道了
# define INTMSK 0x4A000008 /* Interupt-Controller base addresses */ ;0x4A000008是中断屏蔽寄存器
# define INTSUBMSK 0x4A00001C     ;0x4A00001C是子中断屏蔽寄存器   
# define CLKDIVN 0x4C000014 /* clock divisor register */时钟分频寄存器,用于控制FCLK,HCLK,PCLK之间的时钟关系
#endif
#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)    ;我们定义了2410的的
ldr     r0, =pWTCON      ;把看门狗寄存器的地址加载到r0
mov     r1, #0x0      ;r1 <-- #0
str     r1, [r0]      ;对看门狗寄存器清0     
/*
* mask all IRQs by setting all bits in the INTMR - default
*/
mov r1, #0xffffffff     ;r1 <-- #0xffffffff
ldr r0, =INTMSK      ;把中断屏蔽寄存器地址赋到r0
str r1, [r0]      ;对中断屏蔽寄存器位全置1,屏蔽所有中断
# if defined(CONFIG_S3C2410)     ;到这里是不是看到了两种关于#define的用法,对比刚才的,不同的时候不同的妙用!
ldr r1, =0x3ff      ;r1 <-- 0x3ff,等号表示后面的是立即数,可以直接用
ldr r0, =INTSUBMSK     ;这里引用了宏定义,相当于r0 <--0x4A000008
str r1, [r0]      ;把0x3ff存到0x4A000008地址里,也是中断寄存器进行设置,屏蔽部分中断,要根据实际配置
# endif
/* FCLK:HCLKCLK = 1:2:4 */    ;设置FCLK、HCLK、PCLK的比例关系
/* default FCLK is 120 MHz ! */                        ;看DATASHEET也没看明白为什么初始FCLK为120M,晕倒,跟DATASHEET不一样
ldr r0, =CLKDIVN      ;把时钟频控制寄存器地址赋给r0
mov r1, #3       ;r1 <-- 3
str r1, [r0]      ;把3赋给时钟控制寄存器,这时FCLK:HCLK:PCLK=1:2:4,查看DATASHEET可以得到,FCLK指CPU内核的工作频率;HCLK指一些高速设备频率,比如USB,LCD,网口等;PCLK指低速的设备如IDE,SPI等
#endif

/* CONFIG_S3C2400 || CONFIG_S3C2410 */  

/*
* we do sys-critical inits only at reboot,
* not when booting from ram!
*/
#ifdef CONFIG_INIT_CRITICAL      ;到这里忽然意识到,包括上面类似的指令,应该都在UBOOT的Makefile找到定义,也就是判断的这些定义,先不管
bl cpu_init_crit      ;要初始化CPU(包括内存),同时把当前r15(PC寄存器)保存到r14(程序链接寄存器),保护现场,上面那个应该条件成立吧,不然后CPU怎么工作,好现在我们看它到哪里去了,到这里要跳转了,跟着程序走哟
#endif         ;执行bl的时候系统会自动保存,舒服吧

relocate:    /* relocate U-Boot to RAM     */ ;这下面这段程序就要移代码了,因为SRAM已经初始化(我们假设的,回头再看那),2410片内的4KSRAM用得应该差不多了吧
adr r0, _start /* r0 <- current position of code   */;adr伪指令,把_start的地址赋给r0,_start还记得吧,链接生成的地址
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */;查看上面定义过的_TEXT_BASE,ldr是把地址为0x33F80000的数据读到r1,测试下看内在初始化OK了没,ldr指令一般用于从存储器中读取数据
cmp     r0, r1                  /* don't relocate during debug         */;r0与r1中的数据比较,实际上是r0、r1进行减运算,大、小、等于来更改CPSR的标志位(第31位,也是最高位),1为正数,0为负数,r0>r1标志位清0,些时后面GT后缀的指令可以执行
beq     stack_setup         ;如果r0=r1,则跳转到stact_setup(用于堆栈设置)
/*下面4行代码用于计算要移动的代码的大小,还不太清楚是怎么计算出来的,到连接的时候再回头看*/
ldr r2, _armboot_start        ;把地址给r2
ldr r3, _bss_start        ;把代码的起始地址给r3
sub r2, r3, r2 /* r2 <- size of armboot            */ ;r2 <-- r3 - r2
add r2, r0, r2 /* r2 <- source end address         */ ;r2 <-- r0 + r2
/*下面4行用于移动代码*/
copy_loop:
ldmia r0!, {r3-r10} /* copy from source address [r0]    */ ;以r0的值为地址递增的加载到r3-r10,并把最的的基址给r0
stmia r1!, {r3-r10} /* copy to   target address [r1]    */ ;把r3-r10的数据送到以r1的值为地址递增的地址空间里,并把最后的基址给r1
cmp r0, r2   /* until source end addreee [r2]    */ ;判断有没有移动完成
ble copy_loop         ;r0若小于等于r2,则跳转到copy_loop

/* Set up the stack ;堆栈初始化,现在还不知道位置在哪里,链接的时候再回头看    */  
stack_setup:
ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot   */ ;把内存地址为0x33F80000(最后一个地址)中的数据加载到r0,可以猜测u-boot可能把堆栈设置在了内存的最高地址
sub r0, r0, #CFG_MALLOC_LEN /* malloc area                      */ ;r0 <-- r0-#CFG_MALLOC_LEN,CFG_MALLOC_LEN在include/configs/smdk2410.h文件中有定义
sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo                        */ ;r0 <-- r0-#CFG_GBL_DATA_SIZE,CFG_GBL_DATA_SIZE值为128,在include/configs/smdk2410.h文件中有定义,这两条指令可能是用于设置堆栈空间大小和单位
#ifdef CONFIG_USE_IRQ
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)   ;r0 <-- r0-#CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ,不知道这个在哪里定义,在根目录下搜索也没找到,可能由编译器产生吧
#endif
sub sp, r0, #12 /* leave 3 words for abort-stack    */ ;sp <-- r0-#12,给堆栈指针赋值


clear_bss:
ldr r0, _bss_start /* find start of bss segment        */ ;把_bbs_start地址存到r0
ldr r1, _bss_end /* stop here                        */ ;把_bbs_end地址存到r1
mov r2, #0x00000000 /* clear                            */ ;r2 <--#0x00000000


clbss_l:str r2, [r0] /* clear loop...                    */ ;0x00000000 --> _bss_start
add r0, r0, #4         ;r0 <-- r0 + #4
cmp r0, r1          ;r0与r1比较,实际上是进行减运算,但不改其值,只更新标志位
bne clbss_l         ;r0,r1不相等跳转,只到代码段尾,这样所有代码地址就被清0了,难道是为BOOTLOAD 2阶段做准备?

#if 0            ;为假,先不理,继续走
/* try doing this stuff after the relocation */
ldr     r0, =pWTCON
mov     r1, #0x0
str     r1, [r0]

/*
* mask all IRQs by setting all bits in the INTMR - default
*/
mov r1, #0xffffffff
ldr r0, =INTMR
str r1, [r0]

/* FCLK:HCLKCLK = 1:2:4 */
/* default FCLK is 120 MHz ! */
ldr r0, =CLKDIVN
mov r1, #3
str r1, [r0]
/* END stuff after relocation */
#endif

ldr pc, _start_armboot        ;pc <-- _start_armboot

_start_armboot: .word start_armboot       ;start_armboot是一个C函数指针,也就是阶段2的入口程序地址。到这里阶段1完成http://www.diybl.com/course/6_sy ... /200876/130696.html


/*
*************************************************************************
*
* CPU_init_critical registers        下面段程序主要设置关键的寄存器,和内存的时序,应该是SDRAM的吧,这里可是算是到了重要的地方了
*
* setup important registers
* setup memory timing
*
*************************************************************************
*/


cpu_init_crit:
/*
* flush v4 I/D caches                                      刷新缓存,V4的意思是S3C2410内核的架构
*/
mov r0, #0
mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */   ;把ARM寄存器里的r0,写到协处理器p15的c7(c7用于控制缓存)寄存器中,一般为是只写的,读没有意义,其中的两个0,是操作码
mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */    ;刷新v4架构的TLB(TLB一般也是只写的),TLB就是内在映射表,MMU才会用得着吧,参考资料http://hi.baidu.com/grqq7/blog/item/6393607fd0b0af0b28388a8d.html
            ;不明白这里为什么写两次,暂且放过
/*
* disable MMU stuff and caches       ;下面就关于到MMU的设置了
*/
mrc p15, 0, r0, c1, c0, 0       ;把协处理器p15的c1(缓冲类型寄存器)、c0(ID号寄存器)寄存器读到ARM寄存器r0中,
bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)   ;对r0的13、9、8位清0
bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)   ;对r0的7、2、0位清0
orr r0, r0, #0x00000002 @ set bit 1 (A) Align    ;对r0的1位置1(寄存器的最低位为0位)
orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache    ;对r0的12位置1
mcr p15, 0, r0, c1, c0, 0       ;把r0的数据送到c1、c0中,原来ID号是这样写进去的呀,哈哈  


/*
* before relocating, we have to setup RAM timing
* because memory timing is board-dependend, you will    ;cpu_init_crit调用快要返回了,不过在返回之前要设置SRAM的操作时序,设置好就可以使用SDRAM了!
* find a memsetup.S in your board directory.
*/
mov ip, lr          ;先看下先行指令吧,为避免再次调用把lr寄存器的数据给覆盖掉,给于保护,ip寄存器就是一个过程调用中间的一个临时寄存器
bl memsetup         ;跳转到到内存设置程序,bl 是带返回的跳转,对比下本段程序的第一条跳转指令b,好现在看下跑哪里去了,看代码时要注意看注释,就在我们的board/smdk2410下,
mov lr, ip          ;内存设置代码先放一下,回头再把它给贴上来!这里假设内存已经初始化成功,把调用memsetup前保存到lr值恢复

mov pc, lr          ;这里就是把调用cpu_init_crit时的程序指针恢复,这里PC指向bl调用cpu_init_crit的一条指令的地址,到这里现在返回到调用cpu_init_crit


/*
*************************************************************************
*
* Interrupt handling 下面这段代码是中断处理函数,不理它,累人,先把总体流程给搞清楚再说
*
*************************************************************************
*/

@
@ IRQ stack frame.
@
#define S_FRAME_SIZE 72

#define S_OLD_R0 68
#define S_PSR 64
#define S_PC 60

本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/LUHONGXING/archive/2009/11/30/4907293.aspx

u-boot分析 四 (程序入口start.S) u-boot分析 四 (程序入口start.S)注:部分内容摘抄自网络,如有问题,请联络博主。本文内容:了解以stars.S为开始的ARM汇编程序部分。回顾前几篇博文,咱们见识过了u-boot的目录结构,另外简要分析了u-boot.lds脚本文件的link原理。而今天我们要来听听嵌入式程序君告诉咱们的第一句“话”。正式开始之前,我们需要准备三样东西: u-boot source code 常用ARM 阅读详情

相关推荐

u-boot——start.S文件(属于第一阶段)分析

start.s(链接脚本u-boot指定) cpu/s5pv11x/start.s    入口_start 独立编址:如内核不能访问nandflash的地址,该地址为独立编址;ddr里面的地址为统一编址 irom内容只能读出来,不能写进去 irom功能:关闭开门狗;打开icache;初始化iram的堆,栈;初始化系统时钟;判断启动方式引脚, 确定uboot代码在哪里拿进去

hpr1992的专栏 991

UBOOT移植

用的U-BOOT版本是1.1.2,CPU是S3C2410U-BOOT源码在这里可以下到http://sourceforge.net/projects/u-boot/files/u-boot/*/#include #include /**************************************************************************** Jump ve

LUHONGXING的专栏 1067

2022版u-boot启动分析笔记之一(start.S与lowlevel_init.S)

分析2022版U-Boot的启动过程Stage1,包括start.S和lowlevel.S的分析。

weixin_42408707的博客 1080

安卓bootloader:三分钟让你彻底理解uboot的启动与功能

1. Bootloader简介 系统上电后,需要一段程序来进行初始化:关闭看门狗,改变系统时钟,初始化存储控制器,将更多的代码复制到内存中等。它就是bootloader。 bootloader的实现非常依赖具体硬件,在嵌入式系统中,硬件配置千差万别,即使是相同的CPU,它的外设(比如flash)也可能不同,所以不可能有一个bootloader支持所有的CPU,所...

不忘初心 3万+

计算机视觉——SIFT特征匹配

文章目录一、SIFT特征检测原理1.1基本思想1.2二、SIFT特征检测图片兴趣点三、SIFT特征检测描述子匹配四、输入图片检测与之 一、SIFT特征检测原理 1.1基本思想 1.2 二、SIFT特征检测图片兴趣点 代码: 检测结果: 三、SIFT特征检测描述子匹配 四、输入图片检测与之 ...

weixin_43869874的博客 3855

AntV G6边动画实战:手把手教你实现数据流向箭头与虚线流动效果

本文详细解析了如何使用AntV G6实现数据流向箭头与虚线流动效果,通过自定义边动画提升数据可视化的动态表现力。从基础环境搭建到核心概念讲解,再到虚线流动动画和箭头路径动画的具体实现与参数调控,帮助开发者掌握G6边动画的高级技巧,适用于网络流量监控、数据传递等场景。

weixin_28487433的博客 264

u-boot1.1.4移植

u-boot移植前的准备工作:1 下载源码,建立工作目录Uboot的源码可以从以下网址下载:http://downloads.sourceforge.net/u-boot/u-boot-1.1.4.tar.bz2?modtime=1134752480&big_mirror=0我们这里下载的是u-boot-1.1.4.tar.bz2建立工作目录:mkdir /root/build_ubootcd /

wiserstar的专栏 1119

Halcon dyn_threshold详解

dyn_threshold 原型 dyn_threshold(OrigImage, ThresholdImage : RegionDynThresh : Offset, LightDark : ) 功能 利用局部阈值分割图像 参数列表 OrigImage (input_object):原始图像 ThresholdImage (input_object):处理后图像(一般采用滤波处理) RegionDynThresh (output_object):分割后区域 Offset (input_control):灰

ZiLiangQin的博客 1万+

uboot系统分析

一、前言 uboot是一套小系统开源系统,在网络上我们能够找到对这个系统较多的分析,展锐团队在此基础 上适配了对应芯片的开机流程。采用了 uboot 系统, 和其它平台类似,虽然 u boot 本身就是双启动流程即( s pl -->uboot ),但是展锐依然 脱离 uboot 实现 自己 S PL 镜像, 因此小系统的组成变为 s pl/uboot 组合,和高通 xbl/uefi 及 M TK 平台 PBL /lk 类似 。 唯一的区别在于 U BOOT 的跳转过程。展锐平台的启动流程如下:

chbgoon的博客 1866

Linux USB设备命名规则

有一个USB设备,接到了Linux系统的终端的某个插口上,那么怎么找到这个设备对应设备路径呢?这个USB设备虚拟了多个功能(三个串口和一个网卡), 如何找到对应操作路径呢?

weixin_43132521的博客 1697

Camera HAL Camx — DRQ总结

Camera HAL — DRQ(延迟请求队列)总结 DRQ是CAMX核心层的依赖驱动延迟执行调度器,解决Node处理请求时依赖未就绪的问题。其主要特点包括: 核心功能:当Node处理请求时缺少必要输入(property/metadata/fence),DRQ将其挂起并在依赖满足后重新调度,避免阻塞流水线或丢帧。 系统架构:Session持有主DRQ实例,管理该Session下所有Pipeline Node的依赖;CHI context另有独立DRQ实例专门处理Chi fence同步。 关键数据结构: De

DU_YULIN的博客 74

高通机型刷机包的分区解析 了解分区基本常识

其实还有很多分区没有列出来。但有些分区系统启动会自动加载。有些分区是关键分区。例如内核boot .rec .基带。tz uboot等等这些关键分区如丢失或者损坏,轻则系统卡logo。你刷了不对应的分区后系统黑屏救砖线刷其实只需要刷对应你搞错的分区就可以救回。而不需要刷全包丢失用户数据.有些分区只是个人对其的理解。

小马哥的专栏 1万+

零倾覆力矩点(ZMP)

从形式上讲,ZMP 指的是空间中相对于一个平面(通常是地平面)抵消接触力矩的点的集合。这个集合实际上是一个轴,而不是一个点,但为了方便起见,让我们按照传统的推导方法来计算地面平面上的 ZMP。这一推导从任何多刚体系统的牛顿-欧拉运动方程开始:其中,为机器人的总质量,为重力矢量,为系统的重心,为加速度,为固定点的角动量变化率。在右侧,表示净接触扭矩,即施加到机器人上的所有接触扭矩之和,坐标取自质心 (COM)。

机器人控制与仿真应用 2371

【Linux】U-Boot启动文件start.S详解(超详细讲解,上篇)

U-Boot U-Boot的版本选择 U-Boot的下载地址:/pub/u-boot的索引 进入到U-Boot的下载页面,发现U-Boot的版本众多: 那怎么选取U-Boot的版本呢?够用就行。 本文芯片选择S5PV210,U-Boot版本选择u-boot-2010.12版本。 U-Boot两个文件夹 在U-Boot的源码文件中,先简单介绍两个目录: 目录U-boot/arch/arm/cpu/...

Yngz_Miao的博客 5万+

把 ABAP ALV 表头做成两层分组:用 TOP-OF-PAGE 手工绘制双行列标题

摘要:本文介绍了在SAP ALV List中实现双层表头的方法。通过关闭系统默认列标题(no_colhead='X'),在TOP_OF_PAGE事件中手动绘制表头,使用sy-uline和sy-vline绘制线条实现分组效果。关键点包括:1)关闭系统表头;2)在事件处理中分两行输出分组标题和字段名;3)利用系统自动拼接线条的特性绘制表格边框。文中还指出了常见问题如线条自动粘连、颜色不生效等,并提供了完整示例代码和详细解释。这种方法适用于需要对字段进行业务分组的报表场景。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 257

基于四旋翼模型的火箭型无人机视线角保持控制仿真设计

本文针对火箭型无人机的视线角保持控制问题展开研究。基于四旋翼动力学模型,通过改造设计了一种摄像头朝上安装的特殊无人机系统,用于追踪空中目标。文章详细推导了坐标系定义、运动学和动力学方程,重点分析了摄像头安装与视线几何关系,建立了目标运动模型和视线向量计算方法。通过解算期望姿态角,实现了使机体Z轴始终对准目标的控制目标。仿真结果表明,该系统能有效完成视线角保持任务,为空对空监视等应用场景提供了可行方案。~~~~~

huanghm88的专栏 140

U-Boot源码之start.s

start.S 文件是U-Boot启动最先执行的代码,对start.S 文件的正确理解是整个U-Boot源码理解的开端和基础。要理解start.S 文件,需要具备一些预备知识,下面先介绍这些预备知识。 一、start.S预备知识

Enjoy working的博客 876

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

U-BOOT源码中start.S分析

在嵌入式设备中需要一段代码来引导系统的启动,就像windows系统是通过BIOS来引导启动的,嵌入式设备中的引导代码叫做Bootloader,Bootloader有很多中,其中U-BOOT是最常用的一种。通过顶层的Makefile分析,U-BOOT是从start.o开始执行的,所以有必要分析start.S的代码,start.S的代码不是很长,主要完成了CPU的模式设置、关看门狗、关闭中断,设置堆栈

嵌入式菜鸟的专栏 754

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

u-boot启动代码start.S详解

u-boot启动代码start.S详解  U-BOOT一、U-BOOT的目录结构u-boot目录下有18个子目录,分别存放管理不通的源程序。这些目录中所要存放的文件有其规则,可以分成三类。■第一类目录与处理器体系结构或者开发板硬件直接相关;■第二类目录是一些通用的函数或者驱动程序;&#65517

dongliqiang2006的专栏 1571

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

u-boot启动分析01(u-boot.lds,start.S)

1.查找u-boot.lds 2.分析u-boot.lds 3.分析start.S

Charles Zhang 的博客 1110

【u-boot】u-boot启动文件start.S剖析(ARM64)

ARM64 U-Boot启动流程分析 本文分析了ARM64架构下U-Boot的启动入口代码start.S。主要流程包括: 定义_start入口点,根据配置跳转到reset或执行SoC特定的启动代码 设置地址无关代码(PIC)重定位处理 异常向量表初始化,根据不同异常级别(EL3/EL2/EL1)配置系统控制寄存器 启用SMP多核同步支持 应用ARM核心特定的勘误表修正 处理器底层初始化后进入主CPU流程或从CPU等待流程 代码展示了U-Boot在ARM64平台上的底层初始化过程,包括异常处理、缓存控制、多核

iriczhao的博客 554

u-boot-1.1.6 start.S代码笔记

u-boot 1.1.6  start.S 代码学习/*参考了别人的一些笔记,看完了启动代码。本文档记录在看代码时碰到的困难,将这些曾经困扰的问题记录下来,以备今后之用。分析时不重要的代码被删除了。*/.globl _start_start: b       reset    ldr  pc, _undefined_instruction    ldr  pc, _

rockhard的专栏 7225

u-boot start.S内容分析

根据之前的《u-boot 链接脚本内容分析》中可以知道 u-boot执行时的第一个文件是/u-boot-1.1.6/cpu/arm920t/start.s start.s的主要工作分为: 设置运行模式为svc模式 关看门狗 屏蔽中断 初始化SDRAM 设置栈(此时可以调用c函数) 使能时钟 重定位 代码从FLASH拷贝到SDRAM 清bss段 调用start_armbo...

yogach的博客 214

U-boot(三):start.S

转换表是虚拟地址映射的关键包含表索引和表项,表索引对应虚拟地址,表项对应物理地址,表索引和表项构成转换表单元,可对内存块进行虚拟地址转换,转换表由转换表单元构成,每个单元对应1个内存块,整体对应整个内存空间(0-4G)的映射。构建异常向量表,启动介质选择,设置CPU为SVC模式,关看门狗,开发板供电置锁,时钟初始化,DDR初始化,串口初始化并打印"OK",重定位,建立映射表并开启MMU,清理bss,跳转到第二阶段。start.S uboot 一阶段

tyro_wzp的博客 372

U-Boot源代码阅读笔记(一) —— 对start.S的分析

U-Boot源代码阅读笔记(一) —— 对start.S的分析本文主要分析与U-Boot启动过程相关的汇编代码cpu/pxa/start.S,目标平台以PXA270为例。 系统启动执行的第一条指令/* armboot - Startup Code for XScale */.globl _start_start: b    reset    /*跳转到reset标号执行*

sunrock的专栏 7142

U-Boot源码——start.S

start.S是U-Boot执行的第1个文件,是U-Boot的入口,保存于平台相关arch目录的各cpu子目录中,例如U-Boot-2011.12的arch/arm/cpu/arm920t/start.S内容如下: #include #include #include /* ********************************************************

OneSea 951
上一篇: u-boot的内存分布和全局数据结构
下一篇: U-Boot的加载地址分析
Alan0521
博客等级 码龄19年 77粉丝 6原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值