1. ;************************************************************************
  2. ;*
  3. ;* FUNCTION
  4. ;*
  5. ;* INT_IRQ
  6. ;*
  7. ;* DESCRIPTION
  8. ;*
  9. ;* This routine is the board-specific section for
  10. ;* level 1 interrupt handling
  11. ;*
  12. ;* CALLED BY
  13. ;*
  14. ;* None
  15. ;*
  16. ;* CALLS
  17. ;*
  18. ;* TMT_Timer_Interrupt
  19. ;*
  20. ;* INPUTS
  21. ;*
  22. ;* None
  23. ;*
  24. ;*
  25. ;* OUTPUTS
  26. ;*
  27. ;* None
  28. ;*
  29. ;* HISTORY
  30. ;*
  31. ;* NAME DATE REMARKS
  32. ;*
  33. ;* B. Ronquillo 05-10-00 Created initial version 1.0
  34. ;*
  35. ;************************************************************************
  36. .def _INT_IRQ
  37. _INT_IRQ
  38. ; ARM Core Check                                                                 //确认CPSR,这里应该是确认是否在IRQ模式下
  39. STMDB {r1}
  40. MRS r1, SPSR
  41. TST r1, #IRQ_BIT
  42. LDMIA {r1}
  43. SUBNES pc,lr,#4
  44. STMDB sp!,{r0-r4} ; Save r0-r4 on temporary IRQ stack                         //sp=sp-4 保存R0~R4到栈
  45. SUB lr,lr,#4 ; Adjust IRQ return address                                      //lr=lr-4就是把lr下移了一格
  46. ;********************************
  47. ;* Begin Hardware Specific Code *                                                 //开始硬件特性代码?
  48. ;********************************
  49. LDR r3, INT_CNTRL_BASE_1 ; load Interrupt Control Base                        //装载中断控制器基地址
  50. LDR r4, [r3,#INT_CNTRL_MIR] ; Get enable register value                       //获取enable register的值,INT_CNTRL_MIR的值
  51. ;******************************
  52. ;* End Hardware Specific Code *
  53. ;******************************
  54. STMDB sp!,{r4} ; Put the enable register value on the IRQ stack               //把r4压入栈,r4是enable register的值
  55. MVN r4,#0 ; Start with 0xFFFFFFFF to allow nesting of interrupts              //全部置1
  56. ;********************************
  57. ;* Begin Hardware Specific Code *
  58. ;********************************
  59. LDR r2, [r3,#INT_CNTRL_ITR] ; Read Pending reg                                 //这次读取了INT_CNTRL_ITR的值
  60. ;******************************
  61. ;* End Hardware Specific Code *
  62. ;******************************
  63. LDR r3, IRQ_Priority ; Get the Priority table address                          //获取IRQ优先级表的地址
  64. IRQ_VECTOR_LOOP
  65. LDR r0, [r3,#0] ; Load first vector to be checked from priority table
  66. MOV r1, #1 ; Build mask
  67. MOV r1, r1, LSL r0 ; Use vector number to set mask to correct bit position            //逻辑左移优先级个数,不会溢出吗
  68. TST r1, r2 ; Test if pending bit is set                                               //判断
  69. BNE IRQ_VECTOR_FOUND ; If bit is set, branch to found section...                      //找到IRQ_VECTOR
  70. BIC r4,r4,r1 ; Clear mask bit to keep higher priority ints active                     //如果没找到查下一个向量表?
  71. ADD r3, r3, #4 ; Move to next word in the priority table
  72. ADR r0, Priority_End ; Load the end address for the priority table
  73. CMP r0, r3 ; Make sure not at the end of the table (shouldn't happen!)
  74. BNE     IRQ_VECTOR_LOOP                 ; Continue to loop if not at the end of the table





        ; No bits in pending register set, restore registers and exit interrupt servicing                         //恢复上下文

        ADD     sp,sp,#4                        ; Adjust sp above IRQ enable value

        LDMIA   sp!,{r0-r4}                     ; Restore r0-r4

        STMDB   sp!,{lr}                        ; Put return address for IRQ on stack

        LDMIA   sp!,{pc}^                       ; return to the point of the exception and restore SPSR

     

    IRQ_VECTOR_FOUND





    ;********************************

    ;* Begin Hardware Specific Code *

    ;********************************





        LDR     r3, INT_CNTRL_BASE_1            ; load Interrupt Control Base                              //获取INT_CNTRL_BASE



      

        MVN     r2, r1                          ; Get the inverse of the interrupt vector                  //之前r1和r2应该是一样的,取了反

        STR     r2, [r3,#INT_CNTRL_ITR]         ; Write a zero to the interrupt being handled              //写一个0到中断处理中





        LDR     r2, [r3,#INT_CNTRL_MIR]         ; Read the Mask reg

        ORR     r4, r2, r4                      ; Turn off lower priority pending bits and currently masked bits

        STR     r4, [r3,#INT_CNTRL_MIR]         ; Disable(Mask) all lower priority interrupts and currently masked interrupts





        MOV     r1, #1                          ; Clear the pending interrupt                              //清除pending中断位

        STR     r1, [r3,#INT_CNTRL_CONTROL_REG] ; by writing a 1 to the Control Reg                        //写入1清除





    ;******************************

    ;* End Hardware Specific Code *

    ;******************************





        LDR     r3, IRQ_Vectors                 ; Get IRQ vector table address

        MOV     r2, r0, LSL #2                  ; Multiply vector by 4 to get offset into table

        ADD     r3, r3, r2                      ; Adjust vector table address to correct offset

        LDR     r2, [r3,#0]                     ; Load branch address from vector table





        MOV     PC, r2                          ; Jump to correct branch location based on vector table          //跳转到中断向量表,这个跳转应该是找到对应的处理程序?





    ; END: INT_IRQ


中断向量表:

  1. ; Define vector table used by INT_IRQ to branch to necessary ISR
  2. INT_IRQ_Vectors:
  3. .word _INT_IRQ_2 ; Vector 0
  4. .word INT_Interrupt_Shell ; Vector 1
  5. .word INT_Interrupt_Shell ; Vector 2
  6. .word INT_Interrupt_Shell ; Vector 3
  7. .word INT_Interrupt_Shell ; Vector 4
  8. .word INT_Interrupt_Shell ; Vector 5
  9. .word INT_Interrupt_Shell ; Vector 6
  10. .word INT_Interrupt_Shell ; Vector 7
  11. .word INT_Interrupt_Shell ; Vector 8
  12. .word INT_Interrupt_Shell ; Vector 9
  13. .word INT_Interrupt_Shell ; Vector 10
  14. .word INT_Interrupt_Shell ; Vector 11
  15. .word INT_Interrupt_Shell ; Vector 12
  16. .word INT_Interrupt_Shell ; Vector 13
  17. .word INT_Interrupt_Shell ; Vector 14
  18. .word INT_Interrupt_Shell ; Vector 15
  19. .word INT_Interrupt_Shell ; Vector 16
  20. .word INT_Interrupt_Shell ; Vector 17
  21. .word INT_Interrupt_Shell ; Vector 18
  22. .word INT_Interrupt_Shell ; Vector 19
  23. .word INT_Interrupt_Shell ; Vector 20
  24. .word INT_Interrupt_Shell ; Vector 21
  25. .word INT_Interrupt_Shell ; Vector 22
  26. .word INT_Interrupt_Shell ; Vector 23
  27. .word INT_Interrupt_Shell ; Vector 24
  28. .word INT_Interrupt_Shell ; Vector 25
  29. .word INT_Interrupt_Shell ; Vector 26
  30. .word INT_Interrupt_Shell ; Vector 27
  31. .word INT_Interrupt_Shell ; Vector 28
  32. .word INT_Interrupt_Shell ; Vector 29
  33. .word INT_Timer_Interrupt ; Vector 30
  34. .word INT_Interrupt_Shell ; Vector 31
  35. 。。。。。。。。。。。。。。。

INT_Interruopt_Shell(感觉只是跳转到_TCT_Interrupt_Context_Save):

  1. ;************************************************************************
  2. ;*
  3. ;* FUNCTION
  4. ;*
  5. ;* INT_Interrupt_Shell
  6. ;*
  7. ;* DESCRIPTION
  8. ;*
  9. ;* Handles all interrupts which use NU_Register_LISR.
  10. ;*
  11. ;*
  12. ;* CALLED BY
  13. ;*
  14. ;* INT_IRQ
  15. ;*
  16. ;* CALLS
  17. ;*
  18. ;* TCT_Dispatch_LISR
  19. ;* TCT_Interrupt_Context_Restore
  20. ;*
  21. ;* INPUTS
  22. ;*
  23. ;* vector (register r0)
  24. ;*
  25. ;* OUTPUTS
  26. ;*
  27. ;* None
  28. ;************************************************************************
  29. .def INT_Interrupt_Shell
  30. INT_Interrupt_Shell
  31. MOV r4,lr ; Put IRQ return address into r4                                                   //这里r4是PC的值
  32. BL _TCT_Interrupt_Context_Save                                                               //什么直接跳转了?
  33. BL _TCC_Dispatch_LISR                                                                        //怎么两个跳转?LISR?
  34. MRS r1,CPSR ; Pickup current CPSR                                                            //清除了中断,关了位
  35. BIC r1,r1,#MODE_MASK ; Clear the mode bits
  36. ORR r1,r1,#(IRQ_MODE_OR_LOCKOUT) ; Set the IRQ mode bits and Lockout interrupts
  37. MSR CPSR,r1 ; Lockout interrupts/change to IRQ mode
  38. ;********************************
  39. ;* Begin Hardware Specific Code *
  40. ;********************************
  41. LDMIA sp!,{r1} ; Get IRQ enable value off IRQ stack                                              //提取栈中的值到sp
  42. LDR r2, INT_CNTRL_BASE_1 ; Get IRQ0 base register address                                        //获取IRQ0基地址
  43. STR r1,[r2,#INT_CNTRL_MIR] ; Re-enable all lower priority interrupts                             //重新开启低优先级中断
  44. ;******************************
  45. ;* End Hardware Specific Code *
  46. ;******************************
  47. MRS r1,CPSR ; Pickup current CPSR
  48. BIC r1,r1,#MODE_MASK ; Clear the mode bits
  49. ORR r1,r1,#SUP_MODE ; Set the SVC mode bits
  50. MSR CPSR,r1 ; Change to SVC mode                                                                 //切换成svc模式
  51. B _TCT_Interrupt_Context_Restore

既然跳转到_TCT_Interrupt_Context_Save那就继续学习吧:

  1. ;************************************************************************
  2. ;*
  3. ;* FUNCTION
  4. ;*
  5. ;* TCT_Interrupt_Context_Save
  6. ;*
  7. ;* DESCRIPTION
  8. ;*
  9. ;* This function saves the interrupted thread's context. Nested
  10. ;* interrupts are also supported. If a task or HISR thread was
  11. ;* interrupted, the stack pointer is switched to the system stack
  12. ;* after the context is saved.
  13. ;*
  14. ;* CALLED BY
  15. ;*
  16. ;* Application ISRs Assembly language ISRs
  17. ;* INT_Interrupt_Shell Interrupt handler shell
  18. ;*
  19. ;* CALLS
  20. ;*
  21. ;* None
  22. ;*
  23. ;* INPUTS
  24. ;*
  25. ;* vector Interrupt's vector number
  26. ;*
  27. ;* OUTPUTS
  28. ;*
  29. ;* None
  30. ;*
  31. ;* HISTORY
  32. ;*
  33. ;* NAME DATE REMARKS
  34. ;*
  35. ;* W. Lamie 02-15-1994 Created initial version 1.0
  36. ;* D. Lamie 02-15-1994 Verified version 1.0
  37. ;* D. Driscoll 01-04-2002 Released version 1.13.3.
  38. ;* Updated to handle nested /
  39. ;* prioritized IRQs
  40. ;************************************************************************
  41. ;VOID TCT_Interrupt_Context_Save(INT vector)
  42. ;{
  43. .def $TCT_Interrupt_Context_Save
  44. $TCT_Interrupt_Context_Save ; Dual-state interworking veneer
  45. .state16
  46. BX r15
  47. NOP
  48. .state32
  49. B _TCT_Interrupt_Context_Save
  50. .def _TCT_Interrupt_Context_Save
  51. _TCT_Interrupt_Context_Save
  52. ; Determine if this is a nested interrupt.                                                          //确定是不是嵌套中断
  53. LDR r1,Int_Count ; Pickup address of interrupt count                                                //Int_Count是中断计数
  54. LDR r2,[r1, #0] ; Pickup interrupt counter
  55. ADD r2,r2,#1 ; Add 1 to interrupt counter
  56. STR r2,[r1, #0] ; Store new interrupt counter value                                                 //更新中断计数
  57. CMP r2,#1 ; Is it nested?
  58. BEQ TCT_Not_Nested_Save ; No                                                                        //如果不是嵌套就跳转
  59. ; Nested interrupt. Save complete context on the current stack.
  60. TCT_Nested_Save
  61. ; 1. Save another register on the exception stack so we have enough to work with                            //保存另一个寄存器(r5)到异常栈,腾出空间来。r13是sp指针
  62. STMDB r13!,{r5}
  63. ; 2. Save the necessary exception registers into r1-r3                                                      //保存必要的异常寄存器到r1-r3
  64. MOV r1,r13 ; Put the exception r13 into r1
  65. MOV r2,r14 ; Move the return address for the caller
  66. ; of this function into r2
  67. MRS r3,spsr ; Put the exception spsr into r3
  68. ; 3. Adjust the exception stack pointer for future exceptions                                               //调整异常栈指针为之后的异常
  69. ADD r13,r13,#24 ; r13 will point to enable reg value when done
  70. ; 4. Switch CPU modes to save context on system stack                                                       //转换CPU模式到system stack(之前初始化过的)
  71. MRS r5,CPSR ; Pickup the current CPSR
  72. BIC r5,r5,#MODE_MASK ; Clear the mode bits
  73. ORR r5,r5,#SUP_MODE ; Change to supervisor mode (SVD)
  74. MSR CPSR,r5 ; Switch modes (IRQ->SVC)
  75. ; 5. Store the SVC r13 into r5 so the r13 can be saved as is.                                               //这里明明是把r5放进r13(sp)
  76. MOV r5,r13
  77. ; 6. Save the exception return address on the stack (r15).                                                  //保存r4进栈
  78. STMDB r5!,{r4}
  79. ; 7. Save r6-r14 on stack                                                                                   //保存r6-r14进栈
  80. STMDB r5!,{r6-r14}
  81. ; 8. Switch back to using r13 now that the original r13 has been saved.                                     //又把r13换回来了,回到sp回到原来的位置了
  82. MOV r13,r5
  83. ; 9. Get r5 and exception enable registers off of exception stack and                                       //
  84. ; save r5 (stored in r4) back to the system stack.                                                          //保存r5(存在r4中)到system stack中,好吧之前的mov都理解错了,mov 目的,源
  85. LDMIA r1!,{r4-r5}
  86. STMDB r13!,{r4}
  87. MOV r4,r5 ; Put exception enable value into r4
  88. ; 10. Get the rest of the registers off the exception stack and                                             //获取剩下的exception stack到system stack中
  89. ; save them onto the system stack.
  90. LDMIA r1!,{r5-r8,r11} ; Get r0-r4 off exception stack
  91. STMDB r13!,{r5-r8,r11} ; Put r0-r4 on system stack
  92. ; 11. Store the exception enable value back on the exception stack.
  93. STMDB r1,{r4}
  94. ; 12. Save the SPSR on the system stack (CPSR)
  95. STMDB r13!,{r3}
  96. ; 13. Re-enable interrupts                                                                                   //重新开启中断
  97. MRS r1,CPSR
  98. BIC r1,r1,#(IRQ_BIT_OR_FIQ_BIT)
  99. MSR CPSR,r1
  100. BX r2 ; Return to calling ISR
  101. ; }
  102. ; else
  103. ; {
  104. TCT_Not_Nested_Save
  105. ; Determine if a thread was interrupted.                                //判断是否进程产生了中断
  106. ; if (TCD_Current_Thread)                                               //如果TCD_Current_Thread是空,则在schedule中因为初始化线程是关中断的
  107. ; {
  108. LDR r1,Current_Thread ; Pickup current thread ptr address
  109. LDR r1,[r1, #0] ; Pickup the current thread pointer
  110. CMP r1,#0 ; Is it NU_NULL?
  111. BEQ TCT_Idle_Context_Save ; If no, no real save is necessary
  112. ; Yes, a thread was interrupted. Save complete context on the
  113. ; thread's stack.
  114. ; 1. Save another register on the exception stack so we have enough to work with
  115. STMDB r13!,{r5}
  116. ; 2. Save the necessary exception registers into r1-r3
  117. MOV r1,r13 ; Put the exception r13 into r1
  118. MOV r2,r14 ; Move the return address for the caller
  119. ; of this function into r2
  120. MRS r3,spsr ; Put the exception spsr into r3
  121. ; 3. Adjust the exception stack pointer for future exceptions
  122. ADD r13,r13,#24 ; r13 will point to enable reg value when done
  123. ; 4. Switch CPU modes to save context on system stack
  124. MRS r5,CPSR ; Pickup the current CPSR
  125. BIC r5,r5,#MODE_MASK ; Clear the mode bits
  126. ORR r5,r5,#SUP_MODE ; Change to supervisor mode (SVD)
  127. MSR CPSR,r5 ; Switch modes (IRQ->SVC)
  128. ; 5. Store the SVC r13 into r5 so the r13 can be saved as is.
  129. MOV r5,r13
  130. ; 6. Save the exception return address on the stack (r15).
  131. STMDB r5!,{r4}
  132. ; 7. Save r6-r14 on stack
  133. STMDB r5!,{r6-r14}
  134. ; 8. Switch back to using r13 now that the original r13 has been saved.
  135. MOV r13,r5
  136. ; 9. Get r5 and exception enable registers off of exception stack and
  137. ; save r5 (stored in r4) back to the system stack.
  138. LDMIA r1!,{r4-r5}
  139. STMDB r13!,{r4}
  140. MOV r4,r5 ; Put exception enable value into r4
  141. ; 10. Get the rest of the registers off the exception stack and
  142. ; save them onto the system stack.
  143. LDMIA r1!,{r5-r8,r11} ; Get r0-r4 off exception stack
  144. STMDB r13!,{r5-r8,r11} ; Put r0-r4 on system stack
  145. ; 11. Store the exception enable value back on the exception stack.
  146. STMDB r1,{r4}
  147. ; 12. Save the SPSR on the system stack (CPSR)
  148. STMDB r13!,{r3}
  149. ; 13. Save stack type to the task stack (1=interrupt stack)
  150. MOV r1,#1 ; Interrupt stack type
  151. STMDB r13!,{r1}
  152. ; Save the thread's stack pointer in the control block.
  153. ; REG_Thread_Ptr = (TC_TCB *) TCD_Current_Thread
  154. ; REG_Thread_Ptr -> tc_stack_pointer = (VOID *) REG_Stack_Ptr
  155. LDR r1,Current_Thread ; Pickup current thread ptr address
  156. LDR r3,[r1, #0] ; Pickup current thread pointer
  157. STR r13,[r3, #TC_STACK_POINTER] ; Save stack pointer
  158. ; Switch to the system stack.
  159. ; REG_Stack_Ptr = TCD_System_Stack
  160. LDR r1,System_Stack ; Pickup address of stack pointer
  161. LDR r3,System_Limit ; Pickup address of stack limit ptr
  162. LDR r13,[r1, #0] ; Switch to system stack
  163. LDR r10,[r3, #0] ; Setup system stack limit
  164. ; Re-enable interrupts
  165. MRS r1,CPSR
  166. BIC r1,r1,#(IRQ_BIT_OR_FIQ_BIT)
  167. MSR CPSR,r1
  168. ; Return to caller ISR.
  169. BX r2 ; Return to caller ISR
  170. ; }
  171. TCT_Idle_Context_Save
  172. MOV r2,r14 ; Save r14 in r2
  173. LDR r3,[r13] ; Get exception enable value from stack
  174. ADD r13,r13,#20 ; Adjust exception r13 for future interrupts
  175. STR r3,[r13] ; Put exception enable value back on stack
  176. MRS r1,CPSR ; Pickup current CPSR
  177. BIC r1,r1,#MODE_MASK ; Clear the current mode
  178. BIC r1,r1,#(IRQ_BIT_OR_FIQ_BIT) ; Re-enable interrupts
  179. ORR r1,r1,#SUP_MODE ; Prepare to switch to supervisor
  180. ; mode (SVC)
  181. MSR CPSR,r1 ; Switch to supervisor mode (SVC)
  182. BX r2 ; Return to caller ISR
  183. ; }
  184. ;}
NU对于中断上下文的保存具体操作如下:
(1)在中断发生后执行的入口函数INT_IRQ()中,将r0-r4保存至irq的栈中
(2)查找到对应的interrupt_shell(),clear中断源,更新全局的中断计数器,然后进行interrupt_contex_save
(3)首先利用r1,r2,r3保存irq模式下的sp,lr,spsr,这里sp是用来切换至系统栈后拷贝lr和spsr的,这里保存lr和spsr是目的是task被抢占后,当再次schedule时可以返回task之前的状态。
(4)切换至SVC模式,如果是非嵌套的中断则保存上下文至task stack中,将irq模式下的lr作为顶端PC的返回值入栈,将SVC模式下的r6-r14入栈,将irq模式下的sp保存至r4中入栈,最后将保存在irq_stack中的r0-r4入栈
(5)如果是嵌套中断,中断的嵌套发生在LISR中,在执行LISR时已经切换至system stack,因此嵌套中断要将中断的上下文保存至system stack中,与task stack中interrupt stack相比只是少了栈顶用来标记嵌套的标志(1 not nested)
(6)有一个分支判断,就是如果当前线程是空,即TCD_Current_Thread == NULL,表明当前是schedule中,因为初始化线程是关中断的,这样就不为schedule线程建立栈帧,因为schedule不需要保存上下文,在restore中断上下文时直接跳转至schedule。

中断上下文的恢复
全局的中断计数器INT_Count是否为0来判定当前出栈的信息,如果是嵌套则返回LISR中,否则切换至system stack执行schedule

nucleus 学习 中断的更多相关文章

  1. nucleus学习

    task的TCB结构: typedef struct TC_TCB_STRUCT { /* Standard thread information first. This information is ...

  2. 【转载-Andrew_qian】stm32中断学习

    [转载]stm32中断学习 中断对于开发嵌入式系统来讲的地位绝对是毋庸置疑的,在C51单片机时代,一共只有5个中断,其中2个外部中断,2个定时/计数器中断和一个串口中断,但是在STM32中,中断数量大 ...

  3. Linux快速学习系列

    这篇文章会随着学习的进行,不断的更新!!! 总结 操作系统引入的抽象概念 进程(process) 地址空间(address space) 虚拟内存(virtual memory) 操作系统引入的cah ...

  4. Nucleus 实时操作系统中断(下)

    Nucleus 实时操作系统中断(下) Nucleus RTOS兼容性 由于中断在Nucleus SE中的实现方式与Nucleus rto截然不同,因此不应期望有特定的兼容性.Nucleus RTOS ...

  5. JUC源码学习笔记3——AQS等待队列和CyclicBarrier,BlockingQueue

    一丶Condition 1.概述 任何一个java对象都拥有一组定义在Object中的监视器方法--wait(),wait(long timeout),notify(),和notifyAll()方法, ...

  6. 20169212《Linux内核原理与分析》第六周作业

    视频学习 一.用户态.内核态和中断 内核态:处于高的执行级别下,代码可以执行特权指令,访问任意的物理地址,这时的CPU就对应内核态 用户态:处于低的执行级别下,代码只能在级别允许的特定范围内活动.在日 ...

  7. system v和posix的共享内存对比 & 共享内存位置

    参考 http://www.startos.com/linux/tips/2011012822078.html 1)Linux和所有的UNIX操作系统都允许通过共享内存在应用程序之间共享存储空间. 2 ...

  8. Protection 5 ---- Priviliege Level Checking 2

    CPU不仅仅在程序访问数据段和堆栈段的时候进行权限级别检查,当程序控制权转换的时候也会进行权限级别检查.程序控制权转换的情况很多,各种情况下检查的方式以及涉及到的检查项都是不同的.这篇文章主要描述了各 ...

  9. MVC5系列——布局视图

    MVC5系列——布局视图 目录 系列文章 概述 布局视图 系列文章 [Asp.net MVC]Asp.net MVC5系列——第一个项目 [Asp.net MVC]Asp.net MVC5系列——添加 ...

随机推荐

  1. ARGB色彩模式

    看到#ff ff ff 00 00这种 就是啦 .开头两位表示透明度.

  2. SpringMvc Filter的使用

    一:Filter过滤器. 先自定义一个过滤器. package com.jbj.filter; import org.springframework.web.filter.OncePerRequest ...

  3. php str_split()函数 语法

    php str_split()函数 语法 str_split()函数怎么用 php str_split()函数用于把字符串分割到数组中,语法是str_split(string,length),将字符串 ...

  4. HDU 6053 TrickGCD —— 2017 Multi-University Training 2

    TrickGCD Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total ...

  5. flutter中的列表组件

    列表布局是我们项目开发中最常用的一种布局方式.Flutter 中我们可以通过 ListView 来定义列表项,支持垂直和水平方向展示.通过一个属性就可以控制列表的显示方向.列表有以下分类:  垂直列表 ...

  6. C# 实现软件注册功能

    相信很多初学编程的人都会对这个注册功能很感兴趣,我也不例外,刚学asp.net时,竞找不到这方面的实例,结果自己参考微软的一些文档自己做了一个,其实我做的这个注册功能很简单,读取计算机的CPU序列号, ...

  7. JDK1.8中ArrayList的实现原理及源码分析

    一.概述 ArrayList是Java开发中使用比较频繁的一个类,通过对源码的解读,可以了解ArrayList的内部结构以及实现方法,清楚它的优缺点,以便我们在编程时灵活运用. 二.源码分析 2.1 ...

  8. (转)Docker 网络

    转:https://www.cnblogs.com/allcloud/p/7150564.html 本系列文章将介绍 Docker的相关知识: (1)Docker 安装及基本用法 (2)Docker ...

  9. JS:收集的一些Array及String原型对象的扩展实现代码

    扩展Array的原型对象的方法  // 删除数组中数据 Array.prototype.del = function(n) { if (n<0) return this; return this ...

  10. Maven 上传文件 Error creating bean with name 'multipartResolver':

    <!--配置MultipartResolver 处理文件上传--><bean id="multipartResolver" class="org.spr ...