四&五、从0开始卷出一个新项目之瑞萨RA6M5 boot&app源码分析

七、软件设计

    7.2 源码分析

        7.2.1 框图

        7.2.2 boot源码

                7.2.2.1 boot源码分析

                7.2.2.12 boot测试效果

        7.2.3 app源码

                7.2.3.1 app源码分析

                7.2.3.12 boot+app测试效果

四、从0开始卷出一个新项目之瑞萨RA6M5 boot源码分析

五、从0开始卷出一个新项目之瑞萨RA6M5 app源码分析

7.2 源码分析

7.2.1 框图

7.2.2 boot源码
7.2.2.1 boot源码分析

boot中只有一个线程
//jump,跳转前关闭外设,关闭中断,注意带rtos需要的处理
do_boot(Boot_Addr);
如果不需要通过网络升级固件,则不添加网络协议栈,可用串口升级。
void boot_thread0_entry(void *pvParameters)
{
    FSP_PARAMETER_NOT_USED (pvParameters);

///
    fsp_err_t err = FSP_SUCCESS;
    err = g_uart9.p_api->open(&g_uart9_ctrl, &g_uart9_cfg);
    if(err == FSP_SUCCESS)
    {
        const char *log_uart_init = "\nboot log uart init successed!!!\r\n";
        g_uart9.p_api->write(&g_uart9_ctrl, (uint8_t*)log_uart_init, strlen(log_uart_init));
        while(uart_send_complete_flag == false)
        {;}
        uart_send_complete_flag = false;
    }
    printf("\nprintf redirect successed!!!\ndate:%s\ntime:%s\nfile:%s\nfunc:%s,line:%d\nhello world!\n", __DATE__, __TIME__, __FILE__, __FUNCTION__, __LINE__);

    check_reset_status();

    /* Open Flash_HP */
    err = R_FLASH_HP_Open(&g_flash0_ctrl, &g_flash0_cfg);
    /* Handle Error */
    if (FSP_SUCCESS != err)
    {
        printf("R_FLASH_HP_Open API failed=%d", err);
    }

    uint8_t fwUpgradeFlg = 0;
    /*Read code flash data */
    readCodeFlash((uint8_t *) FLASH_HP_CF_BLCOK_69, &fwUpgradeFlg, sizeof(fwUpgradeFlg));
    printf("fwUpgradeFlg=%d", fwUpgradeFlg);

    if(fwUpgradeFlg == 1)
    {
        //do frameware upgrade over Ethernet or other
        //creat frameware thread
        //download frameware and check crc
        //write fwUpgradeFlg = 1, jump to app or reset
    }
    else
    {
        unsigned long Boot_Addr = 0x10000;//memory_regions_boot.ld FLASH_LENGTH
        printf("\n**************************************\n");
        printf(  "**********JUMP TO APP:0x%lX**********\n", Boot_Addr);
        printf(  "**************************************\n");

        //close any peripherals before do_boot
        g_uart9.p_api->close(&g_uart9_ctrl);
        R_FLASH_HP_Close(&g_flash0_ctrl);

        //jump
        do_boot(Boot_Addr);

        printf("this message cant print!\n");
    }
///
    /* TODO: add your own code here */
    while (1)
    {
        vTaskDelay (1);
    }
}

FreeRTOS-Plus-TCP

CSDN当前主流的小型嵌入式网络协议栈:https://blog.csdn.net/Simon223/article/details/115673495
freertos对比lwip:https://www.freertos.org/FreeRTOS_Support_Forum_Archive/November_2014/freertos_FreeRTOS_TCP_IP_stack_vs_lwIP_8324ceabj.html

ChatGPT做的几款小型嵌入式网络协议栈的对比,仅供参考

7.2.2.12 boot测试效果

串口日志
boot log uart init successed!!!

printf redirect successed!!!
date:Jun 18 2023
time:20:12:37
file:../src/boot_thread0_entry.c
func:boot_thread0_entry,line:226
hello world!

RSTSR0=0 RSTSR1=0 RSTSR2=0

************************ Cold start ************************
fwUpgradeFlg=255
**************************************
**********JUMP TO APP:0x10000**********
**************************************
7.2.3 app源码
7.2.3.1 app源码分析

app线程说明
线程0 start_thread0_entry日志和监控
线程1 tcp_thread1_entry云端通讯
线程2 uart_thread2_entry本地通讯
线程0 start_thread0_entry说明
移植easylogger日志分级别
fsp littlefsdataflash保存经常变化数据
移植shell监控系统状态
移植ring buffershell串口数据依赖
流程图:

复制线程源码:
void start_thread0_entry(void *pvParameters)
{
    FSP_PARAMETER_NOT_USED (pvParameters);

///
    fsp_err_t err = FSP_SUCCESS;
    ring_buffer_init(&uart9_RxBuf);
    err = g_uart9.p_api->open(&g_uart9_ctrl, &g_uart9_cfg);
    if(err == FSP_SUCCESS)
    {
        const char *log_uart_init = "\napp log uart init successed!!!\r\n";
        g_uart9.p_api->write(&g_uart9_ctrl, (uint8_t*)log_uart_init, strlen(log_uart_init));
        while(uart_send_complete_flag == false)
        {;}
        uart_send_complete_flag = false;
    }
    printf("\nprintf redirect successed!!!\ndate:%s\ntime:%s\nfile:%s\nfunc:%s,line:%d\nhello world!\n", __DATE__, __TIME__, __FILE__, __FUNCTION__, __LINE__);

    fsp_pack_version_t version;
    R_FSP_VersionGet(&version);
    const uint8_t versionstr[] = FSP_VERSION_BUILD_STRING;
    printf("fsp:%s", versionstr);

    const uint32_t bspVCC = BSP_CFG_MCU_VCC_MV;
    const uint32_t bspStack = BSP_CFG_STACK_MAIN_BYTES;
    const uint32_t bspHeap = BSP_CFG_HEAP_BYTES;
    printf("bspVCC=%d MV,bspStack:%d Byte,bspHeap=%d Byte", (int)bspVCC, (int)bspStack, (int)bspHeap);

    volatile const bsp_unique_id_t * uniqueID;
    uniqueID = R_BSP_UniqueIdGet();
    printf("uniqueID:%08X%08X%08X%08X", (unsigned int)uniqueID->unique_id_words[0],(unsigned int)uniqueID->unique_id_words[1],(unsigned int)uniqueID->unique_id_words[2],(unsigned int)uniqueID->unique_id_words[3]);
    printf("MAC:%02X%02X%02X%02X%02X%02X",g_ether0.p_cfg->p_mac_address[0],g_ether0.p_cfg->p_mac_address[1],g_ether0.p_cfg->p_mac_address[2],g_ether0.p_cfg->p_mac_address[3],g_ether0.p_cfg->p_mac_address[4],g_ether0.p_cfg->p_mac_address[5]);

///

#if 1//test
    /* if littlefs enable thread safe,must copy to common_data.c  g_rm_littlefs0_lfs_cfg,FSP 4.4.0 bug
    #ifdef LFS_THREAD_SAFE
    .lock = &rm_littlefs_flash_lock,
    .unlock = &rm_littlefs_flash_unlock,
    #endif
     */
    err = g_rm_littlefs0.p_api->open(&g_rm_littlefs0_ctrl, &g_rm_littlefs0_cfg);
    if(FSP_SUCCESS != err)
    {
        printf("g_rm_littlefs0.p_api->open err=%d\r\n", err);
        g_rm_littlefs0.p_api->close(&g_rm_littlefs0_ctrl);
    }
    printf("g_rm_littlefs0.p_api->open successed!!!\n");

    err = lfs_mount(&g_rm_littlefs0_lfs, &g_rm_littlefs0_lfs_cfg);
    if( err )
    {
        printf("lfs_mount err=%d\r\n", err);
        lfs_format(&g_rm_littlefs0_lfs, &g_rm_littlefs0_lfs_cfg);
        lfs_mount(&g_rm_littlefs0_lfs, &g_rm_littlefs0_lfs_cfg);
    }


    // read current count
    uint32_t boot_count2 = 0;
    lfs_file_open(&g_rm_littlefs0_lfs, &g_log_lfs_file, "boot_count2", LFS_O_RDWR | LFS_O_CREAT);
    lfs_file_read(&g_rm_littlefs0_lfs, &g_log_lfs_file, &boot_count2, sizeof(boot_count2));
    printf("g_log_lfs_file.id ID:%d\r\n", g_log_lfs_file.id);

    // update boot count
    boot_count2 += 1;
    lfs_file_rewind(&g_rm_littlefs0_lfs, &g_log_lfs_file);
    lfs_file_write(&g_rm_littlefs0_lfs, &g_log_lfs_file, &boot_count2, sizeof(boot_count2));

    // remember the storage is not updated until the file is closed successfully
    lfs_file_close(&g_rm_littlefs0_lfs, &g_log_lfs_file);

    uint32_t txt2 = 0;
    lfs_file_open(&g_rm_littlefs0_lfs, &g_log_lfs_file, "txt2", LFS_O_RDWR | LFS_O_CREAT);
    lfs_file_read(&g_rm_littlefs0_lfs, &g_log_lfs_file, &txt2, sizeof(txt2));
    printf("ID:%d\r\n", g_log_lfs_file.id);

    // update boot count
    txt2 += 1;
    lfs_file_rewind(&g_rm_littlefs0_lfs, &g_log_lfs_file);
    lfs_file_write(&g_rm_littlefs0_lfs, &g_log_lfs_file, &txt2, sizeof(txt2));

    // remember the storage is not updated until the file is closed successfully
    lfs_file_close(&g_rm_littlefs0_lfs, &g_log_lfs_file);

    // release any resources we were using
    lfs_unmount(&g_rm_littlefs0_lfs);

    // print the boot count
    printf("boot_count2: %ld\r\n", boot_count2);
    printf("txt2: %ld\r\n", txt2);
    printf("\r\n");
#endif
    ///
    ///
    elog_init();
#if 0
    elog_set_fmt(ELOG_LVL_ASSERT, ELOG_FMT_ALL & ~ELOG_FMT_P_INFO);
    elog_set_fmt(ELOG_LVL_ERROR, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
    elog_set_fmt(ELOG_LVL_WARN, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
    elog_set_fmt(ELOG_LVL_INFO, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
    elog_set_fmt(ELOG_LVL_DEBUG, ELOG_FMT_ALL & ~(ELOG_FMT_FUNC | ELOG_FMT_P_INFO));
    elog_set_fmt(ELOG_LVL_VERBOSE, ELOG_FMT_ALL & ~(ELOG_FMT_FUNC | ELOG_FMT_P_INFO));
#else
    /* set EasyLogger log format */
    elog_set_fmt(ELOG_LVL_ASSERT, ELOG_FMT_ALL);
    elog_set_fmt(ELOG_LVL_ERROR, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
    elog_set_fmt(ELOG_LVL_WARN, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
    elog_set_fmt(ELOG_LVL_INFO, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
    elog_set_fmt(ELOG_LVL_DEBUG, ELOG_FMT_ALL & ~(ELOG_FMT_FUNC | ELOG_FMT_T_INFO | ELOG_FMT_P_INFO));
    elog_set_fmt(ELOG_LVL_VERBOSE, ELOG_FMT_ALL & ~(ELOG_FMT_FUNC | ELOG_FMT_T_INFO | ELOG_FMT_P_INFO));
#endif
    //start easylogger
    elog_start();
    vTaskDelay(1000);
#if 1//test easylogger
    log_a("Hello EasyLogger!");//断言 assert
    // A/NO_TAG   [10:08:12 pid:1008 tid:24] (../Core/Src/freertos.c LED_TASK03:207)Hello EasyLogger!
    log_e("Hello EasyLogger!");//error
    // E/NO_TAG   [10:08:12] Hello EasyLogger!
    log_w("Hello EasyLogger!");//waring
    // W/NO_TAG   [10:08:12] Hello EasyLogger!
    log_i("Hello EasyLogger!");//info
    // I/NO_TAG   [10:08:12] Hello EasyLogger!
    log_d("Hello EasyLogger!");//dbug
    // D/NO_TAG   [10:08:12] (../Core/Src/freertos.c:211)Hello EasyLogger!
    log_v("Hello EasyLogger!");//日志
    //V/NO_TAG   [10:08:12] (../Core/Src/freertos.c:212)Hello EasyLogger!

    uint8_t buf[256]= {0};
    uint16_t i = 0;

    for (i = 0; i < sizeof(buf); i++)
    {
        buf[i] = (uint8_t)i;
    }
    elog_hexdump("test", 16, buf, sizeof(buf));
    log_d("\nTEXT END!\n");
#endif
///

    //init simple shell, then start it
    shell_init();
    shell_register("shell", shell);
    log_i("shell: welcome to shell ra6m5");


    /* TODO: add your own code here */
    while (1)
    {
        //get strings from uart0 rx ring buffer
        if(!ring_buffer_is_empty(&uart9_RxBuf))
        {
            //get strings from uart0 rx ring buffer
            uint8_t cnt = ring_buffer_dequeue_arr(&uart9_RxBuf, (char*)rx, sizeof(uart9_RxBuf.buffer));
            //log_i("rx=%s cnt=%d",rx,cnt);//print input string for test

            //shell parse, shell register callback 'shell'
            uint8_t res = shell_parse((char *)rx, cnt);

            //shell parse result informations
            if (res == 0)
            {
                /* run success */
            }
            else if (res == 1)
            {
                log_i("shell: run failed.\n");
            }
            else if (res == 2)
            {
                log_i("shell: unknown command.\n");
            }
            else if (res == 3)
            {
                log_i("shell: length is too long.\n");
            }
            else if (res == 4)
            {
                log_i("shell: pretreat failed.\n");
            }
            else if (res == 5)
            {
                log_i("shell: param is invalid.\n");
            }
            else
            {
                log_i("shell: unknown status code.\n");
            }
        }

        vTaskDelay (100);
    }
}
7.2.3.12 boot+app测试效果
boot log uart init successed!!!

printf redirect successed!!!
date:Jun 18 2023
time:20:12:37
file:../src/boot_thread0_entry.c
func:boot_thread0_entry,line:226
hello world!

RSTSR0=0 RSTSR1=0 RSTSR2=0

************************ Cold start ************************
fwUpgradeFlg=255
**************************************
**********JUMP TO APP:0x10000**********
**************************************

app log uart init successed!!!

printf redirect successed!!!
date:Jun 18 2023
time:19:53:43
file:../src/start_thread0_entry.c
func:start_thread0_entry,line:439
hello world!
fsp:Built with Renesas Advanced Flexible Software Package version 4.4.0bspVCC=3300 MV,bspStack:8192 Byte,bspHeap=8192 ByteuniqueID:2D033F8E5736363299DA4E364E4B292DMAC:001122334455g_rm_littlefs0.p_api->open successed!!!
g_log_lfs_file.id ID:0
ID:1
boot_count2: 181
txt2: 180

I/elog    [42] EasyLogger V2.2.99 is initialize success.
I/TCP_TAG [47] tcp_thread1_entry
I/TCP_TAG [50] tcp_thread1_thread
I/UART_TAG [53] uart_thread2_entry
I/UART_TAG [56] uart_thread2_thread
A/INIT_TAG [1047  ] (../src/start_thread0_entry.c:540 start_thread0_entry)Hello EasyLogger!
E/INIT_TAG [1055] Hello EasyLogger!
W/INIT_TAG [1058] Hello EasyLogger!
I/INIT_TAG [1061] Hello EasyLogger!
D/INIT_TAG [1064] (../src/start_thread0_entry.c 548)Hello EasyLogger!
V/INIT_TAG [1070] (../src/start_thread0_entry.c 550)Hello EasyLogger!
D/HEX test: 0000-000F: 00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F    ................
D/HEX test: 0010-001F: 10 11 12 13 14 15 16 17  18 19 1A 1B 1C 1D 1E 1F    ................
D/HEX test: 0020-002F: 20 21 22 23 24 25 26 27  28 29 2A 2B 2C 2D 2E 2F     !"#$%&'()*+,-./
D/HEX test: 0030-003F: 30 31 32 33 34 35 36 37  38 39 3A 3B 3C 3D 3E 3F    0123456789:;<=>?
D/HEX test: 0040-004F: 40 41 42 43 44 45 46 47  48 49 4A 4B 4C 4D 4E 4F    @ABCDEFGHIJKLMNO
D/HEX test: 0050-005F: 50 51 52 53 54 55 56 57  58 59 5A 5B 5C 5D 5E 5F    PQRSTUVWXYZ[\]^_
D/HEX test: 0060-006F: 60 61 62 63 64 65 66 67  68 69 6A 6B 6C 6D 6E 6F    `abcdefghijklmno
D/HEX test: 0070-007F: 70 71 72 73 74 75 76 77  78 79 7A 7B 7C 7D 7E 7F    pqrstuvwxyz{|}~.
D/HEX test: 0080-008F: 80 81 82 83 84 85 86 87  88 89 8A 8B 8C 8D 8E 8F    ................
D/HEX test: 0090-009F: 90 91 92 93 94 95 96 97  98 99 9A 9B 9C 9D 9E 9F    ................
D/HEX test: 00A0-00AF: A0 A1 A2 A3 A4 A5 A6 A7  A8 A9 AA AB AC AD AE AF    ................
D/HEX test: 00B0-00BF: B0 B1 B2 B3 B4 B5 B6 B7  B8 B9 BA BB BC BD BE BF    ................
D/HEX test: 00C0-00CF: C0 C1 C2 C3 C4 C5 C6 C7  C8 C9 CA CB CC CD CE CF    ................
D/HEX test: 00D0-00DF: D0 D1 D2 D3 D4 D5 D6 D7  D8 D9 DA DB DC DD DE DF    ................
D/HEX test: 00E0-00EF: E0 E1 E2 E3 E4 E5 E6 E7  E8 E9 EA EB EC ED EE EF    ................
D/HEX test: 00F0-00FF: F0 F1 F2 F3 F4 F5 F6 F7  F8 F9 FA FB FC FD FE FF    ................
D/INIT_TAG [1208] (../src/start_thread0_entry.c 561)
TEXT END!

I/INIT_TAG [1214] shell: welcome to shell ra6m5
I/TCP_TAG [2376475] tcp_thread1_thread
I/UART_TAG [2376481] uart_thread2_thread
I/INIT_TAG [2380884] Usage:
I/INIT_TAG [2380886]   shell (-h | --help)
I/INIT_TAG [2380890]   shell (-i | --information)
I/INIT_TAG [2380894]   shell (-g highwater | --get=highwater)
I/INIT_TAG [2380899]   shell (-g freeheap | --get=freeheap)
I/INIT_TAG [2380905]   shell (-g dietemp | --get=dietemp)
I/INIT_TAG [2380910] Options:
I/INIT_TAG [2380912]       --times=<num>    Set the running times.([default: 3])

I/TCP_TAG [2381478] tcp_thread1_thread
I/UART_TAG [2381484] uart_thread2_thread
I/TCP_TAG [2386481] tcp_thread1_thread
I/UART_TAG [2386487] uart_thread2_thread
I/TCP_TAG [2391484] tcp_thread1_thread
I/UART_TAG [2391490] uart_thread2_thread
``





评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值