历史上的今天

今天是:2024年11月18日(星期一)

2019年11月18日 | u-boot-1.3.4 移植到S3C2440

发布者:DelightfulSmile 来源: 51hei关键字:u-boot-1  移植  S3C2440 手机看文章 扫描二维码
随时随地手机看文章

一.预备知识:
1. 首先,U-Boot1.3.4还没有支持s3c2440,移植仍是用2410的文件稍作修改而成的。


2. 2440和2410的区别:
2440和2410的区别主要是2440的主频更高,增加了摄像头接口和AC‘97音频接口;寄存器方面,除了新增模 块的寄存器外,移植所要注意的是NAND FlASH控制器的寄存器有较大的变化、芯片的时钟频率控制寄存器(芯片PLL的寄存器)有一定的变化。其他寄存器基本是兼容的。


3. 你开发板的boot方式是什么,开发板上电以后是怎么执行的。
一般来说三星的开发板有三种启动方式:nand、nor、ram。
具体用那一种方式来启动决定于CPU的0M[0:1]这两个引脚,具体请参考S3C2440的datasheet

nand:对于2440来说,CPU是不给nand-flash分配地址空间的,nand-flash只相当于CPU的一个外设,S3C2440做了一个从nand-flash启动的机制。开发板一上电,CPU就自动复制
nand-flash里面的前4K-Bytes内容到S3C2440内部集成的SDRAM,然后把4K内容所在 的RAM映射到S3C2440的0地址,从0地址开始执行。这4K的内容主要负责下面这些工 作:初始化中断矢量、设定CPU的工作模式为SVC32模式、屏蔽看门狗、屏蔽中断、 初始化时钟、把整个u-boot重定向到外部SDRAM、跳到主要的C函数入口。
nor: 早期的时候利用nor-flash启动的方式比较多,就是把u-boot烧写到nor-flash里面, 直接把nor-flash映射到S3C2440的0地址,上电从0地址开始执行。
ram: 直接把u-boot放到外部SDRAM上跑,这一般debug时候用到。


4. u-boot程序的入口地址问题
要理解程序的入口地址,自然想到的是连接文件,首先看看开发板相对于某个开发板的连接文件"/board/你的开发板/u-boot.lds",看一个2410的例子:
ENTRY(_start)
SECTIONS
{
. = 0x00000000;


. = ALIGN(4);
.text :
{
cpu/arm920t/start.o (.text)
*(.text)
}


. = ALIGN(4);
.rodata : { *(.rodata) }


. = ALIGN(4);
.data : { *(.data) }


. = ALIGN(4);
.got : { *(.got) }


__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;


. = ALIGN(4);
__bss_start = .;
.bss : { *(.bss) }
_end = .;
}
(1) 从ENTRY(_start)可以看出u-boot的入口函数是_start,这个没错
(2) 从. = 0x00000000也许可以看出_start的地址是0x00000000,事实并不是这样的,这里的0x00000000没效,在连接的时候最终会被TETX_BASE所代替的,具体请参考u-boot根目录下的config.mk.
(3) 网上很多说法是 _start=TEXT_BASE,我想这种说法也是正确的,但没有说具体原因。
本人的理解是这样的,TEXT_BASE表示text段的起始地址,而从
.text :
{
cpu/arm920t/start.o (.text)
*(.text)
}
看,放在text段的第一个文件就是start.c编译后的内容,而start.c中的第一个函数就是
_start,所以 _start应该是放在text段的起始位置,因此说_start=TEXT_BASE也不为过。


5. 一直不明白的U-BOOT是怎样从4Ksteppingstone跳到RAM中执行的,现在终于明白了。关键在于:
ldr pc, _start_armboot
_start_armboot: .word start_armboot
这两条语句,ldr pc, _start_armboot指令把_start_armboot这个标签的地方存放的内容(也即是start_armboot)移到PC寄存器里面,start_armboot是一个函数地址,在编译的时候给分配了一个绝对地址,所以上面语句实际上是完成了一个绝对地址的跳转。而我一直不明白的为什么在start.S里面有很多BL,B跳转语句都没有跳出4Ksteppingstone,原因是他们都是相对于PC的便宜的跳转,而不是绝对地址的跳转。还有要补充一下LDR,MOV,LDR伪指令的区别。
LDR R0,0x12345678 //把地址0x12345678存放的内容放到R0里面
MOV R0,#x //把立即数x放到R0里面,x必须是一个8 bits的数移到偶数次得到的数。
LDR R0,=0x12345678 //把立即数0x12345678放到R0里面


6. 在移植u-boot-1.3.3以上版本的时候要注意:
在u-boot1.3.3及以上版本Makefile有一定的变化,使得对于24x0处理器从nand启动的遇到问题。也就是网上有人说的:无法运行过lowlevel_init。其实这个问题是由于编译器将我们自己添加的用于nandboot的子函数nand_read_ll放到了4K之后造成的(到这不理解的话,请仔细看看24x0处理器nandboot原理)。我是在运行失败后,利用mini2440的4个LED调试发现u-boot根本没有完成自我拷贝,然后看了uboot根目录下的System.map文件就可知道原因。
解决办法其实很简单:
将__LIBS := $(subst $(obj),,$(LIBS)) $(subst $(obj),,$(LIBBOARD))
改为__LIBS := $(subst $(obj),,$(LIBBOARD)) $(subst $(obj),,$(LIBS))


7. 然后说一下跳转指令。ARM有两种跳转方式。
(1)mov pc <跳转地址〉
这种向程序计数器PC直接写跳转地址,能在4GB连续空间内任意跳转。
(2)通过B BL BLX BX可以完成在当前指令向前或者向后32MB的地址空间的跳转(为什么是32MB呢?寄存器是32位的,此时的值是24位有符号数,所以32MB)。
B是最简单的跳转指令。要注意的是,跳转指令的实际值不是绝对地址,而是相对地址——是相对当前PC值的一个偏移量,它的值由汇编器计算得出。
BL非常常用。它在跳转之前会在寄存器LR(R14)中保存PC的当前内容。BL的经典用法如下:
bl NEXT ; 跳转到NEXT
……
NEXT
……
mov pc, lr ; 从子程序返回。


二.开始上机移植:(红色字体为添加的内容,蓝色字体为修改的内容,下同)
给自己的开发板取名为qljt2440。
1. 随便找个目录解压u-boot,
$tar –xjvf u-boot-1.3.4.tar.gz2
2. 进入u-boot目录修改Makefile (你要编译u-boot那当然少不了配置啦)
$cd u-boot-1.3.4
[uboot@localhost u-boot-1.3.4]$ vim Makefile 修改内容如下:
__LIBS := $(subst $(obj),,$(LIBS)) $(subst $(obj),,$(LIBBOARD))
改为
__LIBS := $(subst $(obj),,$(LIBBOARD)) $(subst $(obj),,$(LIBS))


sbc2410x_config: unconfig @$(MKCONFIG) $(@:_config=) arm arm920t sbc2410x NULL s3c24x0
qljt2440_config : unconfig @$(MKCONFIG) $(@:_config=) arm arm920t qljt2440 qljt s3c24x0
/*
各项的意思如下:
qljt2440_config : 这个名字是将来你配置板子时候用到的名字,参见make qljt2440_config命令。
arm: CPU的架构(ARCH)
arm920t: CPU的类型(CPU),其对应于cpu/arm920t子目录。
qljt2440: 开发板的型号(BOARD),对应于board/qljt/qljt2440目录。
qljt: 开发者/或经销商(vender)。 s3c24x0: 片上系统(SOC)。
*/
4. 在/board子目录中建立自己的开发板qljt2440目录
由于我在上一步板子的开发者/或经销商(vender)中填了 qljt ,所以开发板qljt2440目录一定要建在/board子目录中的qljt目录下 ,否则编译会出错。
[uboot@localhost u-boot-1.3.4]$ cd board
[uboot@localhost board]$ mkdir qljt qljt/qljt2440
[uboot@localhost board]$ cp -arf sbc2410x/* qljt/qljt2440/
[uboot@localhost board]$ cd qljt/qljt2440/
[uboot@localhost qljt2440]$ mv sbc2410x.c qljt2440.c
[uboot@localhost qljt2440]$ ls 可以看到下面这些文件:
config.mk flash.c lowlevel_init.s Makefile qljt2440.c u-boot.lds
[uboot@localhost qljt2440]$ vim Makefile
COBJS := qljt2440.o flash.o
5. 在 include/configs/ 中建立开发板所需要的配置头文件
[uboot@localhost qljt2440]$ cd ../../..
[uboot@localhost u-boot-1.3.4]$ cp include/configs/sbc2410x.h include/configs/qljt2440.h
6. 测试交叉编译能否成功
(1)配置
[uboot@localhost u-boot-1.3.4]$ make qljt2440_config
Configure for qljt2440 board…
(2)测试编译
[uboot@localhost u-boot-1.3.4]$ make
详细信息如下:
编译信息最后两行:
arm-linux-objcopy --gap-fill=0xff -O srec u-boot u-boot.srec
arm-linux-objcopy --gap-fill=0xff -O binary u-boot u-boot.bin
到此交叉编译成功。


三.开始针对自己的开发板移植
1. 修改/cpu/arm920t/start.S
1.1 修改寄存器地址定义
#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
/* turn off the watchdog */
#if defined(CONFIG_S3C2400)
# define pWTCON 0x15300000
# define INTMSK 0x14400008 /* Interupt-Controller base addresses */
# define CLKDIVN 0x14800014 /* clock divisor register */
#else
# define pWTCON 0x53000000 /*该地址用来屏蔽看门狗*/
# define INTMSK 0x4A000008 /* Interupt-Controller base addresses 该地址用来屏蔽中断*/
# define INTSUBMSK 0x4A00001C /*该地址用来屏蔽子中断*/
# define CLKDIVN 0x4C000014 /* clock divisor register 该地址用来决定FCLK、HCLK、PCLK的比例*/
#define CLK_CTL_BASE 0x4c000000 /* qljt 从S3C2440A.pdf中可以看出该寄存器是存放Mpll和Upll的P254 */
#if defined(CONFIG_S3C2440)
#define MDIV_405 0x7f << 12 /* qljt 参见P255表,同时要知道本开发板的Fin是12MHz,需要的Fclk(也就
是Mpll)是405MHz*/
#define PSDIV_405 0x21 /* qljt 同上,同时设定PDIV和SDIV的值,PDIV和SDIV参见S3C2440A.pdf*/
#endif
#endif
1.2 修改中断禁止部分
# if defined(CONFIG_S3C2410)
ldr r1, =0x7ff //根据2410芯片手册,INTSUBMSK有11位可用,
//vivi也是0x7ff,不知为什么U-Boot一直没改过来。但是由于芯片复位默认
//所有的终端都是被屏蔽的,所以这个不影响工作
ldr r0, =INTSUBMSK
str r1, [r0]
# endif
# if defined(CONFIG_S3C2440)
ldr r1, =0x7fff //根据2440芯片手册,INTSUBMSK有15位可用
ldr r0, =INTSUBMSK
str r1, [r0]
# endif
1.3 修改时钟设置
/*时钟控制逻辑单元能够产生s3c2440需要的时钟信号,包括CPU使用的主频FCLK,AHB总线使用的HCLK,APB总线设备使用的PCLK,2440里面的两个锁相环(PLL),其中一个对应FCLK、HCLK、PCLK,另外一个对应UCLK(48MHz)*/
/*注意:AHP、APB总线的简介参见“AHB与APB总线.doc” */
/* FCLK:HCLK:PCLK = 1:4:8 */
ldr r0, =CLKDIVN
mov r1, #5
str r1, [r0]
/*这三条协处理器命令确实不知道什么意思,在ATXJGYBC_ql.pdf中搜p15和c1,只知道它们执行以后会把协处理器p15的寄存器c1的最高两位置1,但c1的最高两位是没有意义啊,弄不懂它的真正意思
不过我却知道这三条语句是从哪里出来的,详细请参考s3c2440的datasheet和s3c2440datasheet中的R1_nF和R1_iA.doc */
mrc p15, 0, r1, c1, c0, 0 /*read ctrl register qljt*/
orr r1, r1, #0xc0000000 /*Asynchronous qljt 改变总线模式为异步模式网上某位朋友说不知到在哪里看到过
如果FCLK与HCLK不同的话就要选择这种模式的 */
mcr p15, 0, r1, c1, c0, 0 /*write ctrl register qljt*/


#if defined(CONFIG_S3C2440) // (2440的主频可达533MHz,但听说设到533MHz时系统
//很不稳定,不知是不是SDRAM和总线配置的影响,所以现在先设到//405MHz,以后在改进。)
/*now, CPU clock is 405.00 Mhz qljt*/
mov r1, #CLK_CTL_BASE /* qljt*/
mov r2, #MDIV_405 /* mpll_405mhz qljt*/
add r2, r2, #PSDIV_405 /* mpll_405mhz qljt*/
str r2, [r1, #0x04] /* MPLLCON qljt实际上是设置寄存器CLK_CTL_BASE+0x04=0x4c000004的值 */
#endif
#endif /* CONFIG_S3C2400 || CONFIG_S3C2410|| CONFIG_S3C2440 */

1.4 将从Flash启动改成从NAND Flash启动。(特别注意:这和2410的程序有不同,不可混用!!!是拷贝vivi的代码。)
将以下U-Boot的重定向语句段:
@#if ndef CONFIG_AT91RM9200
#if 0
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
relocate: /* relocate U-Boot to RAM */
adr r0, _start /* r0 <- current position of code */
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
cmp r0, r1 /* don't reloc during debug */
beq stack_setup


ldr r2, _armboot_start
ldr r3, _bss_start
sub r2, r3, r2 /* r2 <- size of armboot */
add r2, r0, r2 /* r2 <- source end address */


copy_loop:
ldmia r0!, {r3-r10} /* copy from source address [r0] */
stmia r1!, {r3-r10} /* copy to target address [r1] */
cmp r0, r2 /* until source end addreee [r2] */
ble copy_loop
#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
#endif /*CONFIG_AT91RM9200 */
然后添加:
/*下载了一个vivi源代码看了一下,还真的有下面哪一段代码*/
#ifdef CONFIG_S3C2440_NAND_BOOT @qljt@@@@@@@@@@@@@@@@SSSSSSSSSSSSS
@ reset NAND
/*往下四段内容都是针对S3C2440的关于NAND-FLASH的寄存器的设置,具体有什么作用,看了datasheet,有些明白有些不明白*/
mov r1, #NAND_CTL_BASE
ldr r2, =( (7<<12)|(7<<8)|(7<<4)|(0<<0) )
str r2, [r1, #oNFCONF] /*这些宏是在include/configs/qljt2440.h中被定义的*/
ldr r2, [r1, #oNFCONF] /*还是弄不懂为什么上面一句str以后还要有这句的ldr命令?why?难道是多余的?*/


ldr r2, =( (1<<4)|(0<<1)|(1<<0) ) @ Active low CE Control
str r2, [r1, #oNFCONT]
ldr r2, [r1, #oNFCONT]


ldr r2, =(0x6) @ RnB Clear
str r2, [r1, #oNFSTAT]
ldr r2, [r1, #oNFSTAT]


mov r2, #0xff @ RESET command
strb r2, [r1, #oNFCMD]
/*delay一段时间*/
mov r3, #0 @ wait
nand1:
add r3, r3, #0x1
cmp r3, #0xa
blt nand1
/*等待nand-flash的复位完毕信号*/
nand2:
ldr r2, [r1, #oNFSTAT] @ wait ready
tst r2, #0x4
beq nand2


ldr r2, [r1, #oNFCONT]
orr r2, r2, #0x2 @ Flash Memory Chip Disable /*在这里先Display fansh CE先,在C函数中对falsh进行*/
str r2, [r1, #oNFCONT] /*操作的时候才enable,为什么这样操作不太清楚*/
/*下面这段用来初始化栈指针sp和帧指针fp,至于它们的定义和作用参考文件夹” 栈指针sp和帧指针fp”里面的内容
记住它们都是与函数调用时候相关的。简单来讲就是子函数被调用以后是通过指针的相对位置来查找调用参数和局部变量的,但是由于sp经常变化,所以需要fp来协助。*/
@ get ready to call C functions (for nand_read())
ldr sp, DW_STACK_START @ setup stack pointer /*sp 是指堆栈指针*/
mov fp, #0 @ no previous frame, so fp=0
@ copy U-Boot to RAM /*vivi里面应该是有一段是针对gpio的程序,也许使用来debug用的信号灯,这里省略了*/
/* TEXT_BASE 是uboot自己的入口地址,在u-boot-1.3.4-board/qljt/qljt2440的config.mk中定义
有趣的是外国人的逆向思维很厉害,它们很灵活地把它放在SDRAM的最后0x80000地方,也就是0x33F80000
*/
ldr r0, =TEXT_BASE /*r0 : 把u-boot复制到ram的那个位置*/
mov r1, #0x0 /*r1 : 从falsh的那个位置开始复制*/
mov r2, #0x20000 /*r2 : 复制多大的内容*/
bl nand_read_ll /*跳到执行uboot复制的程序入口,这个函数从哪里来?也是来自vivi的,没办法*/
tst r0, #0x0 /*这里特别注意r0的值是指nand_read_ll 执行完以后的返回值,而不是上面
ldr r0, =TEXT_BASE 的值,初学者往往在这里想不通*/
beq ok_nand_read
bad_nand_read: /*如果读nand_read失败的话,那么sorry,重来,或者检查硬件*/
loop2: b loop2 @ infinite loop
ok_nand_read:
@ verify
/*计算机就是好,很容易就可以检测我们放在SDRAM中的u-boot是不是flash中的uboot。
本开发板使用的是nand-falsh的启动方式,板子一上电并不是马上进入SDRAM执行程序的。是这样的:板子一上电,S3C2440自动把nand-falsh中从0地址开始的4Kbytes复制到S3C2440集成的某个缓冲区里面(起始地址是0x00),从那里开始执行,那4K程序负责把整个uboot复制到SDRAM,然后才跳到SDRAM开始正真的UBOOT(这个技术是有个专业名字的我忘记了),*/
/*下面这段程序的作用就是用开始执行的4Kbytes程序跟我们复制到SDRAM中的uboot的前4K程序进行比较,从而校验*/
mov r0, #0
ldr r1, =TEXT_BASE
mov r2, #0x400 @ 4 bytes * 1024 = 4K-bytes
go_next:
ldr r3, [r0], #4
ldr r4, [r1], #4
teq r3, r4
bne notmatch
subs r2, r2, #4
beq stack_setup
bne go_next


notmatch:
loop3: b loop3 @ infinite loop
#endif @ CONFIG_S3C2440_NAND_BOOT @qljt@@@@@@@@@@@@@@@@@@EEEEEEEEE


1.5 在跳到C函数执行前,也就是跳出start.S前,添加几个LED灯的控制,说明程序跑到这里了,移植的第一阶段完成了。
/*本开发板上面有四个LED灯,分别接到CPU 的GPIO_F[4:7]这四个引脚上*/
#if defined(CONFIG_S3C2440)
@ LED1 on u-boot stage 1 is ok!
mov r1, #GPIO_CTL_BASE
add r1, r1, #oGPIO_F
ldr r2,=0x5500
str r2, [r1, #oGPIO_CON]
mov r2, #0xff
str r2, [r1, #oGPIO_UP]
mov r2, #0xdf
str r2, [r1, #oGPIO_DAT]
#endif
1.6 在 “ _start_armboot: .word start_armboot ” 后加入:
#if defined(CONFIG_S3C2440_NAND_BOOT)
.align 2 /*???这里我一直不明白为什么是 .align 2,因为如果按照ARM的规则,意思是按照 2的2次方=4bit的
方式对齐,那么就是半个字节对齐,有可能吗?*/
DW_STACK_START: .word STACK_BASE+STACK_SIZE-4 /*从这里可以看出该堆栈是从高地址向低地址增长的
注意这里的STACK_BASE和STACK_SIZE还没定义,在1.1节中定义*/
#endif
2. 修改include/configs/qljt2440.h文件,在结尾处添加如下内容(注意:s3c2410与s3c2440的Nand Flash控制器寄存器不同,不能混用!!):
......
/*
* Nandflash Boot
*/
#define CONFIG_S3C2440_NAND_BOOT 1
#define STACK_BASE 0x33f00000
#define STACK_SIZE 0x8000
/* NAND Flash Controller */
#define NAND_CTL_BASE 0x4E000000
/* Offset */
#define oNFCONF 0x00 /*这些宏是在start.S中被调用的*/
#define oNFCONT 0x04
#define oNFCMD 0x08
#define oNFADDR 0x0c
#define oNFDATA 0x10
#define oNFSTAT 0x20
#define oNFECC 0x2c
/* GPIO */
#define GPIO_CTL_BASE 0x56000000
#define oGPIO_F 0x50
#define oGPIO_CON 0x0 /* R/W, Configures the pins of the port */
#define oGPIO_DAT 0x4 /* R/W, Data register for port */
#define oGPIO_UP 0x8 /* R/W, Pull-up disable register */
#endif /* __CONFIG_H */


3. 在board/qljt/qljt2440加入NAND Flash读函数文件,拷贝vivi中的nand_read.c文件到此文件夹即可,基本上大陆上移植的都是这样做的,在此把该文件的内容贴出来,目的是对一些难理解的代码进行解析:
#include


#define __REGb(x) (*(volatile unsigned char *)(x))
#define __REGi(x) (*(volatile unsigned int *)(x))
#define NF_BASE 0x4e000000


#define NFCONF __REGi(NF_BASE + 0x0)
#define NFCONT __REGi(NF_BASE + 0x4)
#define NFCMD __REGb(NF_BASE + 0x8)
#define NFADDR __REGb(NF_BASE + 0xC)
#define NFDATA __REGb(NF_BASE + 0x10)
#define NFSTAT __REGb(NF_BASE + 0x20)


//#define GPDAT __REGi(GPIO_CTL_BASE+oGPIO_F+oGPIO_DAT)


#define NAND_CHIP_ENABLE (NFCONT &= ~(1<<1))
#define NAND_CHIP_DISABLE (NFCONT |= (1<<1))
#define NAND_CLEAR_RB (NFSTAT |= (1<<2))
#define NAND_DETECT_RB { while(! (NFSTAT&(1<<2)) );}


#define BUSY 4
inline void wait_idle(void) {
while(!(NFSTAT & BUSY));
NFSTAT |= BUSY;
}


#define NAND_SECTOR_SIZE 512
#define NAND_BLOCK_MASK (NAND_SECTOR_SIZE - 1)


/* low level nand read function */
/*下面nand_read_ll 的三个参数来自start.S里面调用nand_read_ll 前的r0、r1、r2*/
int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)
{
int i, j;
/*下面这个if保证对flash的读操作是从某一页的页头开始的,从直观来看是保证start_addr[0:8]位都为0,
为什么呢?因为本flash的一页的大小位512-bytes,也就是从0x0到0x1ff*/
if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) {
return -1; /* invalid alignment */
}


NAND_CHIP_ENABLE;


for(i=start_addr; i < (start_addr + size);) {
/* READ0 */
NAND_CLEAR_RB;
/*到此应该可以明白s3c2440 nandflash 相关寄存器的确切含义了,就是说s3c2440里面已经集成了对nand flash操
作的相关寄存器,只要你的nand flash接线符合s3c2440 datasheet的接法,就可以随便使用s3c2440 对于nand
flash的相关寄存器,例如如果你想像nand flash写一个命令,那么只要对命令寄存器写入你的命令就可以了,s3c2440 可以自动帮你完成所有的时序动作,写地址也是一样。反过来说如果没有了对nand flash的支持,那么我们对nand falsh的操作就会增加好多对I/O口的控制,例如对CLE,ALE的控制。s3c2440已经帮我们完成了这部分工作了*/
NFCMD = 0;

[1] [2]
关键字:u-boot-1  移植  S3C2440 引用地址:u-boot-1.3.4 移植到S3C2440

上一篇:S3C2440中断过程详解(ADS,TQ2440)
下一篇:最后一页

推荐阅读

2018年双十一购物狂欢节尽管已经收官,但商品的配送仍然热火朝天,为了让剁手党们尽早拿到快递,快递员真的很辛苦,“双十一派件高峰,小哥熬夜抢快递柜”,“快递员三天两夜睡了不到8小时的觉”,这一类的新闻层出不穷。 最后一公里的快递配送难题如何解决,是各大物流最大痛点。人口红利消失,人力成本飙升的当下,单纯的靠招聘快递员已经不能满足配...
在HDMI2.1源端测试中,示波器模拟了sink的行为,提供了端接电阻和端接电压。EDID 仿真器模拟sink的EDID,提供分辨率/速率信息,HDMI2.0 的EDID仿真器也提供SCDC信息, 完成与source的沟通,使source输出需要TMDS信号。测试项目分为单端信号测试和差分信号测试,对应的连接方式分别为单端连接和差分连接,用于采集单端信号和差分信号,以便完成相应的测试...
韩国LED制造商首尔半导体表示,德国杜塞尔多夫地方法院已经对飞利浦品牌的某些手机和照明产品发布了两项永久禁令。法院下令对Signify(原飞利浦照明)的子公司Klite lighting生产的照明产品发出永久禁令,并在最近针对Klite的其他诉讼中对Leuchtstark Vertriebs GmbH提起的专利诉讼中,召回2017年3月后销售的照明产品。此前,在美国还有两起案件,首尔...
如今,随着元宇宙概念的新起,再加上全球各大厂商纷纷在元宇宙领域加码加注,导致现在的元宇宙概念越来越火,而要想进入元宇宙世界,3D机器视觉技术可谓是最佳“入口”。不仅如此,3D机器视觉技术目前正在逐步渗透至人们生活的方方面面。比如医疗、农牧业、工业、智能机器人等行业中,3D机器视觉技术也起到了至关重要的作用。近年来,3D视觉技术正在飞速发...

史海拾趣

问答坊 | AI 解惑

Connectors and Connector Care

Objectives?Fundamentals of Connectors?Commonly Used Connectors?Typical Connector Cross-Section?Principles of Connector Care?Visual Inspection?Mechanical Inspection?Connector Specifications…

查看全部问答∨

485 现场总线施工的实际问题和解决办法(2)

2、终端电阻法:在最后一台485设备的485+和485-上并接120欧姆的终端电阻来改善通讯质量。 3、中间分段断开法:通过从中间断开来检查是否设备负载过多、通讯距离过长、某台设备对整个通讯线路的影响等。 4、单独拉线法:单独简易拉一条 ...…

查看全部问答∨

51单片机外部中断例程

我所收藏的好东西《51单片机外部中断例程 》。给大家提供一点方便。…

查看全部问答∨

Tcl 教程

Tcl 教程 在FPGA中,有用…

查看全部问答∨

请教各位PXA270的主频在哪里设置?

请教各位PXA270的主频 在 WINCE下的BSP哪里设置?…

查看全部问答∨

EM310模块 来电接收问题

在定时上传GPRS数据的情况下,当时间间隔小于10S时,向模块打电话就会出现问题,连RING都接收不到。打电话提示都是:“对不起,您所拨打的电话暂时无法接通,请稍后再拨~~”。但是上传时间间隔比较大时,就没有问题,找不到好的解决方法,请大家帮 ...…

查看全部问答∨

WinCE5.0 下面用 DirectShow 开发的播放器,播放视频时总是新开一个窗口并且自动最小化

我先创建了一个IGraphBuilder接口,查询IVideoWindow,然后render一个文件,把IVideoWindow的owner设为一个dialog,把它的风格设为"WS_CHILD| WS_CLIPSIBLINGS",然后开始播放。 但是实际的结果是:视频播放的窗口不是我指定的dialog的子窗口 ...…

查看全部问答∨

【求助】怎么将路由协议嵌入到CE的协议栈

rt 请各位前辈向晚辈提供一个 将路由协议嵌入CE的解决方案。 晚辈刚刚接到这样一项工作。从来没有接触过。 想问一下各位前辈,需要学那些东西,做什么准备。 实现的 整个流程大体 上是什么。。。 麻烦给 介绍以下。。。 先谢谢各位前辈了。 ...…

查看全部问答∨

做手写板软件。。。

请问有人做过手写板软件吗? 我想做个手写板的软件,通过手写板输入,最好可以检测压力,如果买市面上的手写板,好像很难通过这些成品做出软件来。 请问有有过同样想法的人吗?我要买什么好呢? 请各位指教~~…

查看全部问答∨

FPGA频率影响问题

请问各位达人:     我要是用DSP将数据写到FPGA中,就对FPGA输入的20M信号就有影响,即20M信号就不稳定了。要是不用DSP将数据写到FPGA中,就不对FPGA输入的20M信号就有影响。不知这是什么原因,不知有人以前遇到过这种现象吗?怎样解决 ...…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
  • ARM裸机篇--按键中断
    先看看GPOI的输入实验:按键电路图:GPF1管教的功能:EINT1要使用GPF1作为EINT1的功能时,只要将GPFCON的3:2位配置成10就可以了!GPF1先配 ...
  • 网上下的--ARM入门笔记
    简单的介绍打今天起菜鸟的ARM笔记算是开张了,也算给我的这些笔记找个存的地方。为什么要发布出来?也许是大家感兴趣的,其实这些笔记之所 ...
  • 学习ARM开发(23)
    三个任务准备与运行结果下来看看创建任务和任运的栈空间怎么样的,以及运行输出。Made in china by UCSDN(caijunsheng)Lichee 1 0 0 ...
  • 学习ARM开发(22)
    关闭中断与打开中断中断是一种高效的对话机制,但有时并不想程序运行的过程中中断运行,比如正在打印东西,但程序突然中断了,又让另外一个 ...
  • 学习ARM开发(21)
    先要声明任务指针,因为后面需要使用。 任务指针 volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • 学习ARM开发(20)
  • 学习ARM开发(19)
  • 学习ARM开发(14)
  • 学习ARM开发(15)
何立民专栏 单片机及嵌入式宝典

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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