- board target board related files, mainly including SDRAM and FLASH drivers;
- common Common code that is independent of the processor architecture, such as memory size detection and fault detection;
- cpu is files related to the processor. For example, the mpc8xx subdirectory contains files such as serial port, network port, LCD driver and interrupt initialization;
- driver General device driver, such as CFI FLASH driver (currently supports INTEL FLASH better)
-doc U-Boot documentation;
- examples are sample programs that can be run under U-Boot; such as hello_world.c, timer.c;
- include U-Boot header files; especially the configuration header files related to the target board in the configs subdirectory are files that are often modified during the porting process;
- lib_xxx processor architecture related files, such as lib_ppc, lib_arm directories contain files related to PowerPC and ARM architectures respectively;
- net is the file directory related to network functions, such as bootp, nfs, tftp;
- post Power-on self-test file directory. Still needs to be further improved;
- rtc RTC driver;
- tools Tools for creating U-Boot S-RECORD and BIN image files;
1. Create your own development board file
1. Create your own board directory in the borad folder, copy the files in sbc2410x to this directory as a blueprint to speed up the transplantation process, and modify the makefile file COBJS := tq2440.o flash.o in the board directory (the generation of tq2440.o file must modify the sbc2410x.c file in this directory)
2. Create tq2440.h file in include/configs folder based on sbc2410x.h
3. Modify the makefile file in the uboot root directory, confirm CROSS_COMPLE, the compiler option, and add the make option:
tq2440_config:unconfig
(TAB)@./mkconfig $(@:_config=) arm arm920t tq2440 NULL s3c24x0
in:
arm: CPU architecture (ARCH)
arm920t: CPU type (CPU), which corresponds to the cpu/arm920t subdirectory.
tq2440: development board model (BOARD), corresponding to the board/tq2440 directory.
NULL: developer and/or vender.
s3c24x0: System on chip (SOC).
4. Next, test whether the compilation can pass, execute: make disclean--delete the original compilation result
make tqconfig
After success, Configuring for xxx board..... appears
make – can generate uboot.bin file
2. Modify the source code
1. Modify start.S
Modify the following code:
#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
ldr r0, =pWTCON
mov r1, #0x0
str r1, [r0]
mov r1, #0xffffffff
ldr r0, =INTMSK
str r1, [r0]
# if defined(CONFIG_S3C2410)
ldr r1, =0x3ff
ldr r0, =INTSUBMSK
str r1, [r0]
# endif
#ifdefined(CONFIG_S3C2440)
ldr r1, =0x7fff
ldr r0, =INTSUBMSK
str r1, [r0]
# endif
#if0
ldr r0, =CLKDIVN
mov r1, #3
str r1, [r0]
#endif
#endif
#ifndefCONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_crit
#endif
// Bring the stack initialization to the front, because the clock initialization function to be written later will use the stack
stack_setup:
ldr r0, _TEXT_BASE
sub r0, r0, #CFG_MALLOC_LEN
sub r0, r0, #CFG_GBL_DATA_SIZE
#ifdefCONFIG_USE_IRQ
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
sub sp, r0, #12
// Jump to the clock initialization function
bl clock_init
#ifndefCONFIG_SKIP_RELOCATE_UBOOT
relocate:
adr r0, _start
ldr r1, _TEXT_BASE
cmp r0, r1
beq stack_setup
ldr r2, _armboot_start
ldr r3, _bss_start
sub r2, r3, r2
//Shield the original code and rewrite the code transfer function
#if1
bl CopyCode2Ram
#else
add r2, r0, r2
copy_loop:
ldmia r0!, {r3-r10}
stmia r1!, {r3-r10}
cmp r0, r2
ble copy_loop
#endif
#endif
Then add in include/configs/tq2440.h
#define CONFIG_S3C2440 1
#define CONFIG_TQ2440 1
And shield the original chip and development board definitions, at the same time, the S3C24X0_GPIO structure in s3c24x0.h should also be rewritten to support 2440, and add
S3C24X0_REG32 res9[4];
S3C24X0_REG32 GPJCON;
S3C24X0_REG32 GPJDAT;
S3C24X0_REG32 GPJUP;
This is the definition of GPIO_J port
Add typedef struct {
S3C24X0_REG32 NFCONF;
S3C24X0_REG32 NFCONT;
S3C24X0_REG32 NFCMD;
S3C24X0_REG32 NFADDR;
S3C24X0_REG32 NFDATA;
S3C24X0_REG32 NFMECCD0;
S3C24X0_REG32 NFMECCD1;
S3C24X0_REG32 NFSECCD;
S3C24X0_REG32 NFSTAT;
S3C24X0_REG32 NFESTAT0;
S3C24X0_REG32 NFESTAT1;
S3C24X0_REG32 NFMECC0;
S3C24X0_REG32 NFMECC1;
S3C24X0_REG32 NFSECC;
S3C24X0_REG32 NFSBLK;
S3C24X0_REG32 NFEBLK;
} S3C2440_NAND;
Other structures should also be modified
Modify lowlevel_init.S, modify lines 54, 58, and 126, that is, the external memory controller.
54 #defineB1_BWSCON (DW16)
58 #defineB5_BWSCON (DW8)
126 #defineREFCNT 0x4f4
lowlevel_init.S mainly sets SDRAM configuration
ARM memory controller
Every 4 bits in the bit width and wait control register BWSCON controls a BANK, the highest 4 bits correspond to BANK7, the next 4 bits correspond to BANK6, and so on.
8 memory banks
6 are ROM, SRAM and other types of memory banks
2 can be used as ROM, SRAM, SDRAM and other memory banks
BANK control registers BANKCONx (BANKCON1~5) are used to control the access timing of BANK0~BANK5 external devices. Generally, the default value 0x0700 is sufficient.
BANK control register BANKCONx (BANKCON6~7, among the 8 BANKs, only BANK6 and BANK7 can be connected to SRAM and SDRAM, so BANKCON6~BANKCON7 are a little different from BANKCON0~BANKCON5.
Add the boot_init.c file in the board folder and modify the makefile (the boot_init.c file mainly contains nand reading and writing, clock initialization, and code copying functions)
boot_init.c
#include
#include
#defineGSTATUS1 (*(volatileunsignedint*)0x560000B0)
#defineBUSY 1
#defineNAND_SECTOR_SIZE 512
#defineNAND_BLOCK_MASK (NAND_SECTOR_SIZE - 1)
#defineNAND_SECTOR_SIZE_LP 2048
#defineNAND_BLOCK_MASK_LP (NAND_SECTOR_SIZE_LP - 1)
charbLARGEBLOCK; //HJ_add 20090807
charb128MB; //HJ_add 20090807
voidnand_init_ll(void);
intnand_read_ll(unsignedchar*buf, unsignedlongstart_addr, intsize);
intnand_read_ll_lp(unsignedchar*buf, unsignedlongstart_addr, intsize);
staticvoidnand_reset(void);
staticvoidwait_idle(void);
staticvoidnand_select_chip(void);
staticvoidnand_deselect_chip(void);
staticvoidwrite_cmd(intcmd);
staticvoidwrite_addr(unsignedintaddr);
staticvoidwrite_addr_lp(unsignedintaddr);
staticunsignedcharread_data(void);
intNF_ReadID(void); //HJ_add 20090807
[page]
staticvoids3c2440_nand_reset(void);
staticvoids3c2440_wait_idle(void);
staticvoids3c2440_nand_select_chip(void);
staticvoids3c2440_nand_deselect_chip(void);
staticvoids3c2440_write_cmd(intcmd);
staticvoids3c2440_write_addr(unsignedintaddr);
staticvoids3c2440_write_addr_lp(unsignedintaddr);
staticunsignedchars3c2440_read_data(void);
staticvoids3c2440_nand_reset(void)
{
s3c2440_nand_select_chip();
s3c2440_write_cmd(0xff); // reset command
s3c2440_wait_idle();
s3c2440_nand_deselect_chip();
}
staticvoids3c2440_wait_idle(void)
{
you;
S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;
volatileunsignedchar*p = (volatileunsignedchar*)&s3c2440nand->NFSTAT;
while(!(*p & BUSY))
for(i=0; i<10; i++);
}
staticvoids3c2440_nand_select_chip(void)
{
you;
S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;
s3c2440nand->NFCONT&= ~(1<<1);
for(i=0; i<10; i++);
}
staticvoids3c2440_nand_deselect_chip(void)
{
S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;
s3c2440nand->NFCONT|= (1<<1);
}
staticvoids3c2440_write_cmd(intcmd)
{
S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;
volatileunsignedchar*p = (volatileunsignedchar*)&s3c2440nand->NFCMD;
*p = cmd;
}
staticvoids3c2440_write_addr(unsignedintaddr)
{
you;
S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;
volatileunsignedchar*p = (volatileunsignedchar*)&s3c2440nand->NFADDR;
*p = addr & 0xff;
for(i=0; i<10; i++);
*p = (addr >> 9) & 0xff;
for(i=0; i<10; i++);
*p = (addr >> 17) & 0xff;
for(i=0; i<10; i++);
*p = (addr >> 25) & 0xff;
for(i=0; i<10; i++);
}
staticvoids3c2440_write_addr_lp(unsignedintaddr)
{
you;
S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;
volatileunsignedchar*p = (volatileunsignedchar*)&s3c2440nand->NFADDR;
intcol, page;
col = addr & NAND_BLOCK_MASK_LP;
page = addr / NAND_SECTOR_SIZE_LP;
*p = col & 0xff;
for(i=0; i<10; i++);
*p = (col >> 8) & 0x0f;
for(i=0; i<10; i++);
*p = page & 0xff;
for(i=0; i<10; i++);
*p = (page >> 8) & 0xff;
for(i=0; i<10; i++);
if(b128MB == 0)
*p = (page >> 16) & 0x03;
for(i=0; i<10; i++);
}
staticunsignedchars3c2440_read_data(void)
{
S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;
volatileunsignedchar*p = (volatileunsignedchar*)&s3c2440nand->NFDATA;
return*p;
}
staticvoidnand_reset(void)
{
s3c2440_nand_reset();
}
staticvoidwait_idle(void)
{
s3c2440_wait_idle();
}
staticvoidnand_select_chip(void)
{
you;
s3c2440_nand_select_chip();
for(i=0; i<10; i++);
}
staticvoidnand_deselect_chip(void)
{
s3c2440_nand_deselect_chip();
}
staticvoidwrite_cmd(intcmd)
{
s3c2440_write_cmd(cmd);
}
staticvoidwrite_addr(unsignedintaddr)
{
s3c2440_write_addr(addr);
}
staticvoidwrite_addr_lp(unsignedintaddr)
{
s3c2440_write_addr_lp(addr);
}
staticunsignedcharread_data(void)
{
returns3c2440_read_data();
}
voidnand_init_ll(void)
{
S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;
#defineTACLS 0
#defineTWRPH0 3
#defineTWRPH1 0
//Set timing
s3c2440nand->NFCONF= (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);
// Enable NAND Flash controller, initialize ECC, disable chip select
s3c2440nand->NFCONT= (1<<4)|(1<<1)|(1<<0);
// Reset NAND Flash
nand_reset();
}
#if1
intNF_ReadID(void)
{
charpMID;
charpDID;
int nBuff;
char n4thcycle;
you;
S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;
volatileunsignedchar*p = (volatileunsignedchar*)&s3c2440nand->NFADDR;
b128MB = 1;
n4thcycle = nBuff = 0;
nand_init_ll();
nand_select_chip();
write_cmd(0x90); // read id command
*p=0x00 & 0xff;
for( i = 0; i < 100; i++ );
pMID = read_data();
pDID = read_data();
nBuff = read_data();
n4thcycle = read_data();
nand_deselect_chip();
if(pDID >= 0xA0)
{
b128MB = 0;
}
return(pDID);
}
#endif
intnand_read_ll(unsignedchar*buf, unsignedlongstart_addr, intsize)
{
you, j;
chard;
S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;
volatileunsignedchar*p = (volatileunsignedchar*)&s3c2440nand->NFADDR;
if((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK))
{
return-1;
}
nand_select_chip();
for(i=start_addr; i < (start_addr + size);)
{
if(1){
write_cmd(0x50);
*p = 5;
for(j=0; j<10; j++);
*p = (i >> 9) & 0xff;
for(j=0; j<10; j++);
*p = (i >> 17) & 0xff;
for(j=0; j<10; j++);
*p = (i >> 25) & 0xff;
for(j=0; j<10; j++);
wait_idle();
dat = read_data();
write_cmd(0);
nand_deselect_chip();
if(that != 0xff)
{
i += 16384; // 1 Block = 512*32= 16384
printf("Bad block at 0x%lx,will be skipped1n",i);
}
nand_select_chip();
}
write_cmd(0);
write_addr(i);
wait_idle();
for(j=0; j < NAND_SECTOR_SIZE; j++, i++)
{
*buf = read_data();
buf++;
}
}
nand_deselect_chip();
return0;
}
intnand_read_ll_lp(unsignedchar*buf, unsignedlongstart_addr, intsize)
{
you, j;
chard;
S3C2440_NAND* s3c2440nand = (S3C2440_NAND*)0x4e000000;
volatileunsignedchar*p = (volatileunsignedchar*)&s3c2440nand->NFADDR;
if((start_addr & NAND_BLOCK_MASK_LP) || (size & NAND_BLOCK_MASK_LP))
{
return-1;
}
nand_select_chip();
for(i=start_addr; i < (start_addr + size);)
{
if(1){
intcol, page;
col = i & NAND_BLOCK_MASK_LP;
page = i / NAND_SECTOR_SIZE_LP;
write_cmd(0x00);
*p = 5;
for(j=0; j<10; j++);
*p = 8;
for(j=0; j<10; j++);
*p = page & 0xff;
for(j=0; j<10; j++);
*p = (page >> 8) & 0xff;
for(j=0; j<10; j++);
if(b128MB == 0)
*p = (page >> 16) & 0x03;
for(j=0; j<10; j++);
write_cmd(0x30);
wait_idle();
dat = read_data();
nand_deselect_chip();
if(that != 0xff)
{
i += 131072; // 1 Block = 2048*64= 131072
}
nand_select_chip();
}
write_cmd(0);
write_addr_lp(i);
write_cmd(0x30);
wait_idle();
for(j=0; j < NAND_SECTOR_SIZE_LP; j++, i++)
{
*buf = read_data();
buf++;
}
}
nand_deselect_chip();
return0;
}
intbBootFrmNORFlash(void)
{
volatileunsignedint*pdw = (volatileunsignedint*)0;
unsignedintdwVal;
dwVal = *pdw;
*pdw = 0x12345678;
if(*pdw != 0x12345678)
{
return1;
}
else
{
*pdw = dwVal;
return0;
}
}
intCopyCode2Ram(unsignedlongstart_addr, unsignedchar*buf, intsize)
{
unsignedint*pdwDest;
unsignedint*pdwSrc;
you;
long*GPBCON=0x56000010;
long*GPBDAT=0x56000014;
long*GPBUP =0x56000018;
*GPBCON=0x295551;
*GPBUP=0xff;
*GPBDAT=0x7be;
[page]
if(bBootFrmNORFlash())
{
pdwDest = (unsignedint*)buf;
pdwSrc = (unsignedint*)start_addr;
for(i = 0; i < size / 4; i++)
{
pdwDest[i] = pdwSrc[i];
}
return0;
}
else
{
nand_init_ll();
if(NF_ReadID() == 0x76 )
{
nand_read_ll(buf, start_addr, (size + NAND_BLOCK_MASK)&~(NAND_BLOCK_MASK));}
else
{
nand_read_ll_lp(buf, start_addr, (size + NAND_BLOCK_MASK_LP)&~(NAND_BLOCK_MASK_LP));}
return0;
}
}
staticinlinevoiddelay(unsignedlongloops)
{
__asm__volatile("1:n"
"subs %0, %1, #1n"
"bne1b":"=r"(loops):"0"(loops));
}
#defineS3C2440_MPLL_400MHZ ((0x5c<<12)|(0x01<<4)|(0x01)) //HJ 400MHz
#defineS3C2440_MPLL_405MHZ ((0x7f<<12)|(0x02<<4)|(0x01)) //HJ 405MHz
#defineS3C2440_MPLL_440MHZ ((0x66<<12)|(0x01<<4)|(0x01)) //HJ 440MHz
#defineS3C2440_MPLL_480MHZ ((0x98<<12)|(0x02<<4)|(0x01)) //HJ 480MHz
#defineS3C2440_MPLL_200MHZ ((0x5c<<12)|(0x01<<4)|(0x02))
#defineS3C2440_MPLL_100MHZ ((0x5c<<12)|(0x01<<4)|(0x03))
#defineS3C2440_UPLL_48MHZ ((0x38<<12)|(0x02<<4)|(0x02)) //HJ 100MHz
#defineS3C2440_CLKDIV 0x05 //HJ 100MHz
#defineS3C2440_CLKDIV136 0x07 //HJ 133MHz
#defineS3C2440_CLKDIV188 0x04
#defineS3C2440_CAMDIVN188 ((0<<8)|(1<<9))
#defineS3C2440_MPLL_399MHz ((0x6e<<12)|(0x03<<4)|(0x01))
#defineS3C2440_UPLL_48MHZ_Fin16MHz ((60<<12)|(4<<4)|(2))
voidclock_init(void)
{
S3C24X0_CLOCK_POWER*clk_power = (S3C24X0_CLOCK_POWER*)0x4C000000;
#ifCONFIG_133MHZ_SDRAM
clk_power->CLKDIVN = S3C2440_CLKDIV136; //HJ 1:3:6
#else
clk_power->CLKDIVN= S3C2440_CLKDIV; //HJ 1:4:8
#endif
__asm__( "mrc p15, 0, r1, c1, c0, 0n"
"orr r1, r1, #0xc0000000n"
"mcr p15, 0, r1, c1, c0, 0n"
:::"r1"
);
clk_power->LOCKTIME= 0xFFFFFF;
clk_power->UPLLCON= S3C2440_UPLL_48MHZ; //fin=12.000MHz
// clk_power->UPLLCON = S3C2440_UPLL_48MHZ_Fin16MHz; //fin=16.934MHz
delay (4000);
clk_power->MPLLCON= S3C2440_MPLL_400MHZ; //fin=12.000MHz
// clk_power->MPLLCON = S3C2440_MPLL_405MHZ; //HJ 405MHz
// clk_power->MPLLCON = S3C2440_MPLL_440MHZ; //HJ 440MHz
// clk_power->MPLLCON = S3C2440_MPLL_480MHZ; //HJ 480MHz
// clk_power->MPLLCON = S3C2440_MPLL_399MHz; //fin=16.934MHz
delay (8000);
}
Modify the get_HCLK and other functions in cpu/arm920t/s3c24x0/speed.c. First, add DECLARE_GLOBAL_DATA_PTR in front; so that it can use the pointer of the gd_t global data structure
Relationship between FLCK, HCLK and PCLK
S3C2440 has three clocks: FLCK, HCLK and PCLK
FCLK is used by ARM920T, core clock, main frequency.
HCLK is used for AHB bus, which is used by the ARM920T, the memory controller, the interrupt controller, the LCD controller, the DMA and USB host block. That is, the bus clock, including the USB clock.
PCLK is used for APB bus, which is used by the peripherals such as WDT, IIS, I2C, PWM timer, MMC interface, ADC, UART, GPIO, RTC and SPI. That is, the IO interface clock, for example, the serial port clock setting comes from PCLK;
Specific code:
staticulongget_PLLCLK(intpllreg)
{
S3C24X0_CLOCK_POWER* constclk_power = S3C24X0_GetBase_CLOCK_POWER();
ulongr, m, p, s;
if(pllreg == MPLL)
r = clk_power->MPLLCON;
elseif(pllreg == UPLL)
r = clk_power->UPLLCON;
else
hang();
m = ((r & 0xFF000) >> 12) + 8;
p = ((r & 0x003F0) >> 4) + 2;
s = r & 0x3;
if(gd->bd->bi_arch_number== MACH_TYPE_SMDK2410)
return((CONFIG_SYS_CLK_FREQ * m) / (p << s));
else
return((CONFIG_SYS_CLK_FREQ * m *2) / (p << s));
}
ulongget_FCLK(void)
{
return(get_PLLCLK(MPLL));
}
#defineS3C2440_CLKDIVN_PDIVN (1<<0)
#defineS3C2440_CLKDIVN_HDIVN_MASK (3<<1)
#defineS3C2440_CLKDIVN_HDIVN_1 (0<<1)
#defineS3C2440_CLKDIVN_HDIVN_2 (1<<1)
#defineS3C2440_CLKDIVN_HDIVN_4_8 (2<<1)
#defineS3C2440_CLKDIVN_HDIVN_3_6 (3<<1)
#defineS3C2440_CLKDIVN_UCLK (1<<3)
#defineS3C2440_CAMDIVN_CAMCLK_MASK (0xf<<0)
#defineS3C2440_CAMDIVN_CAMCLK_SEL (1<<4)
#defineS3C2440_CAMDIVN_HCLK3_HALF (1<<8)
#defineS3C2440_CAMDIVN_HCLK4_HALF (1<<9)
#defineS3C2440_CAMDIVN_DVSEN (1<<12)
ulongget_HCLK(void)
{
S3C24X0_CLOCK_POWER* constclk_power = S3C24X0_GetBase_CLOCK_POWER();
unsignedlongclkdiv;
unsignedlongcamdiv;
inthdiv = 1;
clkdiv = clk_power->CLKDIVN;
camdiv = clk_power->CAMDIVN;
if(gd->bd->bi_arch_number== MACH_TYPE_SMDK2410)
return((clk_power->CLKDIVN& 0x2) ? get_FCLK()/2 : get_FCLK());
else
{
switch(clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {
caseS3C2440_CLKDIVN_HDIVN_1:
hdiv = 1;
break;
caseS3C2440_CLKDIVN_HDIVN_2:
hdiv = 2;
break;
caseS3C2440_CLKDIVN_HDIVN_4_8:
hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
break;
caseS3C2440_CLKDIVN_HDIVN_3_6:
hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
break;
}
returnget_FCLK() / hdiv;
}
}
ulongget_PCLK(void)
{
S3C24X0_CLOCK_POWER* constclk_power = S3C24X0_GetBase_CLOCK_POWER();
unsignedlongclkdiv;
unsignedlongcamdiv;
inthdiv = 1;
clkdiv = clk_power->CLKDIVN;
camdiv = clk_power->CAMDIVN;
if(gd->bd->bi_arch_number== MACH_TYPE_SMDK2410)
return((clk_power->CLKDIVN& 0x1) ? get_HCLK()/2 : get_HCLK());
else
{
switch(clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {
caseS3C2440_CLKDIVN_HDIVN_1:
hdiv = 1;
break;
caseS3C2440_CLKDIVN_HDIVN_2:
hdiv = 2;
break;
caseS3C2440_CLKDIVN_HDIVN_4_8:
hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
break;
caseS3C2440_CLKDIVN_HDIVN_3_6:
hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
break;
}
returnget_FCLK() / hdiv / ((clkdiv & S3C2440_CLKDIVN_PDIVN)? 2:1);
}
}
Previous article:Reflection on STM32: Don’t be an irritable embedded engineer
Next article:U-boot1.1.6 ported to TQ2440 development board (Part 2)
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- How Lucid is overtaking Tesla with smaller motors
- Wi-Fi 8 specification is on the way: 2.4/5/6GHz triple-band operation
- Wi-Fi 8 specification is on the way: 2.4/5/6GHz triple-band operation
- Vietnam's chip packaging and testing business is growing, and supply-side fragmentation is splitting the market
- Vietnam's chip packaging and testing business is growing, and supply-side fragmentation is splitting the market
- Three steps to govern hybrid multicloud environments
- Three steps to govern hybrid multicloud environments
- Microchip Accelerates Real-Time Edge AI Deployment with NVIDIA Holoscan Platform
- Microchip Accelerates Real-Time Edge AI Deployment with NVIDIA Holoscan Platform
- Melexis launches ultra-low power automotive contactless micro-power switch chip
- GD32E231 Learning 5: Color Sensor Module GY-31 Test
- Can modules be used in electric racing?
- Huawei P50 series released: the world's first 3D nano-crystal mobile phone
- How to test the continuity of the communication harness?
- FAQ_How to choose TCXO for S2-lp
- [CB5654 Intelligent Voice Development Board Review] First Look at the Intelligent Voice Development Board
- Live broadcast at 3pm today | Keysight Technologies HDMI / DP2.0 online test seminar
- MSP430 G2553 Launchpad implements capacitance measurement
- Emergency help--Drive material preparation, manufacturing process, and operation process knowledge
- Summary of Verilog non-synthesizable statements...