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
how to find out which rev
23 posts
- Posts: 59
- Joined: Tue May 01, 2012 8:47 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.
- Moderator
- Posts: 3248
- Joined: Wed Aug 17, 2011 7:41 pm
- Location: Cambridge
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:
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?
- 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
Are you using the latest firmware? (apt-get update && apt-get dist-upgrade)?
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
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 ?
I wonder, is there any other programmatic way to do this other than to parse /proc/cpuinfo ?
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.
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.
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.
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
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.
echo `awk '{if ($1=="Revision") print substr($3,length($3)-3)}' /proc/cpuinfo`
will return the revision as a string.
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.
I'm thinking c or c++.
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;
}
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 ?
Try understanding the answers you have been given. Also report your post for moderation!
What am I supposed to do if you're not reading my question, you're answering the questions you think I am asking.
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).
- Moderator
- Posts: 3248
- Joined: Wed Aug 17, 2011 7:41 pm
- Location: Cambridge
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!
(I'll look into it and see if I can find anything.)
- Moderator
- Posts: 626
- Joined: Fri Jul 29, 2011 5:36 pm
- Location: The unfashionable end of the western spiral arm of the Galaxy
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+.
a model A reports a revision of 8
so that's going to put a spanner in the works
so that's going to put a spanner in the works
1QC43qbL5FySu2Pi51vGqKqxy3UiJgukSX - Prosliver FTW
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.
- Moderator
- Posts: 3248
- Joined: Wed Aug 17, 2011 7:41 pm
- Location: Cambridge
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.
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.
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
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
Queue the "I told you so" responses
Queue the "I told you so" responses
- 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);
}