• BL808学习日志-0-概念理解


    一、主核心的介绍

            1.三个核心在FREERTOS系统中相互独立,各负责各自的外设和程序;其中M0和LP核心在一个总线上,D0单独在一个总线上,两个总线使用AXI4.0(??)通讯?

    CPU0(M0)-E907架构,320MHz;

    CPU1(LP)-E902架构,160MHz;

    CPU2(D0)-C906架构,480MHz;

            2.CPU0(M0)先启动,然后再启动CPU2(C906),CPU1(e902);相关的代码在博流的SDK中位置如下:/../BOUFFALO_SDK/bsp/board/bl808dk/board.c;

    1. #if defined(CPU_M0)
    2. void board_init(void)
    3. {
    4. int ret = -1;
    5. uintptr_t flag;
    6. flag = bflb_irq_save();
    7. GLB_Halt_CPU(GLB_CORE_ID_D0);
    8. GLB_Halt_CPU(GLB_CORE_ID_LP);
    9. ret = bflb_flash_init();
    10. system_clock_init();
    11. peripheral_clock_init();
    12. bflb_irq_initialize();
    13. console_init();
    14. #ifdef CONFIG_PSRAM
    15. #ifndef CONFIG_PSRAM_COPY_CODE
    16. if (uhs_psram_init() < 0) {
    17. while (1) {
    18. }
    19. }
    20. #endif
    21. #endif
    22. size_t heap_len = ((size_t)&__HeapLimit - (size_t)&__HeapBase);
    23. kmem_init((void *)&__HeapBase, heap_len);
    24. bl_show_log();
    25. if (ret != 0) {
    26. printf("flash init fail!!!\r\n");
    27. }
    28. bl_show_flashinfo();
    29. printf("dynamic memory init success,heap size = %d Kbyte \r\n", ((size_t)&__HeapLimit - (size_t)&__HeapBase) / 1024);
    30. printf("sig1:%08x\r\n", BL_RD_REG(GLB_BASE, GLB_UART_CFG1));
    31. printf("sig2:%08x\r\n", BL_RD_REG(GLB_BASE, GLB_UART_CFG2));
    32. log_start();
    33. #if (defined(CONFIG_LUA) || defined(CONFIG_BFLOG) || defined(CONFIG_FATFS))
    34. rtc = bflb_device_get_by_name("rtc");
    35. #endif
    36. /* set CPU D0 boot XIP address and flash address */
    37. Tzc_Sec_Set_CPU_Group(GLB_CORE_ID_D0, 1);
    38. /* D0 boot from 0x58000000 */
    39. GLB_Set_CPU_Reset_Address(GLB_CORE_ID_D0, 0x58000000);
    40. /* D0 image offset on flash is CONFIG_D0_FLASH_ADDR+0x1000(header) */
    41. bflb_sf_ctrl_set_flash_image_offset(CONFIG_D0_FLASH_ADDR + 0x1000, 1, SF_CTRL_FLASH_BANK0);
    42. Tzc_Sec_Set_CPU_Group(GLB_CORE_ID_LP, 0);
    43. /* LP boot from 0x58020000 */
    44. GLB_Set_CPU_Reset_Address(GLB_CORE_ID_LP, 0x58020000);
    45. bflb_irq_restore(flag);
    46. GLB_Release_CPU(GLB_CORE_ID_D0);
    47. GLB_Release_CPU(GLB_CORE_ID_LP);
    48. /* release d0 and then do can run */
    49. BL_WR_WORD(IPC_SYNC_ADDR1, IPC_SYNC_FLAG);
    50. BL_WR_WORD(IPC_SYNC_ADDR2, IPC_SYNC_FLAG);
    51. L1C_DCache_Clean_By_Addr(IPC_SYNC_ADDR1, 8);
    52. }

    其中按照顺序依次是

    bflb_irq_save();                                                    关闭全局中断;

    GLB_Halt_CPU(GLB_CORE_ID_D0);                关闭D0核心

    GLB_Halt_CPU(GLB_CORE_ID_LP);                关闭LP低功耗核心;

    bflb_flash_init();                                                   初始化FLASH;

    system_clock_init();                                             初始化时钟;

    peripheral_clock_init();                                         初始化外设时钟;

    bflb_irq_initialize();                                               初始化中断;

    console_init();                                                       初始化串口;

    uhs_psram_init();                                                  初始化内置的64M UHS_PSRAM ;

    /* set CPU D0 boot XIP address and flash address */

        Tzc_Sec_Set_CPU_Group(GLB_CORE_ID_D0, 1);

        /* D0 boot from 0x58000000 */

        GLB_Set_CPU_Reset_Address(GLB_CORE_ID_D0, 0x58000000);

        /* D0 image offset on flash is CONFIG_D0_FLASH_ADDR+0x1000(header) */

        bflb_sf_ctrl_set_flash_image_offset(CONFIG_D0_FLASH_ADDR + 0x1000, 1, SF_CTRL_FLASH_BANK0);

        Tzc_Sec_Set_CPU_Group(GLB_CORE_ID_LP, 0);

        /* LP boot from 0x58020000 */

        GLB_Set_CPU_Reset_Address(GLB_CORE_ID_LP, 0x58020000);

        bflb_irq_restore(flag);

        GLB_Release_CPU(GLB_CORE_ID_D0);

        GLB_Release_CPU(GLB_CORE_ID_LP);

        /* release d0 and then do can run */

        BL_WR_WORD(IPC_SYNC_ADDR1, IPC_SYNC_FLAG);

        BL_WR_WORD(IPC_SYNC_ADDR2, IPC_SYNC_FLAG);

        L1C_DCache_Clean_By_Addr(IPC_SYNC_ADDR1, 8);

            3.内存划分,这部分比较抽象,MM内核指的是multi-media内核(手册上多次出现MM前缀的外设,也就是指C906独有的部分),也就是C906(d0)内核,MCU指的就是E907和E902共用的部分;均可使用直接地址访问。

            4.C906的外设只能C906使用;E907(M0)的外设,E902(LP)核心也可以使用(因为他们本来就是在一条AHB总线上的)包括串口和IO之类的;默认的MCU部分有3个串口,UART0、UART1、UART2;C906只有一个串口,在系统中默认编号是UART3;   

            5.XRAM的大小是16K,地址为0x40000000,其设定的意义是让三个核心可以通过这个区域进行IPC通讯;

            每个内核都有一组 IPC 的寄存器,包括 IPCx_TRI、IPCx_STS、IPCx_ACK、IPCx_IEN、IPCx_IDIS、IPCx_ISTS 共 6 个寄存器,这些寄存器的长度都是 32bits,每个 bit 都对应 IPC 的一个通道。核 M0、LP、D0 分别对应 IPC0、IPC1、IPC2。当一个核需要向另一个核发通知时,只需要向接收核的 IPCx_TRI 的对应通道写 1 即可,此时接收核的 IPCx_STS 的对应通道即被设置为 1,如果接收核的 IPC 对应通道的中断也被使能,则会收到一个中断,此时即获知了其他核发来的通知。 

            目前此部分还未做实验,看zhihu上有人实验,D0和M0是可以正常通讯的,好像和LP之间有问题,估计是中断没处理好。地址在这   

            6.coremark测试,使用官方自带的测试例程进行测试,M0的程序可以正常运行,D0的无法正常运行,待修复;已修复,M0实验结果如下:显示为1111,-O3优化,数据放在STACK中;

    1. ____ __ __ _ _ _
    2. | _ \ / _|/ _| | | | | | |
    3. | |_) | ___ _ _| |_| |_ __ _| | ___ | | __ _| |__
    4. | _ < / _ \| | | | _| _/ _` | |/ _ \| |/ _` | '_ \
    5. | |_) | (_) | |_| | | | || (_| | | (_) | | (_| | |_) |
    6. |____/ \___/ \__,_|_| |_| \__,_|_|\___/|_|\__,_|_.__/
    7. Build:13:43:42,Sep 29 2023
    8. Copyright (c) 2022 Bouffalolab team
    9. ======== flash cfg ========
    10. flash size 0x01000000
    11. jedec id 0xEF4018
    12. mid 0xEF
    13. iomode 0x04
    14. clk delay 0x01
    15. clk invert 0x01
    16. read reg cmd0 0x05
    17. read reg cmd1 0x35
    18. write reg cmd0 0x01
    19. write reg cmd1 0x31
    20. qe write len 0x01
    21. cread support 0x00
    22. cread code 0xFF
    23. burst wrap cmd 0x77
    24. ===========================
    25. dynamic memory init success,heap size = 21 Kbyte
    26. sig1:ffff32ff
    27. sig2:0000ffff
    28. Benchmark started, please make sure it runs for at least 10s.
    29. Now PC=58014b88
    30. 2K performance run parameters for coremark.
    31. CoreMark Size : 666
    32. Total ticks : 18067
    33. Total time (secs): 18
    34. Iterations/Sec : 1111
    35. Iterations : 20000
    36. Compiler version : GCC10.2.0
    37. Compiler flags : -O3
    38. Memory location : STACK
    39. seedcrc : 0xe9f5
    40. [0]crclist : 0xe714
    41. [0]crcmatrix : 0x1fd7
    42. [0]crcstate : 0x8e3a
    43. [0]crcfinal : 0x382f
    44. Correct operation validated. See readme.txt for run and reporting rules.
    45. CoreMark 1.0 : 1111 / GCC10.2.0 -O3 / STACK

      D0由于代码有问题,测试结果可能有问题,显示为1666,

    1. ____ __ __ _ _ _
    2. | _ \ / _|/ _| | | | | | |
    3. | |_) | ___ _ _| |_| |_ __ _| | ___ | | __ _| |__
    4. | _ < / _ \| | | | _| _/ _` | |/ _ \| |/ _` | '_ \
    5. | |_) | (_) | |_| | | | || (_| | | (_) | | (_| | |_) |
    6. |____/ \___/ \__,_|_| |_| \__,_|_|\___/|_|\__,_|_.__/
    7. Build:20:01:44,Sep 29 2023
    8. Copyright (c) 2022 Bouffalolab team
    9. dynamic memory init success,heap size = 59 Kbyte
    10. sig1:ffff32ff
    11. sig2:0000ffff
    12. cgen1:9f7ffffd
    13. Benchmark started, please make sure it runs for at least 10s.
    14. Now PC=580104c2
    15. 2K performance run parameters for coremark.
    16. CoreMark Size : 666
    17. Total ticks : 12240
    18. Total time (secs): 12
    19. Iterations/Sec : 1666
    20. Iterations : 20000
    21. Compiler version : GCC10.2.0
    22. Compiler flags : -O3
    23. Memory location : Stack
    24. seedcrc : 0xe9f5
    25. [0]crclist : 0xe714
    26. [0]crcmatrix : 0x1fd7
    27. [0]crcstate : 0x8e3a
    28. [0]crcfinal : 0x382f
    29. Correct operation validated. See readme.txt for run and reporting rules.
    30. CoreMark 1.0 : 1666 / GCC10.2.0 -O3 / Stack

    LP的coremark暂时没搞定,跑出来只有2分,不确定是内存不足还是什么情况。

    1. ____ __ __ _ _ _
    2. | _ \ / _|/ _| | | | | | |
    3. | |_) | ___ _ _| |_| |_ __ _| | ___ | | __ _| |__
    4. | _ < / _ \| | | | _| _/ _` | |/ _ \| |/ _` | '_ \
    5. | |_) | (_) | |_| | | | || (_| | | (_) | | (_| | |_) |
    6. |____/ \___/ \__,_|_| |_| \__,_|_|\___/|_|\__,_|_.__/
    7. Build:15:26:15,Sep 29 2023
    8. Copyright (c) 2022 Bouffalolab team
    9. lp does not use memheap due to little ram
    10. sig1:32ff76ff
    11. sig2:0000ffff
    12. cgen1:9f7ffffd
    13. Benchmark started, please make sure it runs for at least 10s.
    14. Now PC=580349bc
    15. 2K performance run parameters for coremark.
    16. CoreMark Size : 666
    17. Total ticks : 15729
    18. Total time (secs): 15
    19. Iterations/Sec : 2
    20. Iterations : 30
    21. Compiler version : GCC10.2.0
    22. Compiler flags : -O3
    23. Memory location : STACK
    24. seedcrc : 0xe9f5
    25. [0]crclist : 0xe714
    26. [0]crcmatrix : 0x1fd7
    27. [0]crcstate : 0x8e3a
    28. [0]crcfinal : 0xf8b3
    29. Correct operation validated. See readme.txt for run and reporting rules.
    30. CoreMark 1.0 : 2 / GCC10.2.0 -O3 / STACK

       二、应用例程探究                  

            看到好多网络上的例程和官方例程,这里着重写几个有意思的;

            1、模拟GBA游戏机

            例程来源于这里,在这位的基础上增加了一个简单的查看FPS的小功能,其实官方仓库都有;这里做一个对比:ESP32-S3 在分辨率是256*160跳帧为1的情况下是20帧,我测试的BL808的C906在400Mhz,256*160分辨率下是33-37帧。而且后面的日志显示,此时C906主频为400Mhz;

    NameTested hardwarePerformanceNotes
    ESP32-S3ESP32-S3-WROOM-1-N8R820 fpsframeskip: 1
    SDL2AMD 3800X1800 fps
    SDL2Switch314 fps
    SDL2Apple M12300 fps
    SDL2Vita131 fpsframeskip: 1, overclocked
    SDL1New 3DS111 fpsframeskip: 1, overclocked
    watchOSApple Watch Series 5451 fpsNot public yet
    BL808_D0SIPEED M1S_DOCK33fps

            只需要按照原作者的文件,并进行一点点修改就行,增加两个freertos的头文件,增加一个时间获取的函数,计算一下生成120帧的时间,进行FPS平均值统计,结果是33-35FPS;看来对比ESP32-S3还是有点优势的,coremark从ESP32-S3的单核613,提升到BL808_D0的单核1666。

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include "gba.h"
    6. #include "globals.h"
    7. #include "memory.h"
    8. #include "sound.h"
    9. /* aos */
    10. #include
    11. #include
    12. extern "C" {
    13. #include "lcd.h"
    14. #include
    15. #include
    16. }
    17. uint16_t lcd_buff[256 * 160];
    18. uint8_t frameDrawn = 0;
    19. uint32_t frameCount = 0;
    20. void systemDrawScreen(void)
    21. {
    22. frameDrawn = 1;
    23. uint16_t *src = pix;
    24. uint16_t *dst = lcd_buff;
    25. for (int y = 0; y < 160; y++)
    26. {
    27. for (int x = 0; x < 256; x++)
    28. {
    29. *dst++ = __builtin_bswap16(*src++);
    30. }
    31. }
    32. st7789v_spi_draw_picture_blocking(20, 40, 20+256-1, 40+160-1, lcd_buff);
    33. }
    34. void systemOnWriteDataToSoundBuffer(int16_t *finalWave, int length) {}
    35. void systemMessage(const char *fmt, ...)
    36. {
    37. char buf[256];
    38. va_list args;
    39. va_start(args, fmt);
    40. vsnprintf(buf, sizeof(buf), fmt, args);
    41. va_end(args);
    42. printf("GBA: %s", buf);
    43. }
    44. extern "C" {
    45. extern uint32_t bl808_key_read();
    46. void emuMainLoop()
    47. {
    48. int fd = -1;
    49. fd = aos_open("/flash/goodBoyAdv.gba", 0);
    50. if(fd >= 0)
    51. {
    52. int model_bin_len = 0;
    53. model_bin_len = aos_lseek(fd, 0, SEEK_END);
    54. aos_lseek(fd, 0, SEEK_SET);
    55. aos_read(fd, rom, model_bin_len);
    56. aos_close(fd);
    57. }
    58. CPUSetupBuffers();
    59. CPUInit(NULL, false);
    60. CPUReset();
    61. int prevTimeStamp = 0;
    62. TickType_t fpsTick = xTaskGetTickCount();
    63. while (1)
    64. {
    65. joy = bl808_key_read();
    66. UpdateJoypad();
    67. frameDrawn = 0;
    68. while (!frameDrawn)
    69. {
    70. CPULoop();
    71. }
    72. frameCount++;
    73. if (frameCount % 120 == 0) {
    74. TickType_t now = xTaskGetTickCount();
    75. int msPassed = (now - fpsTick) * portTICK_PERIOD_MS;
    76. fpsTick = now;
    77. int fps = 120 * 1000 / msPassed;
    78. printf("FPS: %d\r\n", fps);
    79. }
    80. }
    81. }
    82. }
    1. Starting bl808 now....
    2. Heap Info: 29819 KB @ [0x0x00000000522e10f8 ~ 0x0x0000000054000000]
    3. [OS] Starting aos_loop_proc task...
    4. [OS] Start c906 xram handle...
    5. [OS] Starting OS Scheduler...
    6. init ring:0,tx:0x0000000022020140,rx:0x0000000000000000
    7. init ring:2,tx:0x0000000022021340,rx:0x0000000022020340
    8. init ring:3,tx:0x0000000022022540,rx:0x0000000022022340
    9. init ring:4,tx:0x0000000022022840,rx:0x0000000022022740
    10. init ring:5,tx:0x0000000000000000,rx:0x0000000000000000
    11. Init CLI with event Driven
    12. FPS: 36
    13. FPS: 37
    14. FPS: 36
    15. FPS: 37
    16. FPS: 37
    17. FPS: 36
    18. FPS: 37
    19. FPS: 37
    20. FPS: 36
    21. FPS: 37
    22. FPS: 36
    23. FPS: 36
    24. FPS: 36
    25. FPS: 34
    26. FPS: 35
    27. FPS: 34
    28. FPS: 34
    29. FPS: 35
    30. FPS: 35
    31. FPS: 34
    32. FPS: 35
    33. FPS: 34
    34. FPS: 34
    35. FPS: 35

  • 相关阅读:
    threejs视频教程学习(5):水天一色小岛
    使用Java操作Redis
    一面数据: Hadoop 迁移云上架构设计与实践
    转转“拯救世界”的第一步,师从小米换LOGO?
    MODBUS转PROFINET网关将电力智能监控仪表接入PROFINET网络案例
    QT6不支持QDesktopWidget包含头文件报错Qt 获取设备屏幕大小
    Acwing算法基础学习笔记(二)二分
    Mybatis篇
    记录uniapp切换主题色能在抖音小程序上无效问题
    C++~从编译链接的过程看为什么C++支持重载?externC有什么用?
  • 原文地址:https://blog.csdn.net/DINGDING_GO/article/details/133411947