BeagleBone Black Multiplexing

Okay, found it. For anyone who wants to know the logic.

If you wanted to mux P8:31 you need to understand what the base + offset address is for the control register of the particular pin/ball you want to mux.

AM335x Technical Reference Manual, Section 2 lists the memory map. You will need to base address of the control registers. It lists the region name, start address, end address, size, and description. The Control Module is found on page 158 of this section. The beginning address is 0x44E1_0000. This the base address for the control module.

AM335x Technical Reference Manual. section 9.3 lists all the control module registers.

The BeagleBone Black P8:31 Mode[0] is called out as lcd_data14 is the SRM.
If you look up conf_lcd_data14 in the list of control module registers, you will see that the offset is 8D8h (Eureka!).

Now if you want to mux that pin to operate in Mode[4] uart5_rxd, you would simply mmap a page of memory that contains the address 0x44E10000+8D8. Xor that address within the memory map with 0x04. That should do it.

Someone call me out if I am incorrect.

Any of the libraries that I have obtained that try to do it that way die when they attempt to set the MUX. Now I’m a Kernel moron, but my understanding is that under the 3.8 kernel you are not permitted to simply go in and MMAP to the MUX settings and alter them. It’s all owned by DeviceTree. Both libraries I looked at seemed to do it the way you described and both compiled fine, but blew up when they tried to write to the memory.

Good to know. I have yet to try this out on a 3.8 kernel. What is the error number that was being set? All the code I will write for such a task is in user space. I will be attempting to do an anonymous mmap on /dev/mem at the address locations I specified earlier.

Now if the kernel is marking the location as private or secured, then I will get a permissions error.

Just curious is all.

On Arch just get “Segmentation Fault”, on Angstrom I think it was “Segmentation Fault – Bus Error”.

Yeah, I’ve header the same. The kernel doesn’t allow MMAP to the mux regions. We really need to get a group of use together and write some tutorials on muxing pins using 3.8. This is probably the biggest hurdle for anyone new to the BBB, so it would be really great to have some docs everyone can work with.

I am able to read the registers, but I cannot write to them for some reason. I am wondering if there is a bit I need to flip in order to make it work? I am using ubuntu with kernel version 3.8.11 that I compiled myself.

`
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <errno.h>
#include <string.h>
#include <stdint.h>

static volatile uint32_t *mux;

int main(int argc, char **argv)
{
int fd ;

if ((fd = open ("/dev/mem", O_RDWR | O_SYNC) ) < 0) {
printf(“Unable to open /dev/mem: %s\n”, strerror(errno));
return -1;
}

//the control register is 8192 bytes in length and begins at 0x44E10000
mux = (uint32_t *) mmap(0, getpagesize()*2, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x44E10000);

//this write does nothing???
//0x8D8 is the conf_lcd_data14 register which correlates to P8:31
mux[0x000008D8 / 4] = 0x04;

//However, I can read
printf(“Register: 0x%x\n”, mux[0x000008D8 / 4]);

close(fd);
}
`

Mickey, thanks for your explanation on how to correlate the BBB SRM with the ARM TRM/pin address offsets etc. I believe that accessing the pin mux on kernel 3.8 should be done via the capemgr and devicetree overlays as described in https://github.com/jadonk/validation-scripts/tree/master/test-capemgr. This is all very new to me and I hope I am not spreading bad information, but armed (no pun intended) with both pieces I think I may have a chance of success :-\

Dave.

Yep, looks like that is going to be the direction that I have to take. I looked into the MMU source for arm and it looks like read/write is still supported on /dev/mem, but it is heavily commented that this may go away in the future and it should not be done. From a security stand point without involving selinux, this is definitely needed.

Looks like the device-tree is the way multiplexing will have to occur on the beagle bone black running a 3.8 kernel.