您的位置:首页 > 其它

bbb板运行rtems-编写led底层驱动

2016-09-23 15:03 302 查看
在上盘博文中,成功将rtems移植到了bbb板上,在shell终端,输入hello,返回如下信息:



表明命令运行成功

接下来写一个bbb板上4个led的驱动程序,使得在shell下输入led命令,可以使得led 闪烁

首先要知道寄存器的内存地址,在这里需要查询处理器的说明手册:AM335X Technical Reference Manual.pdf

查到外设储存器映射地址如下:



GPIO1的起始地址是:0x4804c000

AM335X 共4组 GPIO 模块,每组 32 pins
USR0~USR3 对应 GPIO1_21~GPIO1_24
GPIO_OE1: 第一组 GPIO 输出允许(每一位对应一只GPIO引脚,0-输出,1-输入)
GPIO_CLR1: GPIO 引脚清"0" (写 "1" 清0,写"0"无效)
GPIO_SET1: GPIO 引脚置"1" (写 "1" 置1,写"0"无效)
GPIO_OUT1: 输出控制


程序中宏定义地址:

#define GPIO1           0x4804C000
#define GPIO_OE1      (GPIO1+0x134)
#define GPIO_OUT1     (GPIO1+0x13C)
#define GPIO_CLR1     (GPIO1+0x190)
#define GPIO_SET1     (GPIO1+0x194)


将 GPIO1_21~GPIO1_24 设为输出:
*(int *)GPIO_OE1 &= ~(0xf<<21);


4个LED亮:
*(int *)GPIO_CLR1 |= (0xf<<21);
或者    *(int *)GPIO_OUT1 &= ~(0xf<<21);
4个LED灭:
*(int *)GPIO_SET1 |= (0xf<<21);
或者    *(int *)GPIO_OUT1 |= (0xf<<21);


因此编写程序led_cmd.c:

#include <stdlib.h>
#include <stdio.h>
#include <bsp.h>
#define GPIO1 0x4804C000
#define GPIO_OE1 (GPIO1+0x134)
#define GPIO_OUT1 (GPIO1+0x13C)
#define GPIO_CLR1 (GPIO1+0x190)
#define GPIO_SET1 (GPIO1+0x194)
int led_command( int argc, char *argv[])
{
printf("LED TASK\n");
int i=0;
while (1)
{
for(i=0;i<4;i++)
{
if(i!=4)
{
*(int *)GPIO_OE1 = ~(1<<(21+i));
rtems_task_wake_after( 100 );
*(int *)GPIO_OUT1 = ~(1<<(21+i));
rtems_task_wake_after( 50 );
*(int *)GPIO_OUT1 = 0xf<<21;
}
else
i=0;
}

}
return 0;
}


然后在local_shell_cmd.c 文件的int rtems_add_local_cmds(void)函数中加入一行函数:

rtems_shell_add_cmd("led","misc","this is my fisrt driver",led_command);//c add

int rtems_add_local_cmds(void)
{
/*
** Add commands
*/
rtems_shell_add_cmd("netsetup","misc","setup and start networking",net_setup_command);

rtems_shell_add_cmd("hello","misc","Say hello RTEMS!",hello_command);

rtems_shell_add_cmd("led","misc","this is my fisrt driver",led_command);//c add

rtems_shell_add_cmd("taskdemo","misc","run a set of tasks",task_command);

rtems_shell_add_cmd("dhrystone","misc","Run the Dhrystone Benchmark",dhrystone_command);

rtems_shell_add_cmd("whetstone","misc","Run the Whetstone Benchmark",whetstone_command);

shell_init_script();

/*
** Setup the shell
*/
shell_start ();

return(0);

}

可以看出这个函数主要是用来增加命令的,然后将led_command函数在文件前面声明一下:



然后编写led_cmd.c 文件如下:

#include <stdlib.h>
#include <stdio.h>
#include <bsp.h>
#define GPIO1 0x4804C000
#define GPIO_OE1 (GPIO1+0x134)
#define GPIO_OUT1 (GPIO1+0x13C)
#define GPIO_CLR1 (GPIO1+0x190)
#define GPIO_SET1 (GPIO1+0x194)
int led_command( int argc, char *argv[])
{
printf("LED TASK\n");
int i=0;
while (1)
{
for(i=0;i<4;i++)
{
if(i!=4)
{
*(int *)GPIO_OE1 = ~(1<<(21+i));
rtems_task_wake_after( 100 );
*(int *)GPIO_OUT1 = ~(1<<(21+i));
rtems_task_wake_after( 50 );
*(int *)GPIO_OUT1 = 0xf<<21;
}
else
i=0;
}

}
return 0;
}



这个函数就是定义了led_command函数具体的实现,然后在makefile文件中添加这个led_cmd.c的编译信息,确保函数能够被找到。这和在windows下进行嵌入式开发不同,windows下的ide是写好的,要跨文件找到函数需要在头文件中声明,在编译时ide会先编译h头文件找到这些声明的函数。在linux下,makefile可以自己定义,相当于编译器自己写,makefile如下:

OBJS += task_cmd.o
OBJS += hello_cmd.o
OBJS += led_cmd.o
OBJS += dhrystone_cmd.o
OBJS += whetstone_cmd.o
OBJS += benchmarks.o

加上led_cmd.o 文件进行链接。

然后输入make进行编译,通过后继续生成rki.elf和img镜像,烧入sd卡,上电,boot,输入led命令可看到四个user led依次闪烁。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: