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

在上盘博文中,成功将rtems移植到了bbb板上,在shell终端,输入hello,返回如下信息:

表明命令运行成功


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


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

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

bbb板运行rtems-编写led底层驱动_第1张图片


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   
#include   
#include   
#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函数在文件前面声明一下:

bbb板运行rtems-编写led底层驱动_第2张图片



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

#include   
#include   
#include   
#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依次闪烁。

你可能感兴趣的:(RTEMS,rtems开发)