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

来源:互联网 发布:dlp数据加密 沙箱 编辑:程序博客网 时间:2024/06/05 14:43

在上盘博文中,成功将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.oOBJS += hello_cmd.oOBJS += led_cmd.oOBJS += dhrystone_cmd.oOBJS += whetstone_cmd.oOBJS += benchmarks.o

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


然后输入make进行编译,通过后继续生成rki.elf和img镜像,烧入sd卡,上电,boot,输入led命令可看到四个user led依次闪烁。

0 0