u-boot下编写测试CPU的GPIO状态代码[转]

面对自己设计的新板子,基于freesclae的I.MX51 SOC,如果采购仿真器的话,据说连软件带硬件要7000美金,这实在是一笔不小的开销。但是,板子总是需要使用软件方法来测试的,特别是IO的基本功能。那么在u-boot下写一些有关的测试程序是很有必要的。虽然这个方法无法和仿真器相比,但是只要板子boot起来,那么使用底层的IO函数,进行适当的“裸奔”,对设计者来说,总算是有点“招”了。

    本文编写了一个gpio_ctrl程序,在u-boot启动后的命令行运行,直接对SOC的GPIO端口进行高低电平测试。实际就是对u-boot 的命令进行一次自己需要性的扩展。具体做的方法如下:

1、添加命令标志CONFIG_CMD_GPIOCTRL

      打开u-boot/include/config_cmd_default.h

添加:


#define CONFIG_CMD_GPIOCTRL

2、编写代码

     在u-boot/commom目录下,建立一个gpio_ctrl.c空文件,并编写代码:

#include
#include
#include
#include
#include
#include

 

struct gpio_out_list {
 char  strPinName[20];
 int   nGroup;
 int  bit;
 unsigned int PIN;
};


static struct gpio_out_list gpio_list[] = {
    {"EIM_D17",2,1,MX51_PIN_EIM_D17},
    {"EIM_D18",2,2,MX51_PIN_EIM_D18},
    {"EIM_D22",2,6,MX51_PIN_EIM_D22},
    {"EIM_A16",2,10,MX51_PIN_EIM_A16},
    {"EIM_A18",2,12,MX51_PIN_EIM_A18},
    {"EIM_A20",2,14,MX51_PIN_EIM_A20},
    {"EIM_A21",2,15,MX51_PIN_EIM_A21},
    {"EIM_A22",2,16,MX51_PIN_EIM_A22},
    {"EIM_A23",2,17,MX51_PIN_EIM_A23},
    {"EIM_A24",2,18,MX51_PIN_EIM_A24},
    {"EIM_A25",2,19,MX51_PIN_EIM_A25},
    {"EIM_A26",2,20,MX51_PIN_EIM_A26},
    {"EIM_A27",2,21,MX51_PIN_EIM_A27},
    {"EIM_CS1",2,26,MX51_PIN_EIM_CS1},
    {"EIM_OE",2,24,MX51_PIN_EIM_OE},
    {"EIM_DTACK",2,31,MX51_PIN_EIM_DTACK},
    {"NANDF_RB1",3,9,MX51_PIN_NANDF_RB1},
    {"NANDF_CS0",3,16,MX51_PIN_NANDF_CS0},
    {"NANDF_CS1",3,17,MX51_PIN_NANDF_CS1},
    {"NANDF_D0",4,8,MX51_PIN_NANDF_D0},
    {"NANDF_D1",4,7,MX51_PIN_NANDF_D1},
    {"NANDF_D3",4,5,MX51_PIN_NANDF_D3},
    {"NANDF_D4",4,4,MX51_PIN_NANDF_D4},
    {"NANDF_D5",4,3,MX51_PIN_NANDF_D5},
    {"NANDF_D6",4,2,MX51_PIN_NANDF_D6},
    {"NANDF_D14",3,26,MX51_PIN_NANDF_D14},
    {"NANDF_D15",3,25,MX51_PIN_NANDF_D15},
    {"CSI1_D9",3,13,MX51_PIN_CSI1_D9},
    {"CSI2_D12",4,9,MX51_PIN_CSI2_D12},
    {"CSI2_D13",4,10,MX51_PIN_CSI2_D13},
    {"CSI2_D18",4,11,MX51_PIN_CSI2_D18},
    {"CSI2_D19",4,12,MX51_PIN_CSI2_D19},
    {"CSI2_VSYNC",4,13,MX51_PIN_CSI2_VSYNC},
    {"CSI2_HSYNC",4,14,MX51_PIN_CSI2_HSYNC},
    {"CSI2_PIXCLK",4,15,MX51_PIN_CSI2_PIXCLK},
    {"DISP2_DAT6",1,19,MX51_PIN_DISP2_DAT6},
    {"DISP2_DAT7",1,29,MX51_PIN_DISP2_DAT7},
    {"DISP2_DAT9",1,31,MX51_PIN_DISP2_DAT9},
    {"DISP2_DAT11",1,10,MX51_PIN_DISP2_DAT11},
    {"DISPB2_SER_RS",3,8,MX51_PIN_DISPB2_SER_RS},
    {"DISPB2_SER_CLK",3,7,MX51_PIN_DISPB2_SER_CLK},
    {"DISPB2_SER_DIN",3,5,MX51_PIN_DISPB2_SER_DIN},
    {"DI1_D1_CS",3,4,MX51_PIN_DI1_D1_CS},
    {"DI1_D0_CS",3,3,MX51_PIN_DI1_D0_CS},
    {"DI1_PIN13",3,2,MX51_PIN_DI1_PIN13},
    {"DI1_PIN12",3,1,MX51_PIN_DI1_PIN12},
    {"DI1_PIN11",3,0,MX51_PIN_DI1_PIN11},
    {"0",-1,-1,0} 
};

int _atoi(char );
int _listlen(struct gpio_out_list *);

int _listlen(struct gpio_out_list *pList)
{
 int nlen = 0;
 while(pList[nlen].PIN !=0)
 {
  nlen++;
 }
 return nlen;
}

int _atoi(char strInt)
{
 int nInteger = strInt - 0x30;
 return nInteger;
}

int do_gpio_out(cmd_tbl_t *cmdtp,int flag,int argc,char *argv[])
{

 printf("argc = %d\n",argc);
 printf("argv[0] = %s\n",argv[0]);
 printf("argv[1] = %s\n",argv[1]);
 printf("argv[2] = %s\n",argv[2]);
 
 int nLevel = _atoi(argv[2][0]);
 printf("nLevel is -\n",nLevel);
 
 
 int i=0;
 int cmp = -1;
 int bFound = 0;
 int nPosInList=-1;
 int nLen = _listlen(gpio_list);
 printf("list length is = -\n",nLen);
 for(i=0;i
 {
  cmp = strcmp(argv[1],gpio_list[i].strPinName);
  if(cmp == 0)
  {
   bFound = 1;
   nPosInList = i;
   break;
  }
 }
 
 if(bFound==0)
 {
  printf("Can't find pin name!\n");
  return -1;
 }
 
 
 unsigned int GPIO_BASE_ADDR;
 if(gpio_list[nPosInList].nGroup == 1)
 {
  GPIO_BASE_ADDR = GPIO1_BASE_ADDR;
 }
 else if(gpio_list[nPosInList].nGroup == 2)
  {
   GPIO_BASE_ADDR = GPIO2_BASE_ADDR;
  }
  else if(gpio_list[nPosInList].nGroup == 3)
   {
    GPIO_BASE_ADDR = GPIO3_BASE_ADDR;
   }
   else if(gpio_list[nPosInList].nGroup == 4)
    {
     GPIO_BASE_ADDR = GPIO4_BASE_ADDR;
    }
    else
     return -1;
 
 unsigned int uTempReg = 1 << gpio_list[nPosInList].bit;
 
 
 int result = mxc_request_iomux(gpio_list[nPosInList].PIN, IOMUX_CONFIG_GPIO);
 if(result!=0)
 {
  printf("request iomux failed\n");
  return -1;
 }
 
 
 unsigned int reg = readl(GPIO_BASE_ADDR + 0x0);
 
 switch(nLevel)
 {
  case 1:
   {
    
    reg |=uTempReg;
    writel(reg, GPIO_BASE_ADDR + 0x0);
    printf("Set EIM_D22 PIN to High\n");
     
    
    reg = readl(GPIO_BASE_ADDR + 0x4);
    reg |= uTempReg;
    writel(reg, GPIO_BASE_ADDR + 0x4);
   }
   break;
  case 0:
   {
    reg &=~uTempReg;
    writel(reg, GPIO_BASE_ADDR + 0x0);
    printf("Set EIM_D22 PIN to Low\n");
     
    
    reg = readl(GPIO_BASE_ADDR + 0x4);
    reg |= uTempReg;
    writel(reg, GPIO_BASE_ADDR + 0x4);
   }
   break;
  default:
   break;
 }
 mxc_free_iomux(gpio_list[nPosInList].PIN,IOMUX_CONFIG_GPIO);

 return 0;
}

U_BOOT_CMD(gpio_out,3,1,do_gpio_out,"usage: gpio_out PIN_NAME 1 or 0\n","This is a command to test gpio pins for I.MX51 SOC\n");

上面代码比较简单,熟悉C语言,一看就懂。该程序的用法就是:> gpio_out EIM_D22 1 表示对EIM_D22引脚进行输出高电平操作;如果是:> gpio_out EIM_D22 0,就是进行低电平操作。如果控制其他引脚,把EIM_D22换成其他PIN的名字。

3、修改一下u-boot/commom/Makefile文件

#this is added by wigros
ifdef CONFIG_CMD_GPIOCTRL
COBJS-$(CONFIG_CMD_GPIOCTRL) += gpio_ctrl.o
endif

4、回到u-boot顶层目录

> make cft8851_config   # 调入自己板子配置

> make  # 完成make后,就得到u-boot.bin文件

5、把得到的u-boot.bin文件烧入板子NOR FLASH,启动板子进入u-boot命令行,输入help,就能看到gpio_ctrl命令被列出来。

     说明:本程序可以进行对SOC的所有GPIO输出端口进行测试。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值