linux uboot启动流程分析,uboot启动流程分析

uboot版本为NXP维护的2016.03版本

下载地址为http://git.freescale.com/git/...

分析uboot的启动流程,需要编译一下uboot,然后打开链接脚本

u-boot.lds

在u-boot.lds中1 OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")

2 OUTPUT_ARCH(arm)

3 ENTRY(_start)

_start在arch/arm/lib/vectors.S48 _start:

49

50 #ifdef CONFIG_SYS_DV_NOR_BOOT_CFG

51 .word CONFIG_SYS_DV_NOR_BOOT_CFG

52 #endif

53

54 b reset

55 ldr pc, _undefined_instruction

56 ldr pc, _software_interrupt

57 ldr pc, _prefetch_abort

58 ldr pc, _data_abort

59 ldr pc, _not_used

60 ldr pc, _irq

61 ldr pc, _fiq

第54行跳转到reset函数里面,reset在arch/arm/cpu/armv7/start.S32 .globl reset

33 .globl save_boot_params_ret

34

35 reset:

36 /* Allow the board to save important registers */

37 b save_boot_params

38 save_boot_params_ret:

39 /*

40 * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,

41 * except if in HYP mode already

42 */

43 mrs r0, cpsr

44 and r1, r0, #0x1f @ mask mode bits

45 teq r1, #0x1a @ test for HYP mode

46 bicne r0, r0, #0x1f @ clear all mode bits

47 orrne r0, r0, #0x13 @ set SVC mode

48 orr r0, r0, #0xc0 @ disable FIQ and IRQ

49 msr cpsr,r0

......

57 /* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */

58 mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTLR Register

59 bic r0, #CR_V @ V = 0

60 mcr p15, 0, r0, c1, c0, 0 @ Write CP15 SCTLR Register

61

62 /* Set vector address in CP15 VBAR register */

63 ldr r0, =_start

64 mcr p15, 0, r0, c12, c0, 0 @Set VBAR

65 #endif

66

67 /* the mask ROM code should have PLL and others stable */

68 #ifndef CONFIG_SKIP_LOWLEVEL_INIT

69 bl cpu_init_cp15

70 bl cpu_init_crit

71 #endif

72

73 bl _main

第38行save_boot_params_ret函数实现以下功能:

43-49行将处理器设置SVC模式,并且关闭FIQ和IRQ

57-64行设置向量表重定位

第69行cpu_init_cp15函数初始化cp15,关闭mmu及tlb

第70行cpu_init_crit函数, 调用lowlevel_init函数,lowlevel_init在ocram中初始化sp然后调用s_init函数,如果CPU 为 MX6SX、MX6UL、MX6ULL 或MX6SLL中的任意一种,那么s_init为空函数。(为什么初始化sp?因为存在函数嵌套,只有一个lr寄存器)

接下来,分析_main函数。_main在arch/arm/lib/crt0.S67 ENTRY(_main)

68

69 /*

70 * Set up initial C runtime environment and call board_init_f(0).

71 */

72

73 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)

74 ldr sp, =(CONFIG_SPL_STACK)

75 #else

76 ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)

77 #endif

78 #if defined(CONFIG_CPU_V7M) /* v7M forbids using SP as BIC destination */

79 mov r3, sp

80 bic r3, r3, #7

81 mov sp, r3

82 #else

83 bic sp, sp, #7 /* 8-byte alignment for ABI compliance */

84 #endif

85 mov r0, sp

86 bl board_init_f_alloc_reserve

87 mov sp, r0

88 /* set up gd here, outside any C code */

89 mov r9, r0

90 bl board_init_f_init_reserve

91

92 mov r0, #0

93 bl board_init_f

94

95 #if ! defined(CONFIG_SPL_BUILD)

96

97 /*

98 * Set up intermediate environment (new sp and gd) and call

99 * relocate_code(addr_moni). Trick here is that we'll return

100 * 'here' but relocated.

101 */

102

103 ldr sp, [r9, #GD_START_ADDR_SP] /* sp = gd->start_addr_sp */

104#if defined(CONFIG_CPU_V7M) /* v7M forbids using SP as BIC destination */

105 mov r3, sp

106 bic r3, r3, #7

107 mov sp, r3

108#else

109 bic sp, sp, #7 /* 8-byte alignment for ABI compliance */

110#endif

111 ldr r9, [r9, #GD_BD] /* r9 = gd->bd */

112 sub r9, r9, #GD_SIZE /* new GD is below bd */

113

114 adr lr, here

115 ldr r0, [r9, #GD_RELOC_OFF] /* r0 = gd->reloc_off */

116 add lr, lr, r0

117#if defined(CONFIG_CPU_V7M)

118 orr lr, #1 /* As required by Thumb-only */

119#endif

120 ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */

121 b relocate_code

122here:

123/*

124 * now relocate vectors

125 */

126

127 bl relocate_vectors

128

129/* Set up final (full) environment */

130

131 bl c_runtime_cpu_setup /* we still call old routine here */

132#endif

133#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_FRAMEWORK)

134# ifdef CONFIG_SPL_BUILD

135 /* Use a DRAM stack for the rest of SPL, if requested */

136 bl spl_relocate_stack_gd

137 cmp r0, #0

138 movne sp, r0

139 movne r9, r0

140# endif

141 ldr r0, =__bss_start /* this is auto-relocated! */

142

143#ifdef CONFIG_USE_ARCH_MEMSET

144 ldr r3, =__bss_end /* this is auto-relocated! */

145 mov r1, #0x00000000 /* prepare zero to clear BSS */

146

147 subs r2, r3, r0 /* r2 = memset len */

148 bl memset

149#else

150 ldr r1, =__bss_end /* this is auto-relocated! */

151 mov r2, #0x00000000 /* prepare zero to clear BSS */

152

153clbss_l:cmp r0, r1 /* while not at end of BSS */

154#if defined(CONFIG_CPU_V7M)

155 itt lo

156#endif

157 strlo r2, [r0] /* clear 32-bit BSS word */

158 addlo r0, r0, #4 /* move to next */

159 blo clbss_l

160#endif

161

162#if ! defined(CONFIG_SPL_BUILD)

163 bl coloured_LED_init

164 bl red_led_on

165#endif

166 /* call board_init_r(gd_t *id, ulong dest_addr) */

167 mov r0, r9 /* gd_t */

168 ldr r1, [r9, #GD_RELOCADDR] /* dest_addr */

169 /* call board_init_r */

170#if defined(CONFIG_SYS_THUMB_BUILD)

171 ldr lr, =board_init_r /* this is auto-relocated! */

172 bx lr

173#else

174 ldr pc, =board_init_r /* this is auto-relocated! */

175#endif

176 /* we should not return here. */

177#endif

178

179ENDPROC(_main)

第76行,设置sp指向0X0091FF00

第85行,读取sp到寄存器r0里面,此时r0=0X0091FF00

第86行,调用函数board_init_f_alloc_reserve,此函数参数为r0中的值,也就是0X0091FF00,此函数定义在common/init/board_init.c56 ulong board_init_f_alloc_reserve(ulong top)

57 {

58 /* Reserve early malloc arena */

59 #if defined(CONFIG_SYS_MALLOC_F)

60 top -= CONFIG_SYS_MALLOC_F_LEN;

61 #endif

62 /* LAST : reserve GD (rounded up to a multiple of 16 bytes) */

63 top = rounddown(top-sizeof(struct global_data), 16);

64

65 return top;

66 }

函数board_init_f_alloc_reserve主要是留出早期的malloc内存区域和gd内存区域,ocram分布图如下:

bVcIAwU

接着分析_main函数

第87行,r0保存着函数board_init_f_alloc_reserve的返回值,所以sp=0X0091FA00

第89行,r9寄存器存放着全局变量gd的地址,gd为gd_t结构体变量include/asm-generic/global_data.h定义gd_t结构体27 typedef struct global_data {

28 bd_t *bd;

29 unsigned long flags;

30 unsigned int baudrate;

31 unsigned long cpu_clk; /* CPU clock in Hz! */

32 unsigned long bus_clk;

33 /* We cannot bracket this with CONFIG_PCI due to mpc5xxx */

34 unsigned long pci_clk;

35 unsigned long mem_clk;

36 #if defined(CONFIG_LCD) || defined(CONFIG_VIDEO)

37 unsigned long fb_base; /* Base address of framebuffer mem */

38 #endif

......

121 #ifdef CONFIG_DM_VIDEO

122 ulong video_top; /* Top of video frame buffer area */

123 ulong video_bottom; /* Bottom of video frame buffer area */

124 #endif

125 } gd_t;

gd保存着系统初始化参数

所以,第89行设置gd指向0X0091FA00

接着分析_main函数

第90行,调用函数board_init_f_init_reserve,此函数定义在common/init/board_init.c110 void board_init_f_init_reserve(ulong base)

111 {

112 struct global_data *gd_ptr;

113 #ifndef _USE_MEMCPY

114 int *ptr;

115 #endif

116

117 /*

118 * clear GD entirely and set it up.

119 * Use gd_ptr, as gd may not be properly set yet.

120 */

121

122 gd_ptr = (struct global_data *)base;

123 /* zero the area */

124 #ifdef _USE_MEMCPY

125 memset(gd_ptr, '\0', sizeof(*gd));

126 #else

127 for (ptr = (int *)gd_ptr; ptr < (int *)(gd_ptr + 1); )

128 *ptr++ = 0;

129 #endif

130 /* set GD unless architecture did it already */

131 #if !defined(CONFIG_ARM)

132 arch_setup_gd(gd_ptr);

133 #endif

134 /* next alloc will be higher by one GD plus 16-byte alignment */

135 base += roundup(sizeof(struct global_data), 16);

136

137 /*

138 * record early malloc arena start.

139 * Use gd as it is now properly set for all architectures.

140 */

141

142 #if defined(CONFIG_SYS_MALLOC_F)

143 /* go down one 'early malloc arena' */

144 gd->malloc_base = base;

145 /* next alloc will be higher by one 'early malloc arena' size */

146 base += CONFIG_SYS_MALLOC_F_LEN;

147 #endif

148 }

此函数将gd清零,gd->malloc_base=0X0091FB00

接着分析_main函数

第93行,调用board_init_f函数,此函数定义在文件 common/board_f.c,主要用来初始化DDR,定时器,完成代码拷贝1035 void board_init_f(ulong boot_flags)

1036 {

1037 #ifdef CONFIG_SYS_GENERIC_GLOBAL_DATA

1038 /*

1039 * For some archtectures, global data is initialized and used

1040 * before calling this function. The data should be preserved.

1041 * For others, CONFIG_SYS_GENERIC_GLOBAL_DATA should be defined

1042 * and use the stack here to host global data until relocation.

1043 */

1044 gd_t data;

1045

1046 gd = &data;

1047

1048 /*

1049 * Clear global data before it is accessed at debug print

1050 * in initcall_run_list. Otherwise the debug print probably

1051 * get the wrong vaule of gd->have_console.

1052 */

1053 zero_global_data();

1054 #endif

1055

1056 gd->flags = boot_flags;

1057 gd->have_console = 0;

1058

1059 if (initcall_run_list(init_sequence_f))

1060 hang();

1061

1062 #if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) && \

1063 !defined(CONFIG_EFI_APP)

1064 /* NOTREACHED - jump_to_copy() does not return */

1065 hang();

1066 #endif

1067 }

第1059行,通过函数initcall_run_list来运行初始化序列 init_sequence_f里面的一系列函数,init_sequence_f里面包含了一系列的初始化函数,最终,内存分配如图:

bVcIAFJ

接着分析_main函数

第103行,sp=gd->start_addr_sp=0X9EF44E90

第 121 行,调用函数relocate_code,此函数定义在文件arch/arm/lib/relocate.S

拷贝uboot到DDR79 ENTRY(relocate_code)

80 ldr r1, =__image_copy_start /* r1

81 subs r4, r0, r1 /* r4

82 beq relocate_done /* skip relocation */

83 ldr r2, =__image_copy_end /* r2

84

85 copy_loop:

86 ldmia r1!, {r10-r11} /* copy from source address [r1] */

87 stmia r0!, {r10-r11} /* copy to target address [r0] */

88 cmp r1, r2 /* until source end address [r2] */

89 blo copy_loop

90

91 /*

92 * fix .rel.dyn relocations

93 */

94 ldr r2, =__rel_dyn_start /* r2

95 ldr r3, =__rel_dyn_end /* r3

96 fixloop:

97 ldmia r2!, {r0-r1} /* (r0,r1)

98 and r1, r1, #0xff

99 cmp r1, #23 /* relative fixup? */

100 bne fixnext

101

102 /* relative fix: increase location by offset */

103 add r0, r0, r4

104 ldr r1, [r0]

105 add r1, r1, r4

106 str r1, [r0]

107 fixnext:

108 cmp r2, r3

109 blo fixloop

110

111 relocate_done:

112

113 #ifdef __XSCALE__

114 /*

115 * On xscale, icache must be invalidated and write buffers

116 * drained, even with cache disabled - 4.2.7 of xscale core

117 developer's manual */

118 mcr p15, 0, r0, c7, c7, 0 /* invalidate icache */

119 mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */

120 #endif

121

122 /* ARMv4- don't know bx lr but the assembler fails to see that */

123

124 #ifdef __ARM_ARCH_4__

125 mov pc, lr

126 #else

127 bx lr

128 #endif

129

130 ENDPROC(relocate_code)

接着分析_main函数

第 127 行,调用函数relocate_vectors,对中断向量表做重定位,此函数定义在文件arch/arm/lib/relocate.S

重定位向量表27 ENTRY(relocate_vectors)

28

29 #ifdef CONFIG_CPU_V7M

30 /*

31 * On ARMv7-M we only have to write the new vector address

32 * to VTOR register.

33 */

34 ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */

35 ldr r1, =V7M_SCB_BASE

36 str r0, [r1, V7M_SCB_VTOR]

37 #else

38 #ifdef CONFIG_HAS_VBAR

39 /*

40 * If the ARM processor has the security extensions,

41 * use VBAR to relocate the exception vectors.

42 */

43 ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */

44 mcr p15, 0, r0, c12, c0, 0 /* Set VBAR */

45 #else

46 /*

47 * Copy the relocated exception vectors to the

48 * correct address

49 * CP15 c1 V bit gives us the location of the vectors:

50 * 0x00000000 or 0xFFFF0000.

51 */

52 ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */

53 mrc p15, 0, r2, c1, c0, 0 /* V bit (bit[13]) in CP15 c1 */

54 ands r2, r2, #(1 << 13)

55 ldreq r1, =0x00000000 /* If V=0 */

56 ldrne r1, =0xFFFF0000 /* If V=1 */

57 ldmia r0!, {r2-r8,r10}

58 stmia r1!, {r2-r8,r10}

59 ldmia r0!, {r2-r8,r10}

60 stmia r1!, {r2-r8,r10}

61 #endif

62 #endif

63 bx lr

64

65 ENDPROC(relocate_vectors)

接着分析_main函数

第 131 行,调用函数c_runtime_cpu_setup,此函数定义在文件 arch/arm/cpu/armv7/start.S77 ENTRY(c_runtime_cpu_setup)

78 /*

79 * If I-cache is enabled invalidate it

80 */

81 #ifndef CONFIG_SYS_ICACHE_OFF

82 mcr p15, 0, r0, c7, c5, 0 @ invalidate icache

83 mcr p15, 0, r0, c7, c10, 4 @ DSB

84 mcr p15, 0, r0, c7, c5, 4 @ ISB

85 #endif

86

87 bx lr

88

89 ENDPROC(c_runtime_cpu_setup)

接着分析_main函数

第 141~159 行,清除 BSS 段

第 174 行、调用函数board_init_r,此函数定义在文件 common/board_r.c

board_init_f函数调用一系列的函数来初始化一些外

设和 gd 的成员变量,但是 board_init_f 并没有初始化所有的外设,还需要做一些后续工作,这些后续工作就是由函数board_init_r来完成的。991 void board_init_r(gd_t *new_gd, ulong dest_addr)

992 {

993 #ifdef CONFIG_NEEDS_MANUAL_RELOC

994 int i;

995 #endif

996

997 #ifdef CONFIG_AVR32

998 mmu_init_r(dest_addr);

999 #endif

1000

1001 #if !defined(CONFIG_X86) && !defined(CONFIG_ARM)

&& !defined(CONFIG_ARM64)

1002 gd = new_gd;

1003 #endif

1004

1005 #ifdef CONFIG_NEEDS_MANUAL_RELOC

1006 for (i = 0; i < ARRAY_SIZE(init_sequence_r); i++)

1007 init_sequence_r[i] += gd->reloc_off;

1008 #endif

1009

1010 if (initcall_run_list(init_sequence_r))

1011 hang();

1012

1013 /* NOTREACHED - run_main_loop() does not return */

1014 hang();

1015 }

第1010行调用initcall_run_list函数来执行初始化序列 init_sequence_r,init_sequence_r是一个函数集合,定义如下:1 init_fnc_t init_sequence_r[] = {

2 initr_trace,

3 initr_reloc,

4 initr_caches,

5 initr_reloc_global_data,

6 initr_barrier,

7 initr_malloc,

8 initr_console_record,

9 bootstage_relocate,

10 initr_bootstage,

11 board_init, /* Setup chipselects */

12 stdio_init_tables,

13 initr_serial,

14 initr_announce,

15 INIT_FUNC_WATCHDOG_RESET

16 INIT_FUNC_WATCHDOG_RESET

17 INIT_FUNC_WATCHDOG_RESET

18 power_init_board,

19 initr_flash,

20 INIT_FUNC_WATCHDOG_RESET

21 initr_nand,

22 initr_mmc,

23 initr_env,

24 INIT_FUNC_WATCHDOG_RESET

25 initr_secondary_cpu,

26 INIT_FUNC_WATCHDOG_RESET

27 stdio_add_devices,

28 initr_jumptable,

29 console_init_r, /* fully init console as a device */

30 INIT_FUNC_WATCHDOG_RESET

31 interrupt_init,

32 initr_enable_interrupts,

33 initr_ethaddr,

34 board_late_init,

35 INIT_FUNC_WATCHDOG_RESET

36 INIT_FUNC_WATCHDOG_RESET

37 INIT_FUNC_WATCHDOG_RESET

38 initr_net,

39 INIT_FUNC_WATCHDOG_RESET

40 run_main_loop,

41 };

第40行,run_main_loop函数,定义在common/board_r.c中:753 static int run_main_loop(void)

754 {

755 #ifdef CONFIG_SANDBOX

756 sandbox_main_loop_init();

757 #endif

758 /* main_loop() can return to retry autoboot, if so just run it

again */

759 for (;;)

760 main_loop();

761 return 0;

762 }

第760行,main_loop函数,定义在common/main.c:43 /* We come here after U-Boot is initialised and ready to process

commands */

44 void main_loop(void)

45 {

46 const char *s;

47

48 bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop");

49

50 #ifndef CONFIG_SYS_GENERIC_BOARD

51 puts("Warning: Your board does not use generic board. Please

read\n");

52 puts("doc/README.generic-board and take action. Boards not\n");

53 puts("upgraded by the late 2014 may break or be removed.\n");

54 #endif

55

56 #ifdef CONFIG_VERSION_VARIABLE

57 setenv("ver", version_string); /* set version variable */

58 #endif /* CONFIG_VERSION_VARIABLE */

59

60 cli_init();

61

62 run_preboot_environment_command();

63

64 #if defined(CONFIG_UPDATE_TFTP)

65 update_tftp(0UL, NULL, NULL);

66 #endif /* CONFIG_UPDATE_TFTP */

67

68 s = bootdelay_process();

69 if (cli_process_fdt(&s))

70 cli_secure_boot_cmd(s);

71

72 autoboot_command(s);

73

74 cli_loop();

75 }

第48行,调用`bootstage_mark_name函数,打印出启动进度

第72行,autoboot_command函数,定义在common/autoboot.c,检查倒计时是否结束?倒计时结束之前有没有被打断?380 void autoboot_command(const char *s)

381 {

382 debug("### main_loop: bootcmd=\"%s\"\n", s ? s : "");

383

384 if (stored_bootdelay != -1 && s && !abortboot(stored_bootdelay))

{

385 #if defined(CONFIG_AUTOBOOT_KEYED)

&& !defined(CONFIG_AUTOBOOT_KEYED_CTRLC)

386 int prev = disable_ctrlc(1); /* disable Control C checking

*/

387 #endif

388

389 run_command_list(s, -1, 0);

390

391 #if defined(CONFIG_AUTOBOOT_KEYED)

&& !defined(CONFIG_AUTOBOOT_KEYED_CTRLC)

392 disable_ctrlc(prev); /* restore Control C checking */

393 #endif

394 }

395

396 #ifdef CONFIG_MENUKEY

397 if (menukey == CONFIG_MENUKEY) {

398 s = getenv("menucmd");

399 if (s)

400 run_command_list(s, -1, 0);

401 }

402 #endif /* CONFIG_MENUKEY */

403 }

第400行,如果倒计时自然结束那么久执行函数run_command_list,此函数为执行环境变量bootcmd的命令。

如果倒计时结束之前按下按键,那么就执行main_loop函数中第74行的cli_loop函数,此函数为命令处理函数。

综上,整理下uboot启动流程

bVcIAJk

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/355463.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaOne 2015 –第二十版十大收获

我们刚刚在旧金山有了JavaOne的第二十版。 这将是我自2004年以来第十二次参加不间断的系列活动。最大的教训是什么&#xff0c;可以揭示Java的未来。 模块化斗争 自从Java 2007首次提到模块以来&#xff0c;已经花费了将近9年的时间&#xff0c;或者说&#xff0c;直到2016年9…

IOS--文件管理NSFileManager

iOS的沙盒机制。应用仅仅能訪问自己应用文件夹下的文件。iOS不像android。没有SD 卡概念。不能直接訪问图像、视频等内容。iOS应用产生的内容&#xff0c;如图像、文件、缓存内容等都必须存储在自己的沙盒内。默认情况下&#xff0c;每一个沙盒含有3个文件 夹&#xff1a;Docum…

linux修改文件内容_详解5种实用方法---Linux系统清空或删除大文件内容

概述有时我们在处理Linux终端中的文件时&#xff0c;可能要去清除文件的内容&#xff0c;而无需使用任何Linux命令行编辑器打开它。怎么才能实现呢&#xff1f;下面通过几种不同的方式教大家清空文件内容。1.通过重定向到空来清空文件内容使用shell重定向null(不存在的对象)清空…

凯撒密码c语言小写字母,凯撒密码c(c语言编程凯撒密码)

凯撒密码c(c语言编程凯撒密码)2020-05-15 13:09:51共10个回答#include#includeintmain(){charsave[10][30];inta,b,i,j;scanf(&#xff02;%d&#xff02;,&a);for(i0;i能不能说清楚一点,是加密吗?#include#include#defineMAXSIZE81intmain(){charstr[MAXSIZE];inti;intof…

Java正则表达式库基准测试– 2015年

在尝试使Java在计算机语言基准测试游戏的regexdna挑战中排名第一时&#xff0c;我正在研究Java正则表达式库的性能。 我可以找到的最新网站是2010年的tusker.org 。因此&#xff0c;我决定使用Java Microbenchmarking Harness重做测试并发布结果&#xff08;破坏性警告&#xf…

C语言写程序注意,单片机C语言编程应注意的若干问题

作为一种结构化的程序设计语言&#xff0c;C语言的特点就是可以使你尽量少地对硬件进行操作&#xff0c;具有很强的功能性、结构性和可移植性&#xff0c;常常被优选作为单片机系统的编程语言。但是基于单片机的C语言和标准C语言有很大区别&#xff0c;如何结合单片机的系统资源…

Java实现将日志信息存到TXT中

在java文件操作的时候,思考将日志信息存到txt中,现在很多项目都是通过log4j来做的,同样也会用到将日志存到txt中. package FileOperation;import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.Calenda…

接口返回的类型是html页面_1.10 PhalApi 2.x 接口文档

接口文档在线接口文档PhalApi提供一些非常实用而又贴心的功能特性&#xff0c;其中最具特色的就是自动生成的在线可视化文档。在线接口文档主要分为两大类&#xff0c;分别是&#xff1a; 在线接口列表文档在线接口详情文档当客户端不知道有哪些接口服务&#xff0c;或者需要查…

jmeter数据库负载测试_JMeter:负载测试关系数据库

jmeter数据库负载测试Apache JMeter是完全使用Java编写的性能测试工具。 可以在请求/响应模型上运行的任何应用程序都可以使用JMeter进行负载测试。 关系数据库也不例外&#xff1a;接收sql查询&#xff0c;执行查询并返回执行结果。 我将向您展示使用JMeter的图形用户界面设置…

具有Couchbase,Java EE和WildFly的CRUD Java应用程序

Couchbase是一个开源的NoSQL文档数据库。 它允许访问&#xff0c;索引和查询JSON文档&#xff0c;同时利用集成的分布式缓存来实现高性能的数据访问。 开发人员可以使用不同的语言&#xff08;Java&#xff0c;Go&#xff0c;.NET&#xff0c;Node&#xff0c;PHP&#xff0c;…

c语言10个人 三向成绩,C语言入门学习精华:这样学习C语言最有效

C语言入门学习精华&#xff1a;这样学习C语言最有效c语言死了吗&#xff1f;本材料描述了使用C语言的高级技能&#xff0c;并努力将您的C语言能力从“基本”提升到“高级”。然而&#xff0c;学习态度比学习方法要好。在正式学习之前&#xff0c;有一个问题是不能抱怨的。也就是…

jQuery UI全教程之一(dialog的使用教程)

jQuery UI目前的版本已经更新到了1.8.7。个人感觉和easyui相比起来&#xff0c;jQuery UI在界面的美观程度和可定制型更强一些。所以再次将一些jQuery UI组件的用法说明一下&#xff0c;方便日后查阅。也方面没接触jQuery UI的人能早日使用jQuery UI套件 (一)首先来说jQuery UI…

akka es/cqrs_在Akka中实现主从/网格计算模式

akka es/cqrs主从模式是容错和并行计算的主要示例。 模式背后的想法是将工作划分为相同的子任务&#xff0c;然后将其委派给从属。 这些从属节点或实例将处理工作任务&#xff0c;并将结果发送回主节点。 然后主节点将编译从所有从节点接收到的结果。关键是从节点仅知道如何处理…

05 HTML字符串转换成jQuery对象、绑定数据到元素上

1 要求 将一段 HTML脚本 封装成一个字符串&#xff0c;将这个字符串转换成一个jQuery对象&#xff1b;然后将这个jQuery对象添加到指定的元素中去 2 步骤 定义字符串 var str <div id"box01">hello world</div>; //定义一个字符串 利用jQuery框架将字符…

c语言求佩尔方程的解设计思路,c语言版 佩尔方程求最小正整数解及第k解(矩阵快速幂)...

佩尔方程讲解连接&#xff1a;若一个丢番图方程具有以下的形式&#xff1a;且为正整数&#xff0c;则称此方程为佩尔方程(英文&#xff1a;Pells equation 德文&#xff1a;Pellsche Gleichung) 若是完全平方数&#xff0c;则这个方程式只有解(实际上对任意的&#xff0c;都是解…

android 9.0 https 适配,如何适配 Android 9.0? 在 Android 9.0 上发生 SSL handshake timed out 异常怎么解决...

Android 9.0 开始&#xff0c;默认不允许明文传输&#xff0c;所以在建立网络连接时会使用 https 连接&#xff0c;同时进行安全认证。如果应用没有做对应处理&#xff0c;即会发生上述异常。解决方法有两种&#xff1a;一. 在应用里声明允许明文传输.1. 在应用的 res/xml 文件…

java 7.函数-递归_带有谓词的Java中的函数样式-第1部分

java 7.函数-递归您一直在听到将要席卷全球的函数式编程&#xff0c;而您仍然坚持使用普通Java&#xff1f; 不用担心&#xff0c;因为您已经可以在日常Java中添加一些功能样式。 此外&#xff0c;它很有趣&#xff0c;可以节省许多代码行并减少错误。 什么是谓词&#xff1f; …

大话oraclerac集群、高可用性、备份与恢复_数腾Oracle RAC数据库灾备解决方案

“一个系统包含很多模块&#xff0c;数据库、前端、缓存、搜索、消息队列等&#xff0c;每个模块都需要做到高可用&#xff0c;才能保证整个系统的高可用。”数据库作为现代信息社会的基石&#xff0c;几乎所有的计算机应用软件都构建于数据库系统之上&#xff0c;对于数据库而…

Android面试题Service,Android面试题-IntentService源码分析

自定义控件联网工具数据库源码分析相关面试题Activity相关面试题Service相关面试题与XMPP相关面试题与性能优化相关面试题与登录相关面试题与开发相关面试题与人事相关面试题人事面试宝典IntentService是继承于Service并处理异步请求的一个类&#xff0c;在IntentService内有一…

OpenGL中的Shader

http://blog.csdn.net/huangcanjun187/article/details/52474365 学习总结自&#xff1a;http://learnopengl.com/#!Getting-started/Hello-Triangle http://learnopengl.com/#!Getting-started/Shaders 继上篇文章中提到&#xff0c;OpenGL是为了在GPU上同时跑成千上万个程序&…