how to find out which rev

General programming chat and advice for beginners

24 posts
by rudiratlos » Sun Oct 21, 2012 11:08 am
Hi,
since there is a new rev2 board, which has a changed gpio header, it's required to detect on software level, on which rpi board revision the software is running on.

How to determine rev1 or rev2 ?

Is there a starting serialnumber, which indicates that the board is rev2 ?

thanx
Posts: 64
Joined: Tue May 01, 2012 8:47 am
by dom » Sun Oct 21, 2012 11:15 am
Code: Select all
cat /proc/cpuinfo

Code: Select all
Revision        : 100000f

Ignore the top 8 bits (which includes warranty bit). You want:
if ((revision & 0xffffff) >= 4) then rev2 else rev1.

Also:
if ((revision & 0xffffff) >= 10) then 512M else 256M.
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4013
Joined: Wed Aug 17, 2011 7:41 pm
Location: Cambridge
by ktownsend » Mon Dec 10, 2012 8:01 am
There seems to be a problem with the batch of 512MB boards I received a sample from, since my 512MB board clearly has the mounting holes and larger memory but /proc/cpuinfo always returns revision 0002 which is obviously incorrect:
Code: Select all
cat /proc/cpuinfo                           

OLD BOARD (no mounting holes)

Processor       : ARMv6-compatible processor rev 7 (v6l)                       
BogoMIPS        : 697.95                                                       
Features        : swp half thumb fastmult vfp edsp java tls                     
CPU implementer : 0x41                                                         
CPU architecture: 7                                                             
CPU variant     : 0x0                                                           
CPU part        : 0xb76                                                         
CPU revision    : 7                                                             
                                                                               
Hardware        : BCM2708                                                       
Revision        : 0002                                                         
Serial          : 000000007b108354 

512MB BOARD (has mounting holes)

webide@raspberrypi /usr/share/adafruit/webide/repositories $ cat /proc/cpuinfo 
Processor       : ARMv6-compatible processor rev 7 (v6l)                       
BogoMIPS        : 697.95                                                       
Features        : swp half thumb fastmult vfp edsp java tls                     
CPU implementer : 0x41                                                         
CPU architecture: 7                                                             
CPU variant     : 0x0                                                           
CPU part        : 0xb76                                                         
CPU revision    : 7                                                             
                                                                               
Hardware        : BCM2708                                                       
Revision        : 0002                                                         
Serial          : 0000000082a2c3ff               

The main problem here is that I need to detect the board version to point to the correct SMBus port in the Adafruit I2C libraries, and was hoping to use the revision but obviously this won't work.

I'm assuming this is the same issue mentionned here? viewtopic.php?p=226370#p226370

Is there an alternative method to detect the version in SW, since I'd really like to offer people a way to use I2C without having to figure out themselves which I2C bus they should be using?
Posts: 2
Joined: Mon Dec 10, 2012 7:56 am
by croston » Mon Dec 10, 2012 9:30 am
Are you using the latest firmware? (apt-get update && apt-get dist-upgrade)?
User avatar
Posts: 449
Joined: Sat Nov 26, 2011 12:33 pm
Location: Blackpool
by ktownsend » Mon Dec 10, 2012 11:26 am
Updating the distro fixes it, but it would be nice to know a SW work around to detect the version on faulty boards without the (hours long!) update. I'm sure there are a lot of people running the boards that report 0002 and they won't have a clue what the problem is or how to fix it, so I'd rather include something that solves the issue in any situation.
Posts: 2
Joined: Mon Dec 10, 2012 7:56 am
by Davespice » Mon Feb 04, 2013 11:12 pm
Hey folks. I have found myself in a situation where I need to do this too.
I wonder, is there any other programmatic way to do this other than to parse /proc/cpuinfo ?
User avatar
Raspberry Pi Foundation Employee & Forum Moderator
Raspberry Pi Foundation Employee & Forum Moderator
Posts: 1441
Joined: Fri Oct 14, 2011 8:06 pm
Location: London, United Kingdom
by joan » Mon Feb 04, 2013 11:18 pm
Depends on what you mean.

Many of the gpio libraries will "hint" at the board revision. As far as I'm aware the hint is based on the contents of /proc/cpuinfo.
User avatar
Posts: 5497
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK
by Davespice » Tue Feb 05, 2013 10:03 am
I need to know which board revision I'm running on so I can decide how to open my i2c device as i2c1 or i2c0.
User avatar
Raspberry Pi Foundation Employee & Forum Moderator
Raspberry Pi Foundation Employee & Forum Moderator
Posts: 1441
Joined: Fri Oct 14, 2011 8:06 pm
Location: London, United Kingdom
by croston » Tue Feb 05, 2013 10:23 am
Davespice wrote:I need to know which board revision I'm running on so I can decide how to open my i2c device as i2c1 or i2c0.

Code: Select all
cat /proc/cpuinfo

Look at the revision line. If it is 0002 or 0003 then you have a revision 1 board otherwise you have a revision 2 board.croston Posts: 216Joined: 26 Nov 2011 12:33Location: Blackpool
User avatar
Posts: 449
Joined: Sat Nov 26, 2011 12:33 pm
Location: Blackpool
by joan » Tue Feb 05, 2013 10:32 am
If you want to script the open something like

echo `awk '{if ($1=="Revision") print substr($3,length($3)-3)}' /proc/cpuinfo`

will return the revision as a string.
User avatar
Posts: 5497
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK
by Davespice » Tue Feb 05, 2013 11:10 am
Davespice wrote:Hey folks. I have found myself in a situation where I need to do this too.
I wonder, is there any other programmatic way to do this other than to parse /proc/cpuinfo ?

Obviously no one read my previous question. :D
I'm thinking c or c++.
User avatar
Raspberry Pi Foundation Employee & Forum Moderator
Raspberry Pi Foundation Employee & Forum Moderator
Posts: 1441
Joined: Fri Oct 14, 2011 8:06 pm
Location: London, United Kingdom
by joan » Tue Feb 05, 2013 11:15 am
Use code such as the following to find the hardware revision. Translate that in any way you choose to the gpio assignment.
Code: Select all
static unsigned intHardwareRevision(void)
{
   FILE * filp;
   unsigned rev;
   char buf[512];
   char term;

   rev = 0;

   filp = fopen ("/proc/cpuinfo", "r");

   if (filp != NULL)
   {
      while (fgets(buf, sizeof(buf), filp) != NULL)
      {
         if (!strncasecmp("revision\t", buf, 9))
         {
            if (sscanf(buf+strlen(buf)-5, "%x%c", &rev, &term) == 2)
            {
               if (term == '\n') break;
               rev = 0;
            }
         }
      }
      fclose(filp);
   }
   return rev;
}
User avatar
Posts: 5497
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK
by Davespice » Tue Feb 05, 2013 11:38 am
Yep, thanks for that. I can easily do this with a two line regex. But you’re still not reading my original question. Here it is again in big letters.

Davespice wrote:I wonder, is there any other programmatic way to do this other than to parse /proc/cpuinfo ?
User avatar
Raspberry Pi Foundation Employee & Forum Moderator
Raspberry Pi Foundation Employee & Forum Moderator
Posts: 1441
Joined: Fri Oct 14, 2011 8:06 pm
Location: London, United Kingdom
by joan » Tue Feb 05, 2013 11:51 am
Try understanding the answers you have been given. Also report your post for moderation!
User avatar
Posts: 5497
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK
by Davespice » Tue Feb 05, 2013 11:56 am
:D

What am I supposed to do if you're not reading my question, you're answering the questions you think I am asking.
User avatar
Raspberry Pi Foundation Employee & Forum Moderator
Raspberry Pi Foundation Employee & Forum Moderator
Posts: 1441
Joined: Fri Oct 14, 2011 8:06 pm
Location: London, United Kingdom
by dom » Tue Feb 05, 2013 11:59 am
Davespice wrote:Yep, thanks for that. I can easily do this with a two line regex. But you’re still not reading my original question. Here it is again in big letters.

Davespice wrote:I wonder, is there any other programmatic way to do this other than to parse /proc/cpuinfo ?

It might help if you said why you don't want to use the interface designed for the purpose. But the information could be derived from:
cat /proc/cmdline
vcgencmd otp_dump
or possibly by looking at some of the GPIOs that changed between rev1 and rev2. Set them to input and determine if they have pull up or pull downs. You'd need to study the schematic to determine if this is possible. (And it will be unreliable on cases where people have deviced connected to those gpio lines).
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4013
Joined: Wed Aug 17, 2011 7:41 pm
Location: Cambridge
by ShiftPlusOne » Tue Feb 05, 2013 12:02 pm
Davespice wrote::D

What am I supposed to do if you're not reading my question, you're answering the questions you think I am asking.


Why didn't you just say so!?
You can parse /proc/cpuinfo! :D

(I'll look into it and see if I can find anything.)
Forum Moderator
Forum Moderator
Posts: 1695
Joined: Fri Jul 29, 2011 5:36 pm
Location: The unfashionable end of the western spiral arm of the Galaxy
by Davespice » Tue Feb 05, 2013 12:08 pm
dom wrote:It might help if you said why you don't want to use the interface designed for the purpose. But the information could be derived from:
cat /proc/cmdline
vcgencmd otp_dump
or possibly by looking at some of the GPIOs that changed between rev1 and rev2. Set them to input and determine if they have pull up or pull downs. You'd need to study the schematic to determine if this is possible. (And it will be unreliable on cases where people have deviced connected to those gpio lines).

I was only wondering if there was easier way, some kernel function that could be called and would just return an integer for example. Instead of having to open the file, read it in as a string and then run a regex against it like so (?<=(Revision)\s{8}:\s)\d+.
User avatar
Raspberry Pi Foundation Employee & Forum Moderator
Raspberry Pi Foundation Employee & Forum Moderator
Posts: 1441
Joined: Fri Oct 14, 2011 8:06 pm
Location: London, United Kingdom
by RaTTuS » Tue Feb 05, 2013 12:15 pm
a model A reports a revision of 8
so that's going to put a spanner in the works
1QC43qbL5FySu2Pi51vGqKqxy3UiJgukSX - Prosliver FTW
"That's not right, the badgers have moved the goalposts."
User avatar
Posts: 5018
Joined: Tue Nov 29, 2011 11:12 am
Location: North West UK
by dom » Tue Feb 05, 2013 1:05 pm
Davespice wrote:I was only wondering if there was easier way, some kernel function that could be called and would just return an integer for example. Instead of having to open the file, read it in as a string and then run a regex against it like so (?<=(Revision)\s{8}:\s)\d+.

This:
https://github.com/raspberrypi/firmware ... -interface
is another solution.
But really joan's answer is the best and fastest solution. Note that opening /proc/cpuinfo doesn't even open a (sdcard) file - it is just a call into the kernel that returns a global variable.
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4013
Joined: Wed Aug 17, 2011 7:41 pm
Location: Cambridge
by Davespice » Tue Feb 05, 2013 1:22 pm
Thanks Dom, ShiftPlusOne pointed me here too;
https://github.com/raspberrypi/firmware ... -mailboxes

I'm going to give it a go this way and if I am successful I'll post the code.
User avatar
Raspberry Pi Foundation Employee & Forum Moderator
Raspberry Pi Foundation Employee & Forum Moderator
Posts: 1441
Joined: Fri Oct 14, 2011 8:06 pm
Location: London, United Kingdom
by gordon@drogon.net » Tue Feb 05, 2013 1:36 pm
dom wrote:
Davespice wrote:I was only wondering if there was easier way, some kernel function that could be called and would just return an integer for example. Instead of having to open the file, read it in as a string and then run a regex against it like so (?<=(Revision)\s{8}:\s)\d+.

This:
https://github.com/raspberrypi/firmware ... -interface
is another solution.
But really joan's answer is the best and fastest solution. Note that opening /proc/cpuinfo doesn't even open a (sdcard) file - it is just a call into the kernel that returns a global variable.


Or you can always use piBoardRev () that's been part of wiringPi since the Rev B's first came out ;-)

As for I2C - well, wiringPi supports that too - and even works out the board rev for you too...

-Gordon
--
Gordons projects: https://projects.drogon.net/
User avatar
Posts: 1520
Joined: Tue Feb 07, 2012 2:14 pm
Location: Devon, UK
by Davespice » Wed Feb 06, 2013 4:09 pm
Credit is due to ShiftPlusOne for working this out, I think we must have spent about two afternoons on it (I only managed a seg fault). After all that just parsing /proc/cpuinfo doesn't seem so bad :D

Queue the "I told you so" responses :oops:

Code: Select all
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <assert.h>
#include <stdint.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include "vcio.h"
 
int vcio_file;
 
static int mbox_property(int file_desc, void *buf)
{
        int ret_val = ioctl(file_desc, IOCTL_MBOX_PROPERTY, buf);
 
        if (ret_val < 0)
        {
        printf("ioctl_set_msg failed:%d\n", ret_val);
        }
 
        #ifdef DEBUG
                unsigned *p = message; int i; unsigned size = *(unsigned *)buf;
                for (i=0; i<size/4; i++)
                        printf("%04x: 0x%08x\n", i*sizeof *p, p[i]);
        #endif
        return ret_val;
}

static unsigned get_brevision(int file_desc)
{
        int i=0;
        unsigned p[32];
        p[i++] = 0; // size
        p[i++] = 0x00000000; // process request
 
        p[i++] = 0x00010002; // get board revision
        p[i++] = 0x00000004; // buffer size
        p[i++] = 0x00000000; // request size
        p[i++] = 0x00000000; // value buffer
        p[i++] = 0x00000000; // end tag
 
        p[0] = i*sizeof *p; // actual size
 
        mbox_property(file_desc, p);
        return p[5];
}
 
int main(int argc, char *argv[])
{
   //printf("Access: %d\n", access("/dev/vcio", F_OK));
   //printf("Mknod %d\n", mknod("/dev/vcio", S_IFCHR | 0666, makedev(100, 0)));
   
   if (access("/dev/vcio", F_OK) != 0)
   {
      //printf("access true\n");
      
      if (mknod("/dev/vcio", S_IFCHR | 0666, makedev(100, 0)) != 0)
      {
         //printf("mknod true\n");
         perror("mknod");
         return -1;
      }
      else
      {
         //printf("mknod false\n");
      }
   }
   else
   {
      //printf("access false\n");
   }

   vcio_file = open("/dev/vcio", O_RDONLY);
   if (vcio_file < 0)
   {
         perror("open");
         return -1;
   }

   printf("Board revision %d\n", get_brevision(vcio_file));

   return (0);
}
User avatar
Raspberry Pi Foundation Employee & Forum Moderator
Raspberry Pi Foundation Employee & Forum Moderator
Posts: 1441
Joined: Fri Oct 14, 2011 8:06 pm
Location: London, United Kingdom
by jdb » Tue Feb 04, 2014 12:55 pm
Or you can parse /proc/cmdline

There's an ATAGS entry for bcm2708.boardrev.
Keeper of the Proboscidean features
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 700
Joined: Thu Jul 11, 2013 2:37 pm