arm嵌入式复习资料文档格式.docx
《arm嵌入式复习资料文档格式.docx》由会员分享,可在线阅读,更多相关《arm嵌入式复习资料文档格式.docx(22页珍藏版)》请在冰豆网上搜索。
――外部中断模式(irq)
――管理模式(svc)
――数据访问中止模式(abt)
――系统模式(sys)
――未定义指令中止模式(und)
ARM9处理器中的调试接口?
SWD接口(2根线)、串行口(5根线)、TAG接口
CACHE与MMU,DMA的功能?
加入CACHEZ(缓存)、CPU速度加快运算效率高,加快读写速度
MMU用户模式部分任务不执行,内存管理(实现虚拟地址到物理地址的转存),把用户程序与系统程序分开,保证系统程序稳定。
DMA通过减少执行指令,提高CPU的运行速率,执行指令短,让CPU少执行程序.
NANDFLASH与NORFALSH的特点?
存储密度高,价格低,不能在上面执行程序,引脚少,容量大。
价格昂贵,可直接在上面执行程序,引脚多,容量大。
嵌入式系统中存储器的速度,容量,接口形式?
速度由快到慢:
寄存器、内存、I2C、硬盘。
容量由大到小:
硬盘、内存、37个寄存器。
接口形式:
嵌入式软件,操作系统知识嵌入图形用户界面知识:
常见的嵌入式操作系统有哪些?
uC/GUI主要功能,常见控件?
图形用户界面,支持按键、任何大小LCD、鼠标、字符显示
常见控件:
菜单、静态文本框、单行和多行编辑框、列表框、属性页、工具栏、按钮、显示窗口、编辑框、进度条
不能显示word、PDF、DVD.
uC/OS操作系统运行状态?
P18
就绪ready、运行running、休眠dormant、ISR中断
PPT:
运行态、等待态、就绪态、将死态、中断态(不包括内存运行态、外存运行态)
uC/OS任务函数结构?
无限循环(for(;
;
)、一定是调用函数0)、自我删除结构(不需要循环)
uC/OS操作系统中任务通信方式有哪些?
消息、邮箱、信号、消息队列、管道
可移植软件设计
没有涉及I/O接口、寄存器的程序(与硬件相关的程序可移植性高)
有涉及时可用此解决#defineSCLP1.0
开发工具应用常见接口电路知识:
ADS软件功能
AXD软件功能
专门用调试的软件(查看寄存器的英文单词)
J-link功能
下载程序实现调试(H-JTAG)速度快
常用功能
如何查看变量,寄存器,内存等
AD模块,DMA模块
2410中500k最快,采样频率为最快频率的2倍或2倍以上。
应用程序设计
任务函数设计:
•基本程序设计,如流水灯,闪烁灯
参考程序:
实现LED1和LED2轮流闪烁的程序代码
VoidMain(void){
intflag,i;
Target_Init();
for(;
;
){
if(flag==0){
for(i=0;
i<
1000000;
i++);
//延时
rGPGCON=rGPGCON&
0xfff0ffff|0x00050000;
//配置第8、9位为输出引脚
rGPGDAT=rGPGDAT&
0xeff|0x200;
//第8位输出为低电平
//第9位输出为高电平
10000000;
flag=1;
}
else{
0xdff|0x100;
//第8位输出为高电平
//第9位输出为低电平
流水灯程序:
#defineoutled(*((volatileunsignedchar*)0x20000000))
voidledstep(void)
{
unsignedshortinti,j;
intk;
j=1;
for(i=8;
i>
0;
i--)
{
outled=~j;
//取反输出(只有一位亮)
for(k=0;
k<
k++);
//延时
j=j*2;
//左移一位
}
•绘图程序设计,如画矩形,平行四边形,网格,矩形填充等
(1)、常用绘图函数
GUI_Init(void);
//GUI初始化
voidDraw_Point(U16x,U16y);
//绘制点API
U32Get_Point(U16x,U16y);
//得到点API
voidDraw_HLine(U16y0,U16x0,U16x1);
//绘制水平线API
voidDraw_VLine(U16x0,U16y0,U16y1);
//绘制竖直线API
voidDraw_Line(I32x1,I32y1,I32x2,I32y2);
//绘制线API
voidDraw_Circle(U32x0,U32y0,U32r);
//绘制圆API
voidFill_Circle(U16x0,U16y0,U16r);
//填充圆API
voidFill_Rect(U16x0,U16y0,U16x1,U16y1);
//填充区域API
voidSet_Color(U32color);
//设定前景颜色API
voidSet_BkColor(U32color);
//设定背景颜色API
voidSet_Font(GUI_FONT*pFont);
//设定字体类型API
voidDisp_String(constI8*s,I16x,I16y);
//显示字体API
voidDelay(intCount);
//延时函数Count=10000时约1S
(2)、部分绘图函数使用方法
图形用户函数初值化GUI_Init();
设置颜色Set_Color(GUI_RED);
//设置绘图颜色为红色
画水平线Draw_HLine(10,10,50);
画填充矩形Fill_Rect(0,0,639,479);
//填充整个LCD
画填充圆Fill_Circle(100,100,25);
//在100,100坐标画半径25像素填充圆
•可参考的实验程序:
•1、在LCD画如下图案
•
(1)LCD底色为蓝色
•
(2)在LCD上设计一下8*10单元格,在每个格的中间画一个白色正方形
•(3)在LCD上画一下红色填充圆红色圆
•2、在LCD上画红色圆动画显示效果
•红色圆每移一格停约一秒,移动后应擦除
•3、在LCD上灰色填充物
•/#include"
..\..\Gui\Init\GUI_Init.h"
•#include"
..\gui\glib\glib.h"
..\lcddrv\inc\lcd.h"
..\..\lcddrv\inc\lcdlib.h"
target.h"
2410LIB.h"
2410addr.h"
•
•externGUI_FONTGUI_Font8x16;
•externGUI_FONTCHINESE_FONT12;
•externGUI_FONTCHINESE_FONT16;
•externvoid__caidan(void);
•U8gz[8][10]={
•{0,0,0,0,0,0,0,0,0,0},
•{0,0,0,0,0,0,0,0,0,0}
•};
•//0:
蓝底白点,1:
红色圆,2:
灰色墙}
•voidGeneration(U8x,U8y,U8style)
•{U8m;
•m=style;
•if(x<
8&
&
y<
10)
•{
•if(m==0)
•{Set_Color(GUI_BLUE);
•Fill_Rect(x*64,y*60,x*64+63,y*60+59);
//填充底色
•Set_Color(GUI_WHITE);
//设定前景颜色API
•Fill_Rect(x*64+30,y*60+28,x*64+34,y*60+32);
//白点画于网格中间
•};
•if(m==1)
•{Set_Color(GUI_RED);
•Fill_Circle(x*64+32,y*60+30,25);
•};
•if(m==2)
•{Set_Color(GUI_BROWN);
•Fill_Rect(x*64,y*60,x*64+63,y*60+14);
•Fill_Rect(x*64,y*60+30,x*64+63,y*60+44);
•Fill_Rect(x*64+20,y*60,x*64+39,y*60+59);
•};
•
•}
•}
•/*
•**********************************************
•-函数名称:
Main(void)
•-函数说明:
系统的主程序入口
•-输入参数:
无
•-输出参数:
•*/
•voidMain(void){
•intCount=3000;
•inti,j;
//widthandhigh
•Target_Init();
•GUI_Init();
•while
(1){
•
•Set_Color(GUI_BLUE);
•Fill_Rect(0,0,639,479);
•Set_Color(GUI_WHITE);
//设定前景颜色API
•//填充12*15白色网点(网点4*4)
•//每行10格,每列8格
•for(i=0;
8;
i++)//行号(0-7)
•for(j=0;
j<
10;
j++)//列号(0-9)
•Fill_Rect(j*64+30,i*60+28,j*64+34,i*60+32);
//每格64*60,白点画于网格中间
•}
•Set_Color(GUI_RED);
•Fill_Circle(96,30,25);
•Fill_Circle(32,30,25);
•Set_Color(GUI_BROWN);
•Fill_Rect(0,0,0+60,0+15);
•Fill_Rect(0,0+30,0+60,0+45);
•Fill_Rect(0+20,0,0+40,0+59);
•Generation(0,0,0);
•Generation(3,4,2);
•任务函数设计,如收发信号,邮箱,任务延时,创建任务等
消息邮箱:
主要内容:
任务的结构
开始多任务运行
任务间的消息邮箱通信
串口发送接收任务
包含图形界面的任务
任务的结构:
一个任务通常是一个无限的循环。
一个任务看起来像其它C的函数一样,有函数返回类型,有形式参数变量,但是任务是绝不会返回的。
任务完成后自我删除
voidYourTask(void*pdata)
{
/*用户代码*/
OSTaskDel(OS_PRIO_SELF);
}
voidYourTask(void*pdata)
(1)
){
(2)
/*用户代码*/
调用uC/OS-II的某种系统服务:
OSMboxPend();
OSQPend();
OSSemPend();
OSTaskSuspend(OS_PRIO_SELF);
OSTimeDly();
OSTimeDlyHMSM();
任务间的通信方式
共享内存
消息邮箱
信号量
消息队列
邮箱是μC/OS-II中另一种通讯机制,它可以使一个任务或者中断服务子程序向另一个任务发送一个指针型的变量。
该指针指向一个包含了特定“消息”的数据结构
中断程序中,只能用这种方式,无等待地从邮箱中得到消息
邮箱使用例子
voidTask_1(void*data)
{chartxmsg;
INT8Uerr;
data=data;
txmsg='
A'
for(;
){while(txmsg<
='
Z'
)
OSMboxPost(TxMbox,(void*)&
txmsg);
(1)
OSMboxPend(AckMbox,0,&
err);
(2)
txmsg++;
(3)重复发送A--Z字符到TxMbox邮箱,并等待接收AckMbox邮箱响应消息
txmsg='
}
voidTask_2(void*data)接收TxMbox邮箱消息,显示出来,并发送AckMbox邮箱响应消息
{char*rxmsg;
INT8Uerr;
data=data;
Timer1_Init();
OSTaskCreate(Task_1,
(void*)0,
(OS_STK*)&
Stack_Task_1[STACKSIZE-1],
9);
){
rxmsg=(char*)OSMboxPend(TxMbox,0,&
Uart_Printf("
char=%c\n"
*rxmsg);
OSTimeDlyHMSM(0,0,1,0);
//1秒后发响应消息
OSMboxPost(AckMbox,(void*)1);
主程序中创建邮箱,任务,并启动
OS_EVENT*TxMbox;
OS_EVENT*AckMbox;
voidMain(void)
{Target_Init();
//ARMII实验系统的初始化,包括CPU板
OSInit();
//操作系统的初始化
AckMbox=OSMboxCreate((void*)0);
TxMbox=OSMboxCreate((void*)0);
OSTaskCreate(Task_2,
(void*)0,
(OS_STK*)&
5);
OSStart();
用邮箱实现延时,而不使用OSTimeDly()
邮箱的等待超时功能可以被用来模仿OSTimeDly()函数的延时。
如果在指定的时间段TIMEOUT内,没有消息到来,Task1()函数将继续执行。
这和OSTimeDly(TIMEOUT)功能很相似。
但是,如果Task2()在指定的时间结束之前,向该邮箱发送了一个“哑”消息,Task1()就会提前开始继续执行。
OS_EVENT*MboxTimeDly;
voidTask1(void*pdata)
{INT8Uerr;
for(;
){OSMboxPend(MboxTimeDly,TIMEOUT,&
/*延时该任务*/
./*延时结束后执行的代码*/
voidTask2(void*pdata)
{for(;
){OSMboxPost(MboxTimeDly,(void*)1);
/*取消任务1的延时*/}
信号量-同步
串口接收缓冲区状态信号量
当接收到字符时,缓冲区有效,没有接收到字符时,缓冲区无效
任务2每次检测到串口接收到字符时,最发出串口缓冲区可用信号。
任务1在接收到任务2发来的信号后,把串口缓冲区的字符进行大小写转后并发到串口
voidTask_1(void*pdata)
Timer1_Init();
//打开定时器1,让操作系统运行起来
)
{OSSemPend(SendOneChar_Sem,0,&
//请求共享资源
if(ReceiveBuf>
64&
ReceiveBuf<
91)
{Uart_Select
(1);
Uart_Printf("
CHAR=%c\n"
(ReceiveBuf+32));
//输入大写,变成小写
96&
123)
(ReceiveBuf-32));
//输入小写,变成大写
}第二次运行任务时,由于SendOneChar_Sem为0(被占用),需释放后才能用
voidTask_2(void*pdata)
{Uart_Select(0);
ReceiveBuf=Uart_GetKey();
if(ReceiveBuf>
0)//接收串口数据
{Uart_Printf("
ReceiveBuf);
//任务的干得活儿就是向超级终端发送内容
OSSemPost(SendOneChar_Sem);
OSTimeDly(10);
//延时10个单位时间
用邮箱作二值信号量
一个邮箱可以被用作二值的信号量。
首先,在初始化时,将邮箱设置为一个非零的指针(如void*1)。
这样,一个任务可以调用OSMboxPend()函数来请求一个信号量,然后通过调用OSMboxPost()函数来释放一个信号量。
这样做可以节省代码空间。
这时可以将OS_SEM_EN设置为0,只使用邮箱就可以了。
OS_EVENT*MboxSem;
voidTask1(void*pdata)
{INT8Uerr;
OSMboxPend(MboxSem,0,&
/*获得对资源的访问权*/
/*任务获得信号量,对资源进行访问*/
OSMboxPost(MboxSem,(void*)1);
/*释放对资源的访问权*/
消息队列(邮箱阵列)
通过内核提供的服务,任务或中断服务子程序可以将一条消息(该消息的指针)放入消息队列。
同样,一个或多个任务可以通过内核服务从消息队列中得到消息。
发送和接收消息的任务约定,传递的消息实际上是传递指针指向的内容。
先进入消息队列的消息先传给任务,也就是说,任务先得到的是最先进入消息队列的消息,即先进先出原则(FIFO)。
消息队列举例-向队列发一个消息
voidTask1(void*data)
{char*txmsg;
inti;
txmsg=“ABCDEFGHIJK”;
//初始化时钟节拍
OSTaskCreate(Task_2,
Stack_Task_2[STACKSIZE-1],
7);
{for(i=0;
i++)
OSQPost(TxMbox,(void*)txmsg);
OSTimeDly(100);
(3)每100个节拍,向队列发一个消息
txmsg=“ABCDEFGHIJK”;
每秒钟从消息队列中取出4个消息
voidTask2(void*data)
){OSTimeDlyHMSM(0,0,1,0);
rxmsg=(char*)OSQPend(TxMbox,0,&
,*rxmsg);
主程序中创建队列,任务,并启动
void*ComMsg1[8];
//定义一个指针数组
//操作系统的初始