MSP432用上μC/OS-III,却开不了FPU

2019-03-24 09:41发布

本帖最后由 TWENLONG 于 2015-9-27 16:25 编辑

最近接触了μC/OS-III,手里的MSP432LaunchPad都尘封了好久了,于是想着让它用上μC/OS-III。在Micrium公司官网下载已经移植好的示例工程,这是为这块板子适配的,拿来就可以用,里面包含了IAR和CCS的工程文件。(所有文件在文末有百度云下载)
无标题.png
先在IAR上玩一下,直接下载调试运行,就可以看到LED1在闪烁了,S1可以调节闪烁频率,S2用来控制RGB LED的点亮
官方的工程文件里面主要是BSP里面的内容需要根据自己的实际情况改写,我这种新手还不习惯官方的写法,于是进行了一番删减
官方的启动文件同之前的不一样,中断向量表里面的函数入口地址每个都已经写好了,复位程序里面就关掉了看门狗,
  1. /*
  2. *********************************************************************************************************
  3. *                                  EXCEPTION / INTERRUPT VECTOR TABLE
  4. *
  5. * Note(s) : (1) The Cortex-M4 may have up to 256 external interrupts, which are the final entries in the
  6. *               vector table.  The MSP432 has 65 external interrupt vectors.
  7. *********************************************************************************************************
  8. */

  9. __root  const  APP_INTVECT_ELEM  __vector_table[] @ ".intvec" = {
  10.     { .Ptr = (void *)__sfe( "CSTACK" )},
  11.                                                                 /* 000 Initial stack pointer.                           */
  12.     App_Reset_ISR,                                              /* 001 Initial program counter.                         */
  13.     App_NMI_ISR,                                                /* 002 Non-maskable interrupt.                          */
  14.     App_Fault_ISR,                                              /* 003 Hard fault exception.                            */
  15.     App_Spurious_ISR,                                           /* 004 Reserved interrupt 4.                            */
  16.     App_BusFault_ISR,                                           /* 005 Bus fault exception.                             */
  17.     App_UsageFault_ISR,                                         /* 006 Usage fault exception.                           */
  18.     App_Spurious_ISR,                                           /* 007 Reserved interrupt 7.                            */
  19.     App_Spurious_ISR,                                           /* 008 Reserved interrupt 8.                            */
  20.     App_Spurious_ISR,                                           /* 009 Reserved interrupt 9.                            */
  21.     App_Spurious_ISR,                                           /* 010 Reserved interrupt 10.                           */
  22.     App_Spurious_ISR,                                           /* 011 A supervisor call exception.                     */
  23.     App_Spurious_ISR,                                           /* 012 Debug Monitor.                                   */
  24.     App_Spurious_ISR,                                           /* 013 Reserved interrupt 13.                           */
  25.     OS_CPU_PendSVHandler,                                       /* 014 PendSV exception.                                */
  26.     OS_CPU_SysTickHandler,                                      /* 015 SysTick Interrupt.                               */

  27.     BSP_IntHandlerPSS,                                          /* 016 IRQ[  0] PSS ISR                                 */
  28.     BSP_IntHandlerCS,                                           /* 017 IRQ[  1] CS ISR                                  */
  29. .
复制代码OS_PendSVHandler和OS_SysTickHandler在移植文件os_cpu_a.asm里面定义,前者用来上下文切换,后者是SysTick定时器的中断服务程序,外设的中断名都已经定义好了,假如PORT6中断发生,那就会执行BSP_IntHandlerPORT6,这个函数在bsp_int.c文件里:
  1. <blockquote>void  BSP_IntHandlerPORT6                 (void)  { BSP_IntHandler(BSP_INT_ID_PORT6);               }
复制代码然后又执行BSP_IntHandler(BSP_INT_DI_PORT6),
  1. void  BSP_IntHandler (CPU_INT16U  src_nbr)
  2. {
  3.     CPU_FNCT_VOID  isr;
  4.     CPU_SR_ALLOC();

  5.     CPU_CRITICAL_ENTER();                                       /* Tell the OS that we are starting an ISR            */
  6.     OSIntEnter();
  7.     CPU_CRITICAL_EXIT();

  8.     if (src_nbr < BSP_INT_ID_MAX) {
  9.         isr = BSP_IntVectTbl[src_nbr];
  10.         if (isr != (CPU_FNCT_VOID)0) {
  11.             isr();
  12.         }
  13.     }

  14.     OSIntExit();                                                /* Tell the OS that we are leaving the ISR            */
  15. }
复制代码这个函数先定义了一个CPU_FNCT_VIOD类型的变量isr,这是个指向函数指针,该函数参数和返回值均为空,然后根据传入的中断源ID号从BSP_IntVecTbl里面取得地址,BSP_IntVecTbl在bsp_int.c里面定义:
  1. static CPU_FNCT_VOID BSP_IntVectTbl[BSP_INT_ID_MAX];
复制代码这个中断向量表由以下函数初始化:
  1. void  BSP_IntInit (void)
  2. {
  3.     CPU_INT32U  int_id;


  4.     for (int_id = 0; int_id < BSP_INT_ID_MAX; int_id++) {       /* Initialize each interrupt with Dummy Handler         */
  5.         BSP_IntVectSet((CPU_INT08U)int_id,
  6.                        (CPU_FNCT_VOID)BSP_IntHandlerDummy);
  7.     }
  8. }

  9. void  BSP_IntVectSet (CPU_INT08U     int_id,
  10.                       CPU_FNCT_VOID  isr)
  11. {
  12.     CPU_SR_ALLOC();


  13.     if (int_id < BSP_INT_ID_MAX) {
  14.         CPU_CRITICAL_ENTER();
  15.         BSP_IntVectTbl[int_id]   = isr;                         /* Setup interrupt specified in the vector table        */
  16.         CPU_CRITICAL_EXIT();
  17.     }
  18. }
复制代码初始化完毕后向量表全部指向BSP_IntHandlerDummy,这个函数死循环,什么也不做:
  1. static void  BSP_IntHandlerDummy (void)
  2. {
  3.     while (DEF_TRUE) {
  4.         ;
  5.     }
  6. }
复制代码所以要用中断时先要调用BSP_IntVectSet 设置对应的中断向量表,比如在官方的例程里面开启了按键的中断:
  1. BSP_IntVectSet(BSP_INT_ID_PORT1,  App_Port1_ISR);
复制代码App_Port1_ISR就是自己定义的中断服务程序了,这真是绕了好大一圈啊,这么做我想也是有道理的,不过我不习惯,就给改了,启动代码里面全用App_Spurious_ISR代替BSP_IntHandlerxxx,用到某个中断就把函数名替换过来,这就习惯了,跟原来差不多了,官方提供的一些中断初始化之类的函数就不要了,最后bsp_int.c文件里面就删减得没东西了。

再对着例程看看,任务运行之前都干了些啥
先CPU初始化,CPU name 什么的:CPU_Init();
关中断,以免初始化过程被打断:BSP_IntDisAll(); 这个函数就是执行CPU_IntDis(),就是两条汇编指令,所以可以替换掉;
接着创建启动任务,启动任务里面执行BSP_Init():
  1. void  BSP_Init (void)
  2. {
  3.     BSP_SysInit();                                              /* -------------- CLOCK INITIALIZATION --------------- */
  4.     BSP_IntInit();                                              /* ------------- INTERRUPT INITIALIZATION ------------ */
  5.     BSP_LED_Init();                                             /* ---------------- LED INITIALIZATION --------------- */
  6.     BSP_PB_Init();                                              /* ------------ PUSH BUTTON INITIALIZATION ----------- */
  7. }
复制代码BSP_SysInit()函数把MCLK设为48M,SysTick定时器时间间隔为1ms,然后开启了中断,我觉得中断的开启放在外面是不是要好一点
  1. void  BSP_SysInit (void)
  2. {
  3.                                                                 /* - Configure DCO to 48MHz. Make MCLK use the DCO.   - */
  4.     CSKEY  = CS_ACCESS_KEY;                                     /* Unlock CS module for register access.                */
  5.     CSCTL0 = 0u;                                                /* Reset tuning parameters.                             */
  6.     CSCTL0 = DCORSEL_5;                                         /* Set DCO to 48MHz operation.                          */
  7.     DEF_BIT_SET(CSCTL0, DCOEN);                                 /* Enable DCO (digitally controlled oscillator).        */
  8.    
  9.                                                                 /* Select DCO as the MCLK with no divider.              */
  10.     DEF_BIT_CLR(CSCTL1, (SELM_M | DIVM_M));
  11.     DEF_BIT_SET(CSCTL1, SELM_3);
  12.     CSKEY = 0u;                                                 /* Lock CS module to protect it from inadvertent access.*/

  13.                                                                 /* Enable SysTick Module                                */
  14.     DEF_BIT_SET(BSP_SYS_REG_SCS_STCSR,
  15.                         SYSTICK_STCSR_CLKSOURCE | SYSTICK_STCSR_ENABLE);

  16.                                                                 /* Set SysTick period to 1/48000                        */
  17.     if (((CSCTL0 & DCORSEL_M) >> 16u) == 5u) {
  18.             SYSTICK_STRVR = 48000u;
  19.     }
  20.                                                
  21.     CPU_IntEn();                                                /* Enable Interrupts.                                   */
  22. }
复制代码BSP_IntInit()就是前面说的设置中断向量表,我就不用它了。接着是LED和按键的初始化
然后执行BSP_Tick_Init(),根据所设定的系统滴答设置SysTick定时器的时间间隔,SysTick在Cortex-M4内核的MCU上应该是一样的,OS_CPU_SysTickInit里面开启了SysTick的中断,我把BSP_Tick_Init函数也写进BSP_Init里面了,bsp_sys.c和bsp_sys.h文件我就不要了
  1. void BSP_Tick_Init (void)
  2. {
  3.     CPU_INT32U  cpu_clk_freq;
  4.     CPU_INT32U  cnts;

  5.     cpu_clk_freq = BSP_CPU_ClkFreq();                           /* Determine SysTick reference freq.                    */

  6. #if (OS_VERSION >= 30000u)
  7.     cnts  = cpu_clk_freq / (CPU_INT32U)OSCfg_TickRate_Hz;       /* Determine nbr SysTick increments.                    */
  8. #else
  9.     cnts  = cpu_clk_freq / (CPU_INT32U)OS_TICKS_PER_SEC;        /* Determine nbr SysTick increments.                    */
  10. #endif

  11.     OS_CPU_SysTickInit(cnts);                                   /* Init uC/OS periodic time src (SysTick).              */
  12. }
复制代码到这儿初始化工作差不多就完了,然后就可以创建自己的任务了。
调试之前需对工程设置一番:
Debugger里面的Setup选项卡Driver选择TI XDS:
捕获.PNG
Download选项卡勾上Use flash loader(s):
捕获4.PNG
IAR提供了调试UC/OS的插件,可以勾上μC/OS-III,如果安装了μC/Prob还可勾上:
捕获5.PNG
TI XDS里面Setup选项卡选择调试器和调试包的安装路径:
捕获3.PNG
然后就可以进入调试了,勾选了插件之后菜单栏会有μC/OS-III,任务列表,CPU使用率,堆栈使用量等等都可以显示出来,可是我感觉这个这个显示的并不准确呀,而且不能实时地刷新
捕获6.PNG
我安装了μC/Prob,这个软件也可以显示μC/OS的各种信息,不过教育版使用有限制,首先设置连接方式,有很多可选项,这里由于IAR里面勾选了插件,选择TCP/IP,填上自己的IP地址就可以了
捕获7.PNG
接着加载ELF文件,IAR输出的.out文件就是ELF格式
捕获8.PNG
右键project1,添加μC/OS-III Awareness,并在datascreen里面添加一个温度计,把一个全局变量和温度计关联起来,直接托上去
捕获9.PNG
接着就可以点run了(IAR需要在调试界面),也有各种信息,全局变量也可以显示,可是为啥有时候是实时的,有时候又不是啊???
捕获10.PNG
捕获11.PNG

接着测试FPU,MSP432要用PFU的话,是不是首先编译器要开启FPU,然后程序里面再用库函数开启FPU?我在工程选项里面选择了使用FPU,创建了一个定时器任务,里面调用库函数MAP_FPU_enableModule(),然后每秒对浮点数加0.01,结果任然硬件错误,不启用FPU一切正常,启用FPU不进行浮点运算也是一切正常。。。μC/OS-III里面对浮点寄存器确实是做了进栈和出栈处理的,这里我也不知道该怎么改,汇编什么的都不懂,忧伤。。。。
捕获12.PNG
  1. <blockquote>void timerTask(void *p_arg)
复制代码接着在CCS里面玩,感觉CCS要人性化一点,可是我的是Free License的,不能调试
做同样的删减,同样的程序代码,同样也是浮点的问题,没有浮点运算一切正常,加了浮点运行3秒就死了,而且工程选项里面我关不掉FPU,不能选择第一行空白,还有我在添加驱动库的时候路径必须添加到最后一行,要不然就报错,实在让人无语。。。
捕获13.PNG
刚接触μC/OS-III,也不知道其他的RTOS好用不,比如FreeRTOS和TI RTOS,附上百度云连接,官方代码,自己的工程,μC/Prob:
http://pan.baidu.com/s/1kT1YrxP
此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
4条回答
sunduoze
2019-03-24 21:36
Mark,差的还远着呢,得向楼主学习~

一周热门 更多>

相关问题

    相关文章