|
首先感谢ourdev,这是个很好的学习交流场所,让我学到不少,今天发一个关于AVR单片机操作系统AvrX的文章
由于还没研究操作系统的底层汇编代码,这里也不敢大话,只简单介绍一下应用方法,先看一下界面,
(原文件名:图像008.jpg)
首先从网上下载AvrX 2.6f 的源码www.barello.net,修改其中的Makefile MCU类型,编译。在自己的应用中包含其头文件“avrx-io.h”、“avrx-signal.h”、“avrx.h”,
AvrX系统的应用中包括main()、AVRX_SIGINT(SIG_OVERFLOW0)、至少两个Task等。
编程时可认为单片机从main()函数开始执行,main()函数有如下特征:
int main(void)
{
AvrXSetKernelStack(0); // 设置操作系统内核堆栈
nlcd_init(); //
nlcd_plot_circle(23, 23, 23); // 设备初始化
clock_plot_scale(); //
MCUCR = 1<<SE;
TCNT0 = TCNT0_INIT; // 定时器初始化,1ms定时,TCNT0_INIT 在hardware.h 中指定
TCCR0 = TMC8_CK256;
TIMSK = 1<<TOIE0;
///
AvrXRunTask(TCB(task1)); //
AvrXRunTask(TCB(task2)); // 装入任务
//AvrXRunTask(TCB(task3)); //
////
Epilog(); // Switch from AvrX Stack to first task
while(1);
}
我这次的程序只用了两个任务,任务1与任务2通过Message联系,任务1简单的依靠定时器定时计数更改显示信息,任务2简单的负责刷新屏幕。两个任务稍后附上源代码。
AvrX操作系统提供了40个API函数,可分为6大类:
Tasking (任务级)
Semaphores (信号量管理)
Timer Management (定时器时间队列管理)
Message Queues (消息管理)
Single Step Debugging support (单步运行支持)
Byte FIFO support with synchronization (字节FIFO支持)
这次的程序简单的用到了Timer Management 和 Message Queues 里面的几个API:
AvrXStartTimer
AvrXWaitTimer
AvrXSendMessage
AvrXWaitMessage
Task1 代码如下:
AVRX_GCC_TASKDEF(task1, 75, 1) // clock timer
{
while(1)
{
AvrXStartTimer(&timer1, 499);
AvrXWaitTimer(&timer1);
half_second = !half_second;
// ////////////////////////////////////////
if(half_second)
{
clock_intplot_hand(23, 23, second, SECOND_HAND);
if(second - minute < 3 || minute - second < 3)
clock_plot_hand(23, 23, minute, MINUTE_HAND);
if(second - hour < 3 || hour - second < 3)
clock_plot_hand(23, 23, hour, HOUR_HAND);
/////////////////////////////////////////////
second ++;
if(second > 59)
{
second = 0;
clock_intplot_hand(23, 23, minute, MINUTE_HAND);
if(minute - hour < 3 || hour - minute < 3)
clock_plot_hand(23, 23, hour, HOUR_HAND);
minute ++;
if(minute % 12 == 0)
{
if(minute == 60)
minute = 0;
clock_intplot_hand(23, 23, hour, HOUR_HAND);
hour ++;
if(hour > 59)
hour = 0;
clock_plot_hand(23, 23, hour, HOUR_HAND);
}
clock_plot_hand(23, 23, minute, MINUTE_HAND);
}
clock_plot_hand(23, 23, second, SECOND_HAND);
}
else;
AvrXSendMessage(&myQueue, &second_step);
}
}
Task1 的任务是钟表计时,并重绘钟表指针,然后调用AvrXSendMessage系统函数向消息队列myQueue中发送消息second_step。而Task2就是一直在等待消息。
函数clock_plot_hand( , , , )是绘制时钟指针函数,前两个参数是时钟中心点位置,最后一个参数是说明什么类型的针,秒针,分针或失真。该函数的原型在ckock.h中声明,具体实现代码可参考附件的clock.c 文件。
Task2的代码如下:
AVRX_GCC_TASKDEF(task2, 70, 3) //display all
{
MessageControlBlock *p;
while(1)
{
p = AvrXWaitMessage(&myQueue);
if(p == &second_step)
{
nlcd_plot_circle(23, 23, 23);
clock_plot_scale();
nlcd_show_all();
nlcd_wrtchar( 9, 5, (hour / 12) / 10 + '0');
nlcd_wrtchar(10, 5, (hour / 12) % 10 + '0');
nlcd_wrtchar(12, 5, minute / 10 + '0');
nlcd_wrtchar(13, 5, minute % 10 + '0');
if(half_second)
nlcd_wrtchar(11, 5, ':');
else
nlcd_wrtchar(11, 5, ' ');
}
else;
//AvrXHalt();
}
}
所有的函数具体代码可参考附件,点击此处下载 ourdev_546621.rar(文件大小:14K) (原文件名:ExampleOfAvrX.rar)
该应用的架构层次比较清晰。接下来研究下AvrX的系统代码, |
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|