如果您对此文有任何疑问,请到电子论坛提问我们将热忱为您解答。
由于学习µC/OS-II 时间比较短,很多问题还在不断地摸索,我想将我在移植µC/OS-II到PIC18f8720中的一些经验贡献出来,让大家分享,难免错误的地方,欢迎拍砖。由于手头任务时间较紧,我只有抽空凑一点大家一起交流。望走在前面的大虾,多提宝贵意见。
为什么要RTOS(实时内核)?是不是觉得很时髦?这样说,你要是搞一些代码量很小,产品质量也不是很重要,也不需要所有的任务都按时完成,那还是传统的程序结构比较适用,因为它不需要你花大量的时间去接触内核这个当代软件的专家技术。如果你的程序量很大,系统的任务繁重,像现在超过32K的code已很常见,这时,就再也不是我们传统说的30%时间写程序,70%调试程序了,很可你花了大半年时间搞出来的程序自己都说不清结构,维护起来十分吃力,有时候维护一个程序还不如重新写一个快。我去年就这样,3个月写出来的东西,自己都把它否定了!搞得人很累。最近又一个东西需要管理4个步进电机、一个交流电机,多路开关信号的输入输出,还要240x64的lcd,键盘。要求人机信息交换很多。最头痛的还要这些电机同步协调工作。我水平很臭,搞了10来天就走不动了,超过25k后没有头绪了。只好咬紧牙关看看RTOS(实时内核)的东西了。没有一点基础,也就没有一点底自己到底行不行?但背水一战,也只好硬着头试一下。它有什么作用?虽然学起来十分艰难,但完全可以将整个工程分成若干个小块,每一块就只处理一个任务,比如说一个电机的工作或lcd如何显示;各个任务之间再想办法通过专门的方法联系,让你不再考虑程序的整体结构问题了。
用什么RTOS?从一些资料中发现µC/OS-II很适合初学者,好,就是它。
µC/OS-II是一个源代码公开专门针对MCU的一个占先式实时内核,它的最大好处是可以放在你的源代码中,一起编译链接后在mcu中运行,不像一些内核需要放在专门的boot代码块中。其次可以根据你的需要进行裁减——这些都可以在它的资料中看到。当然你离不开一下的几个过程,有些甚至很痛苦。
首先,你要有较好的C基础,不然你看它的一些代码就是坐飞机了!
其次,必须搞懂嵌入式系统的概念。
有这样的前提,你就可以看看邵贝贝翻译Jean J.Labrosse著的《嵌入式实时操作系统 µC/OS-II》,我花了20天时间专门看这本书,现在也就懂一点皮毛。我认为第一步不要深究代码的意思,只要知道这个函数做了些什么工作,就可以了,关键是要知道如何应用,必须搞懂的地方有:任务和事件的数据结构,优先级算法,中断的处理方法。然后你就可以试着使用被前人移植过的环境了。如果要自己去搞移植,没有功底就绝对没有把握。
去www.ucosii.com 上下载一个适合你的移植好了的代码,着手编译一下,最好是能够在PICDEM 2 PLUS上运行。这个过程看来简单,自己摸索也很费时日的~~~ 要注意的一些问题:
1、 不要指望在htsoft出的Picc18下编译,由于它不支持代码重载,你用的再熟练也只有抛掉!去关心难用的mcc18吧。还要注意linker脚本文件的修改,我也没有搞懂linker,参照下载文档里现成的18f452的样子,删掉对databank的划分,在编译命令里选用大模式,就过去了。现在也说不出原因。
2、 下载的文档里,没有Kernel的代码,你还得拷贝进去,注意千万不要覆盖已存在的源代码。
3、 编译通过了,你就成功了一半,我在PICDEM 2 PLUS 下调时发现根本就不能运行,今天花了一天时间,才找到问题,是xlcd.c里面除了问题。只要看到任务能够调动了,不管它,过。搞了3个任务,分别驱动3个led,很好都工作了。代码如下:
***************************************************************/
#include "includes.h"
#include <timers.h>
#include <string.h>
#include <stdlib.h>
/************************************************************************/
#define Ldata PORTD
#define Lport TRISD
#define ******1 PORTCbits.RC2
#define DIR1 PORTCbits.RC3
#define EN1 PORTCbits.RC4
OS_STK Task1Stk[100];
OS_STK Task2Stk[50];
OS_STK Task3Stk[50];
OS_STK Task4Stk[50];
void Task1(void *pdata);
void Task2(void *pdata);
void Task3(void *pdata);
void Task1(void *pdata)
{
OpenTimer0(TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_PS_1_1);
WriteTimer0(-10000);
// Initialize statistics task
OSStatInit();
OSTaskCreate(Task2,(void *)0,Task2Stk,7);
for(;;)
{ ******1=1;
OSTimeDly(0x20);
******1=0;
OSTimeDly(0x20);
}
}
void Task2(void *pdata)
{ OSTaskCreate(Task3,(void *)0,Task3Stk,6);
for(;;)
{ DIR1=1;
OSTimeDly(0x20);
DIR1=0;
OSTimeDly(0x20);
}
}
void Task3(void *pdata)
{ for(;;)
{ EN1=1;
OSTimeDly(0x20);
EN1=0;
OSTimeDly(0x20);
}
}
void Task4(void *pdata)
{
}
// initialization
void Initialize(void)
{
ADCON1=0x0F; // all ad conversion disable at this system
PORTA=0x00;
LATA=0x00;
TRISA=0x00;
PORTB=0b11110000;
LATB=0xF0;
TRISB=0xF0;
PORTC=0x00;
LATC=0x80;
TRISC=0x80;
Ldata=0xff;
Lport=0xff;
LATD=0XFF;
PORTF=0xFF;
LATF=0xFF;
TRISF=0xFF;
PORTG=0x00;
LATG=0x00;
TRISG=0x00;
PORTH=0x0F;
LATH=0x0F;
TRISH=0x0F;
PORTJ=0b11111111;
LATJ=0xFF;
TRISJ=0b11010101;
}
//main rouitine
void main(void)
{ Initialize();
OSInit();
OSTaskCreate(Task1,(void *)0,Task1Stk,5);
OSStart();
}
下一步就可以试一下身手了。以后的经验看情况,继续发给大家。
原文:http://www.mcublog.com/blog/group.asp?cmd=show&gid=23&pid=272