5iMX宗旨:分享遥控模型兴趣爱好

5iMX.com 我爱模型 玩家论坛 ——专业遥控模型和无人机玩家论坛(玩模型就上我爱模型,创始于2003年)
查看: 15134|回复: 60
打印 上一主题 下一主题

BLHeli_S 源码解析讨论

[复制链接]
跳转到指定楼层
楼主
发表于 2016-10-22 16:41 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 逗倪豌儿 于 2016-10-24 09:32 编辑

# 1.时钟配置说明 #

对每次 FLASH 读或取指操作,系统为 FLASH存储器提供一个内部 FLASH 读选通信号。FLASH读选通信号持续一或两个系统时钟周期,由 FLRT(PFE0CN.4)决定。如果系统时钟大于 25 MHz,则 FLRT 位必须被设置为逻辑 1,否则,从 FLASH读取的数据或指令不是实际的 FLASH内容。

更新 FLRT步骤如下

- 第一步:设置SFRPAGE地址为 PFE0CN页地址(0X10) 即 mov SFRPAGE, #10h
- 第二步:

         如果系统时钟SYSCLK小于等于25M 则
                         禁止指令预取引擎(PFE0CN寄存器中的 PFEN位清 0),设置  PFE0CN.5 = 0
                         FLASH读选通信号为一个系统时钟                   设置 PFE0CN.4 = 0  即mov SFRPAGE, #10h

         如果系统时钟SYSCLK大于 25 MH 则
                         使能指令预取引擎(PFE0CN寄存器中的 PFEN位清 0),设置  PFE0CN.5 = 1
                         FLASH读选通信号为两个系统时钟                   设置 PFE0CN.4 = 1 即mov PFE0CN, #30h

- 第三步:设置 SFRPAGE页地址为 00H。即 mov SFRPAGE, #00h

所以时钟配置程序如下 :
  1.     ;****************************** 设置系统时钟为24M *****************************
  2.     ;
  3.     ; 1:时钟源为 HFOSC1 (48M)  ,然后配置为 2分频
  4.     ; 2
  5.     ;
  6.     ;*****************************************************************************
  7.     Set_MCU_Clk_24MHz MACRO
  8.     mov CLKSEL, #13h; Set clock to 24MHz
  9.     mov SFRPAGE, #10h
  10.     mov PFE0CN, #00h; Set flash timing for 24MHz
  11.     mov SFRPAGE, #00h
  12.     mov Clock_Set_At_48MHz, #0
  13.     ENDM
复制代码
  1.    ;****************************** 设置系统时钟为48M *****************************
  2.     ;
  3.     ; 1:时钟源为 HFOSC1 (48M) SYSCLK 为  clock source(原时钟的1分频)
  4.     ; 1:
  5.     ;
  6.     ;*****************************************************************************
  7.     Set_MCU_Clk_48MHz MACRO
  8.     mov SFRPAGE, #10h
  9.     mov PFE0CN, #30h; Set flash timing for 48MHz
  10.     mov SFRPAGE, #00h
  11.     mov CLKSEL, #03h; Set clock to 48MHz
  12.     mov Clock_Set_At_48MHz, #1
  13.     ENDM
复制代码

##  1.1页寄存器使用说明  ##

你所用的每个寄存器都有个寄存地址,而寄存器页的页码就是指向你的寄存地址的。当你需要使用某个寄存器时,就必须把SFRPAGE指向你所要用的寄存器页上面去
举例如下:
  1.     void Init_ADC0()

  2.     {

  3.      char SFRPAGE_SAVE = SFRPAGE;  // 保存当前的SFR页

  4.      SFRPAGE = ADC0_PAGE;          //把页码改到以下几个寄存器所在的页码

  5.      ADC0CN = 0x00;                // 每次向AD0BUSY 写1 时启动ADC0 转换

  6.      REF0CN = 0x03;                // ADC0电压基准取自VREF0引脚,内部电压基准缓冲器工作

  7.      AMX0CF = 0x00;                // AIN inputs are single-ended (default)

  8.      AMX0SL = 0x00;                // 选择ADC 输入为AIN0.0   

  9.                                   // ADC0CF = (SYSCLK/SAR_CLK) << 3; // ADC 转换时钟 = 2.5MHz

  10.      ADC0CF |= 0x00;  // PGA 增益 = 1 (默认)

  11.                                   // EIE2 |= 0x02;   // 允许ADC0 转换结束中断

  12.      SFRPAGE = SFRPAGE_SAVE;      //回复寄存器页

  13.     }
复制代码



这个程序中char SFRPAGE_SAVE = SFRPAGE; 和  SFRPAGE = SFRPAGE_SAVE; 是使在调用这个子函数后页码能够回到调用前的页码

----------

# 2.脉冲捕获--获取油门值说明 (Get_Rcp_Capture_Values) #
函数说明

- 1:脉冲捕获使用定时器0,计数周期 41.67ns;
- 2:该函数是在定时器 0中断中执行。

操作步骤如下:

- 1:关闭定时器0
- 2:保存计数值 Temp1 = TL0  Temp2 = TH0  Temp3 = Timer0_X (该值在定时器0中断中被自加)
- 3:如果定时器0和其他的中断同时产生了,那么定时器0会被挂起,如果被挂起则把Temp3++, 否则 Temp3 保持原来的值
- 4:把定时器0 计数器清0 即TL0 =0 TH0 = 0
- 5:把 Timer0_X 清零,即 Timer0_X = 0
- 6:从新使能定时器 0
- 7: 如果48M Temp1 = Temp1 *2  Temp2 = Temp2 *2  Temp3 = Temp3 *2,如果不是 Temp1 Temp2 Temp3 保持原有值

该函数的作用是读取脉冲捕获的计数器值 参数返回放到 Temp1 和 Temp2 中


----------

# 3. PCA初始化函数说明 -- Initialize_PCA #
  说明:

-  1: 使能PCA0
-  2: PCA0时钟选择系统时钟
-  3: 如果延时为0  如果48M,则设置PCA0为11位PWM  ,否则设置为10位模式 ,设置PWM 边沿对齐
-  4: 如果延时不为0 如果48M 则设置PCA0为10位PWM  ,否则设置为9位模式 , 设置PWM 中间对齐

----------

# 4.上电PWM模式设置--Enable_Power_Pwm_Module #

说明:

1. 如果延时为0 使能比较器CPM0,使能匹配功能,  使能PCA为PWM模式
2. 如果延时为0 使能比较器CPM0, 禁能匹配功能, 使能PCA为PWM模式

代码如下 :
  1.   Enable_Power_Pwm_Module MACRO
  2.     IF FETON_DELAY == 0
  3.             mov PCA0CPM0, #4Ah  ; Enable comparator of module, enable match, set pwm mode
  4.     ELSE
  5.             mov PCA0CPM0, #42h  ; Enable comparator of module, set pwm mode
  6.     ENDIF
  7.     ENDM
复制代码
----------

# ADC 初始化函数 -- Initialize_Adc #


说明:设置采样频率为 2M

-  1:设置VDD作为电压基准,使能内部温度传感器
-  2:设置ADC转换clk =  PCLK/(REF0CN >>3 -1) ,所以,

                  如果是48M 则48/ (B9H >>3 -1)= 2.18M
                如果是24M 则24/ (59h >>3 -1)= 2.4M

-  3:设置ADC增益为 1倍

代码如下 :

  1. Initialize_Adc MACRO
  2.             mov REF0CN, #0Ch; Set vdd (3.3V) as reference. Enable temp sensor and bias
  3.     IF MCU_48MHZ == 0
  4.             mov ADC0CF, #59h; ADC clock 2MHz, PGA gain 1
  5.     ELSE
  6.             mov ADC0CF, #0B9h   ; ADC clock 2MHz, PGA gain 1
  7.     ENDIF
  8.             mov ADC0MX, #10h; Select temp sensor input
  9.             mov ADC0CN0, #80h   ; ADC enabled
  10.             mov ADC0CN1, #01h   ; Common mode buffer enabled
  11.     ENDM
复制代码



欢迎继续阅读楼主其他信息

主题

  • 没有相关信息
  • 没有相关信息
  • 没有相关信息
沙发
 楼主| 发表于 2016-10-22 16:44 | 只看该作者
本帖最后由 逗倪豌儿 于 2016-10-24 09:33 编辑

定时器资源使用如下 :

1. 定时器 0 : 定时周期41.67ns, 用于RC;
2. 定时器 2 : 定时周期500ns,   用于RC 和换向时间;
3. 定时器 3 : 定时周期500ns,   用于换向时间;
4. PCA0    : 用于硬件PWM ;

# 定时器0中断服务函数说明 -- t0_int #

- 1.清除定时器中断标志
- 2.Timer0_X ++

代码如下 :

  1.     IF MCU_48MHZ == 1
  2.             t0_int:
  3.     clr TCON_TF0; Clear interrupt flag
  4.             inc Timer0_X
  5.     reti
  6.     ENDIF
复制代码


# 定时器2中断服务函数说明 -- t2_int #

说明 :

1. 保护现场
2. 清除中断标志位
3. Timer2_X ++
4. Skip_T2_Int 取反
5. 如果 Rcp_Timeout_Cntd =0 即RC脉冲超时计数如果为0 则退出中断,恢复现场,否则 Rcp_Timeout_Cntd --

代码如下 :

  1.    t2_int: ; Happens every 32ms
  2.             push        PSW                 ; Preserve registers through interrupt
  3.             push        ACC
  4.             clr TMR2CN0_TF2H        ; Clear interrupt flag
  5.             inc Timer2_X
  6.     IF MCU_48MHZ == 1
  7.             mov A, Clock_Set_At_48MHz
  8.             jz  t2_int_start         ;24MHz 跳转 t2_int_start
  9.                                                      ;48MHz往下执行
  10.                                                            ; Check skip variable
  11.             mov A, Skip_T2_Int
  12.                    jz  t2_int_start; Execute this interrupt
  13.                                                     ; Skip_T2_Int =0 跳转 t2_int_start (把Skip_T2_Int 置 1)
  14.                                                     ; 否则往下执行
  15.             mov Skip_T2_Int, #0 ; Skip_T2_Int = 0
  16.             ajmpt2_int_exit ;

  17.     t2_int_start:
  18.                    mov Skip_T2_Int, #1 ; Skip next interrupt
  19.     ENDIF

  20.     ; Update RC pulse timeout counter
  21.             mov A, Rcp_Timeout_Cntd ; RC pulse timeout count zero?
  22.     jz  t2_int_exit                 ; Yes - do not decrement

  23.             dec Rcp_Timeout_Cntd; No decrement

  24.     t2_int_exit:
  25.             pop ACC                         ; Restore preserved registers
  26.             pop PSW
  27.     reti
复制代码


# 定时器3中断服务函数 -- t3_int #

说明:

- 1:关闭所有中断
- 2:给定时器3的计数器赋值,下次进中断设置个短的延时
- 3:清除Flags0.T3_PENDING 标志
- 4:清除 定时器3的中断标志 TMR3CN0
- 5:打开所有的中断

代码如下 :

  
  1. t3_int: ; Used for commutation timing
  2.             clr IE_EA                           ; Disable all interrupts
  3.             anl EIE1, #7Fh                  ; Disable timer3 interrupts
  4.             mov TMR3RLL, #0FAh          ; Set a short delay before next interrupt
  5.             mov TMR3RLH, #0FFh
  6.             clr Flags0.T3_PENDING   ; Flag that timer has wrapped
  7.             anl TMR3CN0, #07Fh          ; Timer3 interrupt flag cleared
  8.             setb IE_EA                           ; Enable all interrupts
  9.     reti
复制代码



3
 楼主| 发表于 2016-10-22 16:44 | 只看该作者
本帖最后由 逗倪豌儿 于 2016-10-24 09:33 编辑

# 默认参数加载函数 -- set_default_parameters #

----------


说明 :

     从_Pgm_Gov_P_Gain 地址开始 每一个字节存一个变量

           参数地址                   默认参数                                  参数意义
        _Pgm_Gov_P_Gain            0FFh                                     P 参数
        _Pgm_Gov_P_Gain + 1        0FFh                                     I 参数
        _Pgm_Gov_P_Gain + 2        0FFh                                     Governor mode 调节模式
        _Pgm_Gov_P_Gain + 3        0FFh                                     Low voltage limit 低压限制值
        _Pgm_Gov_P_Gain + 4       0FFh                                                       Multi gain
        _Pgm_Gov_P_Gain + 5       0FFh                                                     保留
        _Pgm_Gov_P_Gain + 6       DEFAULT_PGM_STARTUP_PWR               
        _Pgm_Gov_P_Gain + 7       0FFh                                                     Pwm freq PWM频率
        _Pgm_Gov_P_Gain + 8       DEFAULT_PGM_DIRECTION

        从 Pgm_Enable_TX_Program 地址开始 每一个字节存一个变量

           参数地址                          默认参数                                参数意义

        Pgm_Enable_TX_Program            DEFAULT_PGM_ENABLE_TX_PROGRAM            
        Pgm_Enable_TX_Program + 1        0FFh                                             Main rearm start
        Pgm_Enable_TX_Program + 2        0FFh                                             Governor setup target
        Pgm_Enable_TX_Program + 3        0FFh                                             Startup rpm
        Pgm_Enable_TX_Program + 4       0FFh                                             Startup accel
        Pgm_Enable_TX_Program + 5       0FFh                                             Voltage comp
        Pgm_Enable_TX_Program + 6       DEFAULT_PGM_COMM_TIMING               
        Pgm_Enable_TX_Program + 7       0FFh                                             Damping force
        Pgm_Enable_TX_Program + 8       0FFh                                             Governor range      
        Pgm_Enable_TX_Program + 9       0FFh                                             Startup method
        Pgm_Enable_TX_Program + A       DEFAULT_PGM_MIN_THROTTLE         
        Pgm_Enable_TX_Program + B       DEFAULT_PGM_MAX_THROTTLE            
        Pgm_Enable_TX_Program + C       DEFAULT_PGM_BEEP_STRENGTH                           
        Pgm_Enable_TX_Program + D       DEFAULT_PGM_BEACON_STRENGTH                           
        Pgm_Enable_TX_Program + E       DEFAULT_PGM_BEACON_DELAY                           
        Pgm_Enable_TX_Program + F       0FFh                                            Throttle rate      
        Pgm_Enable_TX_Program + 10h       DEFAULT_PGM_DEMAG_COMP                           
        Pgm_Enable_TX_Program + 11h       0FFh                                            Bec voltage high      
        Pgm_Enable_TX_Program + 12h       DEFAULT_PGM_CENTER_THROTTLE                           
        Pgm_Enable_TX_Program + 13h       0FFh                                       保留   
        Pgm_Enable_TX_Program + 14h       DEFAULT_PGM_ENABLE_TEMP_PROT                           
        Pgm_Enable_TX_Program + 15h       DEFAULT_PGM_ENABLE_POWER_PROT                           
        Pgm_Enable_TX_Program + 16h       0FFh                                            Enable pwm input     
        Pgm_Enable_TX_Program + 17h       0FFh                                            Pwm dither      
        Pgm_Enable_TX_Program + 18h       DEFAULT_PGM_BRAKE_ON_STOP                           
        Pgm_Enable_TX_Program + 19h       DEFAULT_PGM_LED_CONTROL  




# 读取全部eeprom函数: read_all_eeprom_parameters #

执行过程 :

从 Eep_Initialized_L 所代表的地址中读取数据dataL放到 Bit_Access所代表的地址中 ,

  如果 读到数据dataL == 055h

                把 Eep_Initialized_L +1 所代表的地址中的数据读取出来dataH,放到   Bit_Access所代表的地址中,此时
             如果 dataH  ==0AAh 则调用read_eeprom_read函数,读取 eeprom中的数据;
             如果 dataH  != 0AAh 则调用 read_eeprom_store_defaults函数 ,读取默认的eeprom中的数据
  如果 读到数据dataL != 055h

                则调用 read_eeprom_store_defaults函数 ,读取默认的eeprom中的数据

总结 :如果 [Eep_Initialized_L] = 055h 且 [Eep_Initialized_L +1] = 0AAh 才能调用read_eeprom_read函数,读取 eeprom中的数据;否则会调用 read_eeprom_store_defaults函数 ,读取默认的eeprom中的数据,

# 延时函数#

----------
执行一次是 42.7us  内环是 23 * 42.7 us = 982.1us = 1ms
所以 Temp2的值决定着 要延时多少ms eg : wait30ms中 要把 Temp2 = 30

  
  1. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  2.     ;
  3.     ; Wait xms ~(x*4*250)  (Different entry points)
  4.     ;
  5.     ; No assumptions
  6.     ;
  7.     ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  8.     wait1ms:
  9.             mov         Temp2, #1
  10.             jmp                 waitxms_o

  11.     wait3ms:
  12.             mov         Temp2, #3
  13.             jmp         waitxms_o

  14.     wait10ms:   
  15.             mov         Temp2, #10
  16.             jmp         waitxms_o

  17.     wait30ms:   
  18.             mov         Temp2, #30
  19.             jmp         waitxms_o

  20.     wait100ms:  
  21.             mov         Temp2, #100
  22.             jmp         waitxms_o

  23.     wait200ms:  
  24.             mov         Temp2, #200
  25.             jmp         waitxms_o

  26.     waitxms_o:  ; Outer loop
  27.             mov         Temp1, #23
  28.     waitxms_m:  ; Middle loop
  29.             clr         A
  30.             djnz        ACC, [        DISCUZ_CODE_0        ]nbsp; ; Inner loop (42.7us - 1024 cycles)
  31.             djnz        Temp1, waitxms_m
  32.             djnz        Temp2, waitxms_o

  33.     ret
复制代码


# pgm_start 函数 #

1. 初始化 Flash_Key_1和Flash_Key_2为 0
2. 禁能看门口
3. 初始化栈大小
4. 使能VDD电压监视器
5. 如果 是1s电池 不把VDD电压监视器设置为系统复位源,否则设置为系统复位源
6. 选择内部震荡器为系统时钟源
7. 关闭所有的MOS管和PWM输出
8. 初始化 所有IO
9. 初始化交叉开关
10. 再次关闭所有的MOS管和PWM输出
11. 清除RAM
12. 执行设置默认参数到内存中
13. 执行从eeprom中读取参数
14. 取出Pgm_Beep_Strength地址中的数据 放到Beep_Strength中
15. 把 Initial_Arm位置1
16. 禁能所有中断,
17. 发声处理
18. 执行led控制

代码如下 :

      
  1. pgm_start:
  2.             ; Initialize flash keys to invalid values
  3.             mov Flash_Key_1, #0
  4.             mov Flash_Key_2, #0
  5.             ; Disable the WDT.
  6.             mov WDTCN, #0DEh        ; Disable watchdog
  7.             mov WDTCN, #0ADh        
  8.             ; Initialize stack
  9.             mov SP, #0c0h           ; Stack = 64 upper bytes of RAM
  10.             ; Initialize VDD monitor
  11.             orl VDM0CN, #080h       ; Enable the VDD monitor
  12.         IF ONE_S_CAPABLE == 0      
  13.             mov     RSTSRC, #06h    ; Set missing clock and VDD monitor as a reset source if not 1S capable
  14.         ELSE
  15.             mov     RSTSRC, #04h    ; Do not set VDD monitor as a reset source for 1S ESCSs, in order to avoid resets due to it
  16.         ENDIF
  17.             ; Set clock frequency
  18.             mov CLKSEL, #00h        ; Set clock divider to 1
  19.             ; Switch power off
  20.             call    switch_power_off
  21.             ; Ports initialization
  22.             mov P0, #P0_INIT
  23.             mov P0MDIN, #P0_DIGITAL
  24.             mov P0MDOUT, #P0_PUSHPULL
  25.             mov P0, #P0_INIT
  26.             mov P0SKIP, #P0_SKIP               
  27.             mov P1, #P1_INIT
  28.             mov P1MDIN, #P1_DIGITAL
  29.             mov P1MDOUT, #P1_PUSHPULL
  30.             mov P1, #P1_INIT
  31.             mov P1SKIP, #P1_SKIP               
  32.             mov P2MDOUT, #P2_PUSHPULL               
  33.             ; Initialize the XBAR and related functionality
  34.             Initialize_Xbar
  35.             ; Switch power off again, after initializing ports
  36.             call    switch_power_off
  37.             ; Clear RAM
  38.             clr A               ; Clear accumulator
  39.             mov Temp1, A            ; Clear Temp1
  40.             clear_ram:  
  41.             mov @Temp1, A           ; Clear RAM
  42.             djnz Temp1, clear_ram   ; Is A not zero? - jump
  43.             ; Set default programmed parameters
  44.             call    set_default_parameters
  45.             ; Read all programmed parameters
  46.             call read_all_eeprom_parameters
  47.             ; Set beep strength
  48.             mov Temp1, #Pgm_Beep_Strength
  49.             mov Beep_Strength, @Temp1
  50.             ; Set initial arm variable
  51.             mov Initial_Arm, #1
  52.             ; Initializing beep
  53.             clr IE_EA           ; Disable interrupts explicitly
  54.             call wait200ms  
  55.             call beep_f1
  56.             call wait30ms
  57.             call beep_f2
  58.             call wait30ms
  59.             call beep_f3
  60.             call wait30ms
  61.             call    led_control
复制代码



4
 楼主| 发表于 2016-10-22 16:45 | 只看该作者
本帖最后由 逗倪豌儿 于 2016-10-24 09:21 编辑

# 外部中断0 服务函数 -- int0_int #
----------
说明:

-         1:禁能所有中断
-         2:禁能PCA中断
-         3:保护现场
-         4:置位 PSW.3,设置为 工作寄存器为Bank1 即  08H-0FH
-         5:打开所有的中断
-         6: 获取脉冲计数值
-         7:根据初始化参数 Flags2.RCP_MULTISHOT,决定是否初执行        int0_int_fall_not_multishot 函数
-         8: Temp3 =  Temp2.L Temp1.H
       9: 接下来就是无论哪种油门模式,都把转换为1000us 到2000us 然后把相应的油门模式置位,

5
 楼主| 发表于 2016-10-22 16:46 | 只看该作者

附件是KEIL 编译BLHeli_S的说明文档,和原理图,欢迎拍砖

本帖最后由 逗倪豌儿 于 2016-12-26 15:06 编辑

百度云附件:BLHeli_S最小系统原理图.PDF等   
6
 楼主| 发表于 2016-10-22 16:46 | 只看该作者
占楼编辑
7
 楼主| 发表于 2016-10-22 16:47 | 只看该作者
欢迎大家一起学,有什么问题可以一起讨论  后期会更新。。。。
8
发表于 2016-10-22 18:32 | 只看该作者
9
发表于 2016-10-22 18:37 | 只看该作者
高端大气,看不懂……
来自苹果客户端来自苹果客户端
10
发表于 2016-10-22 19:08 | 只看该作者
占楼编辑
11
发表于 2016-10-22 21:22 | 只看该作者
虽然看不懂但是感觉确实高大上

12
发表于 2016-10-23 06:36 | 只看该作者
仰望高端玩家。。。我就一点没看懂
13
发表于 2016-10-23 09:40 | 只看该作者
好奇bl原作者干什么的,能写出这么好的电调软件 开源 且长期更新
来自苹果客户端来自苹果客户端
14
发表于 2016-10-24 01:57 | 只看该作者
老外流行开源,人人为我,我为人人的精神是国人很难理解的。

此外BB1和BB2的主频分别为24.5MHz和49MHz
15
发表于 2016-10-24 01:59 | 只看该作者
看不懂啊.....
来自安卓客户端来自安卓客户端
16
 楼主| 发表于 2016-10-24 09:06 | 只看该作者
盒子炮 发表于 2016-10-22 18:37
高端大气,看不懂……

这只是BLHeli_S最新源码的程序,我只是看着程序,对着MCU手册,注释下源码,方便有些人学习BLHeli源码,大家一起完善,有什么关于代码不懂的都可以发帖讨论

17
 楼主| 发表于 2016-10-24 09:27 | 只看该作者
阳光哥 发表于 2016-10-23 09:40
好奇bl原作者干什么的,能写出这么好的电调软件 开源 且长期更新

原作者是Steffen Skaug,传说中的S君, 我大华府的开源精神和老外和还是........,你懂的!

18
 楼主| 发表于 2016-10-24 09:30 | 只看该作者
风中老长 发表于 2016-10-24 01:57
老外流行开源,人人为我,我为人人的精神是国人很难理解的。

此外BB1和BB2的主频分别为24.5MHz和49MHz

BB2 48M ,差不了几个钱,直接上BB2 mcu 存储大,易于后续二次开发。

19
发表于 2016-10-24 21:30 | 只看该作者
挺你一下。

这个帖子最好标明你的BLS软件版本号。
此外根据不同文件分别分析源码是否会好点?
20
发表于 2016-10-29 01:06 | 只看该作者
BLS 比BL有啥优势啊?
您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

关闭

【站内推荐】上一条 /1 下一条

快速回复 返回顶部 返回列表