0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

【御芯微UCM108E开发板试用体验】二次开发代码启动分析

开发板试用精选 来源:开发板试用 作者:电子发烧友论坛 2022-11-24 17:05 次阅读

本文来源电子发烧友社区,作者:许鹏虎, 帖子地址:https://bbs.elecfans.com/jishu_2286915_1_1.html

UCM108E二次开发代码启动分析

简介

UCM108E内置了一颗RISC-V核心的UC8188MCU,所以其实也是在分析UC8188的启动过程。UC8188 是一款高性能 MCU GNSS 多模卫星导航接收机 SoC 芯片。 芯片集成了 RISCV 32 位通用处理器, 数字基带处理器, 射频前端, 具有 4Mb 内嵌的闪存。 拥有 SPI、I2CUARTx2 以及其它丰富的外设。

启动过程分析

  1. MCU启动一般情况下是从reset中断开始的,我们拿到的这颗MCU也是这样,找到它的启动汇编代码,找到reset中断入口

XoLRjU.md.png

  1. 分析这段启动代码
/* reset 中断入口 */
reset_handler:
  csrw mtvec, x0
  csrci  mstatus, 0x08
  /* 1. 将所有寄存器置位为0 set all registers to zero */
  mv  x1, x0
  mv  x2, x1
  mv  x3, x1
  mv  x4, x1
  mv  x5, x1
  mv  x6, x1  
  mv  x7, x1 
  mv  x8, x1  
  mv  x9, x1 
  mv x10, x1
  mv x11, x1
  mv x12, x1
  mv x13, x1
  mv x14, x1
  mv x15, x1
  mv x16, x1
  mv x17, x1
  mv x18, x1
  mv x19, x1
  mv x20, x1
  mv x21, x1
  mv x22, x1
  mv x23, x1
  mv x24, x1
  mv x25, x1
  mv x26, x1
  mv x27, x1
  mv x28, x1
  mv x29, x1
  mv x30, x1
  mv x31, x1

#ifdef ARCH_RISCV_FPU
  fssr    x0
  fmv.s.x f0, x0
  fmv.s.x f1, x0
  fmv.s.x f2, x0
  fmv.s.x f3, x0
  fmv.s.x f4, x0
  fmv.s.x f5, x0
  fmv.s.x f6, x0
  fmv.s.x f7, x0
  fmv.s.x f8, x0
  fmv.s.x f9, x0
  fmv.s.x f10,x0
  fmv.s.x f11,x0
  fmv.s.x f12,x0
  fmv.s.x f13,x0
  fmv.s.x f14,x0
  fmv.s.x f15,x0
  fmv.s.x f16,x0
  fmv.s.x f17,x0
  fmv.s.x f18,x0
  fmv.s.x f19,x0
  fmv.s.x f20,x0
  fmv.s.x f21,x0
  fmv.s.x f22,x0
  fmv.s.x f23,x0
  fmv.s.x f24,x0
  fmv.s.x f25,x0
  fmv.s.x f26,x0
  fmv.s.x f27,x0
  fmv.s.x f28,x0
  fmv.s.x f29,x0
  fmv.s.x f30,x0
  fmv.s.x f31,x0
#endif

  /* 2. 初始化堆栈 stack initilization */
  la   x2, _stack_start


_start:
  .global _start
  
  /* 3. 将bss段清零 clear BSS */
  la x26, _bss_start
  la x27, _bss_end

  bge x26, x27, zero_loop_end

zero_loop:
  sw x0, 0(x26)
  addi x26, x26, 4
  ble x26, x27, zero_loop
zero_loop_end:

  /* 4. 运行全局初始化函数 Run global initialization functions */
  li a0, 1                      /* set app mode */
  call  set_program_type
  
  call  boot_noop
  call  boot_strap /* 关闭全局中断 配置时钟和XIP */
  call  __libc_init_array
  j main_entry   /* 跳转到main_entry 在下面*/
.section .crt0, "ax" 

main_entry:
  addi   x10, x0, 0
  /* Baud Rate 156250 
  *clock divider, SYSCLK/156250/16-1
  *5MHZ 1; 50MHZ 19
  * 103.68Mhz clk, 115200 sv model 89
  * 19.6608Mhz clk, VHD model, value 4. VHD
  * 196/2Mhz   VHD model value 84 for 115200
  */
  //addi   x11, x0, 84 //98Mhz, 1152000 for sim
  addi   x11, x0, 70  //131.072Mhz, 115200 for sim
  //addi   x11, x0, 22 //26M DCXO, just leave it here, not necessary
  //jal  uart_set_cfg 
  
  /* jump to main program entry point (argc = argv = 0) */
  addi x10, x0, 0
  addi x11, x0, 0
  jal x1, entry   /* 跳转到entry函数 */

  jal  uart_wait_tx_done;

  /* if program exits call exit routine from library */
  jal  x1, exit
  1. 通过以上的分析,我们看到最后是跳转到entry函数去了,这个entry就是rt-thread的入口函数,接下来,我们看在这个函数里做了哪些事情

XoLXuD.md.png

  1. 在entry函数里面其实就是调用了rtthread_startup()函数,然后,我们重点分析一下这个函数里面都做了哪些事情
int rtthread_startup(void)
{
    // 关闭全局中断
    rt_hw_interrupt_disable();

    /* board level initialization
     * NOTE: please initialize heap inside board initialization.
     * 板子相关的初始化,主要是启动了systick
     */
    rt_hw_board_init();

    /* show RT-Thread version */
    rt_show_version();

    /* 系统定时器初始化,后续的任务切换调度都会用到这个timer,timer system initialization */
    rt_system_timer_init();

    /* 初始化系统调度器 scheduler system initialization */
    rt_system_scheduler_init();

#ifdef RT_USING_SIGNALS
    /* signal system initialization */
    rt_system_signal_init();
#endif

    /* 创建main线程并启动 create init_thread */
    rt_application_init();

    /* 创建timer线程并启动 timer thread initialization */
    rt_system_timer_thread_init();

    /* 创建空闲线程并启动 idle thread initialization */
    rt_thread_idle_init();

#ifdef RT_USING_SMP
    rt_hw_spin_lock(&_cpus_lock);
#endif /*RT_USING_SMP*/

    /* 启动调度器 start scheduler */
    rt_system_scheduler_start();

    /* never reach here */
    return 0;
}
  1. 通过对以上的分析,我们大概知道rt-thread创建了几个必要的线程并启动了调度器,这个时候就会启动刚才创建的线程,其中用户关心的则是main线程,我们看下main线程里面做了哪些工作
/* the system main thread */
void main_thread_entry(void* parameter)
{
    extern int main(void);

#ifdef RT_USING_COMPONENTS_INIT
    /* RT-Thread components initialization */
    rt_components_init();
#endif

#ifdef RT_USING_SMP
    rt_hw_secondary_cpu_up();
#endif
    /* invoke system main function */
#if defined(__CC_ARM) || defined(__CLANG_ARM)
    {
        extern int $Super$$main(void);
        $Super$$main(); /* for ARMCC. */
    }
#elif defined(__ICCARM__) || defined(__GNUC__) || defined(__TASKING__)
    main();  // 运行main函数
#endif
}
  1. 其实这个线程最终是为了调用main函数,也就是我们用户编程的入口函数
int main(void)
{
        int_disable();
        REG_INT_PEND = 0x0;
#ifdef _WTG_OPEN_
        wdt_init(UC_WATCHDOG, 5000);
        wdt_enable(UC_WATCHDOG);
#endif
        InitUart(UART_BSP_115200);
        GnssStart(get_pos, 0x7f, FALSE, NULL);
        
        g_hTaskUartTx = rt_thread_create("Task Uart Tx", TaskUartTx, NULL, TSK_STACK_SIZE_UART_TX, 10, 10);
        
        if(g_hTaskUartTx == RT_NULL)
                printf("tx task create failed!rn");
        else
        {
                rt_thread_startup(g_hTaskUartTx);
                printf("tx task is start!rn");
        }
        
        g_hTaskUartRx = rt_thread_create("Task Uart Rx", TaskUartRx, NULL, TSK_STACK_SIZE_UART_RX, 10, 10);
        
        if(g_hTaskUartRx == RT_NULL)
                printf("rx task create failed!rn");
        else
        {
                rt_thread_startup(g_hTaskUartRx);
                printf("rx task is start!rn");
        }
#ifdef _WTG_OPEN_
        wdt_feed(UC_WATCHDOG);
#endif
}
  1. 分析到这里我们应该清楚的知道UCM108E从上电到main的整个运行流程了。

如果大家对rt-thread感兴趣,可以访问官网获取更多学习资料。后续还会分享RISC-V任务切换相关知识。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 御芯微
    +关注

    关注

    4

    文章

    48

    浏览量

    3232
  • 开发板试用
    +关注

    关注

    3

    文章

    299

    浏览量

    1898
  • UCM108E
    +关注

    关注

    0

    文章

    13

    浏览量

    134
收藏 人收藏

    评论

    相关推荐

    【米尔-瑞萨RZ/G2UL开发板开发板开箱与接口介绍

    总结1.板子做工设计不错,产品级设计,该有得防护设计等都有考虑,可以直接基于其进行二次开发也可以参考其设计。2.资料非常全完善,这一点是非常非常难得得,学习开发都是不错的选择。
    发表于 01-14 13:25

    【涂鸦T2-U开发板试用体验】嵌入式linux开发板涂鸦T2-U

    120 MHz 。它支持 开发者通过涂鸦自研的物联网操作系统---- TuyaOS 进行自定义二次开发 ,拥有电量统计芯片驱动、照明驱动、幻彩灯带芯片驱动等功能,开发者可按需选用。 外观还是比较
    发表于 12-22 11:21

    【爱派 Pro 开发板试用体验】开箱测试

    的各种纸盒包装结实很多。 打开后发现,其中包括一个开发板和电源。还有一个口袋里面有个螺母,不知道什么用途,我现在把它安装在电源的接头上了,好像也不是特别合适。 开发板上的各种接口似乎都是双份,包括
    发表于 11-20 22:09

    【爱派 Pro 开发板试用体验】开箱报告 + 资料准备

    很高兴获得了这次试用爱心派Pro开发板试用资格,之前也有接触过爱元智家的AX620开发板,是因为他们的家的AI ISP慕名而来的,之前深
    发表于 11-14 20:59

    【爱派 Pro 开发板试用体验】+开箱初次体验

    【爱派 Pro 开发板试用体验】+开箱初次体验 开箱内容    打开包装,你可以看到以下物品 12v 2A电源适配器 typec的数据线 一个螺母头(应该为了给固定插12 2A的适配器的插头
    发表于 11-12 10:58

    【LuckFox Pico 开发板免费试用】+ 系统烧写

    很高兴有机会对LuckFox Pico 开发板试用。收到板子后好好研究了一番,找了相关的资料。 LuckFox Pico 开发板基于瑞
    发表于 10-29 20:05

    【LuckFox Pico 开发板免费试用】开箱初体验

    很高兴有这次LuckFox Pico 开发板试用机会,前面也做了些了解,搜集了一些相关资料。1.关于开发板 LuckFox Pico 开发板基于瑞
    发表于 10-15 19:09

    【LuckFox Pico Plus开发板免费试用】使用ADB命令访问开发板

    感谢电子发烧友和幸狐科技提供了此次LuckFox Pico Plus开发板试用机会。 LuckFox Pico 是一款基于瑞 RV1103 芯片具有高性价比的微型 Linux
    发表于 10-14 09:42

    【新品体验】涂鸦 T2-U 开发板免费试用

    。它支持开发者通过 TuyaOS 进行自定义二次开发,拥有电量统计芯片驱动、照明驱动、幻彩灯带芯片驱动等功能,开发者可按需选用。了解更多>>
    发表于 09-18 10:31

    RK3568开发板三屏异显方案演示# 3568

    开发板
    武汉万象奥科
    发布于 :2023年09月15日 16:49:00

    【米尔-驰D9开发板- 国产平台试用】-- 01 -- 开箱上电

    其实和米尔还是很有缘分的,很多的开发板都有过试用的经历,这个米尔电子推出的国产化的芯片驰D9的性能让我很是向往,所以就在发烧友的论坛申请了,庆幸的是我是如此的幸运,能够有机会
    发表于 08-16 17:45

    0元试用!车规级国产芯驰D9开发板

    米尔与合作芯驰推出的新品基于D9系列应用处理器的MYC-JD9X核心板及开发板现已开放免费试用名额!!米尔准备了3块价值1199元的开发板发起试用活动您不仅可以免费体验还可以获得京东购
    的头像 发表于 07-06 10:07 540次阅读
    0元<b class='flag-5'>试用</b>!车规级国产芯驰D9<b class='flag-5'>开发板</b>

    基于RV1109/RV1126方案IPC,始终致力于为算法厂商提供可二次开发的智能摄像头硬件设备

    、智慧AI商业解决方案公司自有算法接入,提供硬件定制以及软件二次开发Demo帮助客户自有算法场景落地。目前,量产的IPC产品已在国内外的家居监控及大型购物商场中投入使用。(20年的传统安防制造经验让您量产无忧)
    发表于 06-28 16:51

    【感科技MC3172开发板体验】感科技MC3172开发板上手体验

    前言 逛发烧友社区时,在试用中心看到由厦门感科技推出的搭载MC3172芯片的开发板试用资格,然后就心动了,马上申请,通过后不久发烧友就安排了快递寄送(爱了),到手后直接找资料学习起来
    发表于 05-24 16:24

    空间光调制器的简便控制方法:灵活应用二次开发

    01.什么是二次开发模式? 二次开发模式实际上就是一组指令集,不同于一个有窗口的软件,这组指令集更像一根管道,管道的一端可以和任意编程软件对接,管道的另外一头就可以将结果展现在特定设备上,管道完成
    的头像 发表于 05-11 13:37 351次阅读
    空间光调制器的简便控制方法:灵活应用<b class='flag-5'>二次开发</b>