CoIDE下UCos-II在STM32下的移植

来源:互联网 发布:php hadoop 编辑:程序博客网 时间:2024/04/28 21:58

最近喜欢上了CoIDE这个开发环境来开发STM32,为什么不用UV4的,因为用UV4来写基于库函数的STM32程序,我相信每个人都会产生一个念头,为什么变量名这么长啊,这是在写文章还是在写代码,如果有一个自动补全功能该多好,笔者我自己就是深受其害,UV系列都这么多年了,编辑器的功能为什么还是这么落后,人家AVR都有VS,也有Eclipse,ARM现在这么热门,配套的IDE却还是这么落后,这的确让人惋惜.

于是我就打算开始换IDE,查了查大概有那么几种方案,有用VS+GCC的,也有eclipse+GCC的,这些我都试过,编辑代码没啥问题,问题在于硬件调试,比较难以实现,还不得不到UV4下去调,最近才发现CoIDE,代码编辑是基于eclipse的,也支持各种硬件调试,所以还是值得推荐的。(我广告打完了,当然我是自愿为他们宣传的)

自从用了RTOS以后,渐渐地就不太喜欢在编裸机程序了,所以就开始移植Ucos-II了。

至于关于如何移植Ucos的细节我就不在阐述了,大家可以去看邵贝贝翻译的书,我就讲一下在CoIDE上面移植遇到的问题。

1. uCosII中有一个用汇编语言编写的文件os_cpu_a.s文件,但是uCos-II的源码中只有realview和IAR的代码,没有给出GNU环境下的代码,所以只能找GNU汇编的代码.

2. 源码是基于V2.0库函数版本写的,但是我习惯用V3.5版本的,版本新的肯定比旧的优秀,不然更新干嘛,所以我就修改了一下,用V3.5的库函数.

3. 移植完成后,就开始上机验证是否工作,于是遇到了问题,在OSTCBHighRdy里卡在了死循环了,查了查问题在于没有进入PendSV中断,解决方法如下,

在移植的过程中要给系统提供两个中断函数,一个是“OS_CPU_PendSVHandler”,另一个是"OS_CPU_SysTickHandler",第一个在os_cpu_a.asm中用到,另一个在os_cpu_c.c中用到。

项目中---startup_stm32f10x_md.s中定义了中断向量表(中断函数的入口地址)

          ---stm32f10x_it.c 中断服务函数的C语言代码。

在startup_stm32f10x_md.s中有两段代码如下:(keil编译器)(如果是IAR编译器需要在vcetor.c中查找 )

        DCD     PendSV_Handler 

        DCD     SysTick_Handler 

在stm32f10x_it.c中的服务函数如下

void PendSV_Handler(void){ }                  

void SysTick_Handler(void)  { }

刚开始,为了偷懒而且没意识到问题的严重性,所以做出了下面的修改。

void PendSV_Handler(void)

{

   OS_CPU_PendSVHandler(); //调用ucos系统中断函数

}

void SysTick_Handler(void)

{

   OS_CPU_SysTickHandler(); //调用ucos系统中断函数

}

startup_stm32f10x_md.s没变动,我直接修改了两个服务函数,在函数中调用ucosII的函数。。。结果就出

现了下面的问题:

程序死在了OSStart();里。经过单步发现程序的软件中断触发后调用服务函数失败,停在了

OSStartHang

    B       OSStartHang <-----------------------停在这里了

上网搜了一下,发现遇到这个问题的还挺多的,不过原因可能有很多,而且基本上没人给出解决的办法,郁闷中,只能一步一步的对比查找,后来就发现了问题,解决如下:

1:ucos系统中的中断函数(os_cpu_a.s和 os_cpu.h中的所有OS_CPU_PendSVHandler)更名为PendSV_Handler,注释掉stm32f10x_it.c文件中void PendSV_Handler(void)函数。(os_cpu_c.c和 os_cpu.hOS_CPU_SysTickHandler做类似的修改)

2.在void SysTick_Handler(void)函数中添加如下代码:

void SysTick_Handler(void)

{

  OS_CPU_SR  cpu_sr;

  OS_ENTER_CRITICAL();                                        // Tell uC/OS-II that we are starting an ISR                

  OSIntNesting++;

  OS_EXIT_CRITICAL();

  OSTimeTick();                                               // Call uC/OS-II's OSTimeTick()                             

  OSIntExit();                                                // Tell uC/OS-II that we are leaving the ISR  

}

也就是要把入口直接指向服务函数的入口,不可以第二次调用,因为第二次调用SP和一些寄存器的内容已经被改了,所以没法系统调度了,系统就死掉了。

经过这些问题以后,就完成了移植,我把我移植好的工程文件给大家分享一下.

http://pan.baidu.com/share/link?shareid=690866565&uk=755305467

原创粉丝点击