Compile Hello world


#1

Link Location of cross compile tools for CHIP is not working because of change in CHIP-SDK.
Right now, I don’t see where is “arm-linux-gnueabihf-gcc” described in Makefile.
Any update document on how to compile or usefull link ?


#2

Hello,

You can just change the first line of the Makefile to:
CCBASEDIR=/home/vagrant/CHIP-buildroot/output/host/usr

It worked on my side.

Nicolas


#3

@3Sigma Thanks…I forgot one major thing : compiling the buildroot :confounded:
Still compiling on the virtual machine … as I run an Ubuntu 14.04LTS I don’t understand why going to vbox. Shoud test directly later .
Thanks again and sorry for my mistake !


#4

@f5oeo
Its becoming more and more common to deliver virtual build machines. That way the product owners only have to worry about having things working in their virtual machine, instead on every single platform. So personally I think it is a really good to do so.

In general I would recommend it for someone new to buildroot/linux/u-boot/embedded development or those that just want something that works out of the box. Then for those brave souls that venture outside into the real world, they will learn a lot more on how things work and save some disk space for doing so.

As a final note, since you are on the same distro as the virtual machine, it should be relatively easy to get everything running on your local machine.

Cheers


#5

fwiw - the current version of virtualbox (5.0.4) has a bug with symlinks on some platforms that won’t let you compile buildroot with the provided virtual machine

it will fail with a series of errors in the format of
rsync: symlink "/home/vagrant/CHIP-SDK/CHIP-buildroot/output/target/var/run" -> "../run/" failed: Protocol error (71)

downgrading to 5.0.2 seems fine however


#6

Thanks for clarification…


#7

After a lonnnng time compilation, just see that I let make menuconfig with default parameters : target is x86 !
As I am a newbie in kernel compilation and menuconfig, is there a document to know which parameters to set (Target architecture ARM little endian, target architecture variant …).
Sorry for this basic question but could help other newbies !


#8

@f5oeo

You might want to base all your personalization on the default config for C.H.I.P

So run

make chip_defconfig

Then

make menuconfig

It is not only the hardware architecture that will be wrong if you don’t make a proper base config.

Cheers :slight_smile:


#9

@soderstrom Thanks a lot ! My chip is saying hello now !
Next : want to play with GPIO by writing to registry directly through /dev/mem like I do on Raspberry.


#10

@f5oeo

If you only wish to flip a pin or check its value etc. You can do as follows

Request / Release

You first have to request a GPIO. So if you wanted to request say GPIO 12, you would do

# echo 12 > /sys/class/gpio/export

If this is successful, you will find a /sys/class/gpio/gpio12/ directory.

When you have finnished using it, release it so other drivers can use it.

# echo 12 > /sys/class/gpio/unexport

Reading/Writing

In the specific GPIO directory, there will be two files: directory and value. Reading from them returns the current state (direction / value). Writing to them sets the current state.


  State  Description
  high   Set GPIO to an output with a starting value of 1
  low    Set GPIO to an output with a starting value of 0
  out    Same as 'low'
  in     Set GPIO to an input

Possible states for direction


The value field simply uses numeric values, that is 0 and 1.

Examples

To set GPIO 12 to an input

# echo in > /sys/class/gpio/gpio12/direction

To set GPIO 12 to a high output

echo high > /sys/class/gpio/gpio12/direction

To set GPIO 12’s value to 0

echo 0 > /sys/class/gpio/gpio12/value

To read GPIO 12’s current value

cat /sys/class/gpio/gpio12/value

Source: https://www.kernel.org/doc/Documentation/gpio/sysfs.txt

EDIT 1:

When you connect the C.H.I.P and check the /sys/class/gpio directory you will notice that gpiochip0 and gpiochip408 already present. These you most likely don’t won’t to fiddle with.

Also, please read up on how muxing works on the chip

Warning: incorrect usage of gpio pins can be dangerous

EDIT 2:
Form @renzo post Buttons and Leds on XIO I see that the gpiochip408 is the PCF8574A expander, So it should be safe to use. Lesson learned (hopefully).

Cheers
Rikard


A Layperson's Intro to GPIO: How to make things blink
Desiderata, who-does-what, chroot and search-engine-tagging
#11

Ok, that’s this “normal” way to access to gpio using kernel module. However, I want to hack more deeply with the register and GPIO. I use this way with Raspberry to produce HF on pin (meaning up to 500MHZ) though PWM. So I guess have to use /dev/mem to map and write on register on userland (which I know is not the linux standard way of doing).


#12

You can make do that with gpiofs. But it requires programming instead of using the shell :smile:

Something like this should get you started.

#include <stdio.h>
#include <stdlib.h>
 
int main()
{
    int fd;
 
    fd = open("/sys/class/gpio/export", O_WRONLY);
    if (fd < 0) return -1;
 
    write(fd, "12", 3); // TODO: Check return value
    close(fd);
 
    fd = open("/sys/class/gpio/gpio12/direction", O_RDWR);
    if (fd < 0) return -1;
 
    write(fd, "out", 4);
    close(fd);
 
    fd = open("/sys/class/gpio/gpio12/value", O_RDWR);
    if (fd < 0) return -1;
    
    for(int i=0; i< 1000000000; i++)
    {
        write(fd,"1", 2);
        write(fd,"0", 2);
    }
    close(fd);

    fd = open("sys/class/gpio/unexport", O_WRONLY);
    if (fd < 0) return -1;
    
    write(fd, "12", 3); // TODO: Check return value
    close(fd);
    return 0;
}

What is left to to is define how often it should toggle,and error handling ofc :wink:

If you need even finer grain of control you would have to construct a kernel space driver. Using /dev/mem to control gpio is not recommended.

EDIT 1:

It has been asked in other posts what the O_WRONLY, O_RDWR stands for, so just for completeness I also write them here.

Libc Standard File Access Modes
O_RDONLY - Open the file for read access.
O_WRONLY - Open the file for write access.
O_RDWR   - Open the file for both reading and writing.

http://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html
http://www.gnu.org/software/libc/manual/html_node/Access-Modes.html#Access-Modes

In response to: CHIP C++ GPIO use porting

Hope this helps

Cheers
Rikard


CHIP C++ GPIO use porting
CHIP C++ GPIO use porting
A Layperson's Intro to GPIO: How to make things blink
#13

am I also able to access this from chroot-debian?

maybe even via ssh?

could you give me a quick start how to issue commands like ssh and even further entries like the password from a c-file? I would be damn interested in this… you can’t imagine… :scream:

Solving this with private key and no pass required is also a work around but just as an example for understanding plz :smile:


#14

am I also able to access this from chroot-debian?

Yes, you should be able to with the correct permissions (not as a normal user but as root, or a group with access to sys/class)

maybe even via ssh?

Yes, if you allow sudo or su over ssh.

could you give me a quick start how to issue commands like ssh and
even further entries like the password from a c-file? I would be damn
interested in this… you can’t imagine… :scream:

Solving this with private key and no pass required is also a work around but just as an example for understanding plz :smile:

Sure thing, but we should do this is another thread. This thread is for “Compile hello world” or at least blinking LEDs.

Cheers


#15

I have modified this example, so you can compile and see a pulse in the pin xio-p0:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>    /* For O_RDWR */
#include <unistd.h>   /* For open(), creat() */

int main()
{
    int fd;
 
    fd = open("/sys/class/gpio/export", O_WRONLY);
    if (fd < 0) return -1;
 
    write(fd, "408", 3); // TODO: Check return value
    close(fd);
 
    fd = open("/sys/class/gpio/gpio408/direction", O_RDWR);
    if (fd < 0) return -1;
 
    write(fd, "out", 4);
    close(fd);
 
    fd = open("/sys/class/gpio/gpio408/value", O_RDWR);
    if (fd < 0) return -1;
    
    for(int i=0; i< 1000000000; i++)
    {//Generate pulses
        write(fd,"1", 2);
        write(fd,"0", 2);
    }

    fd = open("sys/class/gpio/unexport", O_WRONLY);
    if (fd < 0) return -1;
    
    write(fd, "408", 3); // TODO: Check return value
    close(fd);
    return 0;
}

#16

When I look into this I have a few questions:

  1. I see now that here are not different ways described about setting a pin to 1 / 0. Here is described that you first have to open the device tree, than specific the right port, saying that you want it as an INPUT/OUTPUT, and then issuing your 1 and 0’s and finally releasing this pin again.

Is this right?

But why do you not need to close fd after you have written all those 1/0’s?

  1. Can you or @soderstrom give an example how you would configure a INPUT pin? For reading some basic data? And what about ADC conversion? Value between 0-255 or even higher or less. PWM output and where do we have Interrupt Pins?

@gush maybe you could help here out a bit too. And I have a problem with the forum itself. I write here “2. Can you…” but the forum is thinking that I want to create a list. Is not seeing the “1.” in the top and therefore making my “2.” to a “1.” because it wants to make a nice list… Just a bug I thing I just found


#17

Two answers:

  1. I suspect that it was an unintentional omission to not close the FD on exit from the for loop. To be honest, I would consider it a small stylistic improvement to have separate file descriptor variables for each file. Another minor suggestion: change the direction of the pin back to “in” before unexporting it (I think the chip is in a slightly safer state if all pins are inputs).

  2. There is in fact no need to close that fd, nor the “direction” fd. Technically, the code is leaking file descriptors, which is bad form so please do the closes in your own code, but given that the program exits at the end, the OS will clean up any leaked file descriptors for you.

Oh, and just because I have a strange sense of humor, I numbered both of the above with “1”. I crack myself up!

I’ll add some related info. Note that the above sample code uses the low-level Unix-specific system calls “open”, “read”, “write”, “close”. But many (most?) C programmers would use the portable functions: fopen, fread, fwrite, and fclose. I haven’t tried them yet, but I suspect they will work fine, except for one thing: the portable functions add I/O buffering. Which is to say that when you open a file and write data to it, it may or may not flush the data to the device. Buffered I/O tries to convert large numbers of small writes into smaller numbers of large writes, which is much more efficient. But for device control, it can be a big problem.

For one thing, the pulses will probably come in batches, rather than a constant, steady square wave. (You can prevent this batching by using “fflush”.)

But it also makes it much more important to close the files when you’re done. If you let the program exit close the files implicitly, it won’t write out any partially-filled buffers. Specifically, if you change the above code to buffered I/O, I suspect the last bunch of writes will never make it to the device.


#18

Not that anybody asked, but I did a test and can verify that buffered I/O (fopen, etc) does work. As I suspected, you need to flush after every fprintf. I opened a thread asking for help from an oscilloscope owner to evaluate what happens when you don’t do the flushes. See Help: Oscilloscope owner?