Raspberry pi zero 2 w cmake command - file

What's the way of entering
cmake .. -DRPI2=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo
On the raspberry pi zero 2 w
Doesnt work
cmake .. -DRPIZero2=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo

Related

Logging from a C program on boot

I have a C program running on raspberry pi boot from /etc/rc.local:
bash -c 'MY_PATH/MY_FILE > /MY_PATH/MY_LOG_FILE 2>&1' &
Is this correct to write a log file from the C program when the raspberry pi boots?
Using the April 2022 raspbian, I tested both console/lite and Desktop Raspios.
Added this line to /etc/rc.local:
bash -c '/usr/bin/uname > /tmp/MY_LOG_FILE 2>&1' &
Rebooted, and check the log:
$ cat /tmp/MY_LOG_FILE
Linux
Both confirmed working.

How to distribute an application using shared library on Linux

My app uses library: boost, ffmpeg (avcodec, avformat,...). I want to pack my app to run on Ubuntu 14 or higher. I don't want to use static build.
I have checked on some computers which install Ubuntu. Here is results:
Ubuntu 14.04:
ls -l libavcodec*
libavcodec.a
libavcodec.so -> libavcodec.so.54.35.1
libavcodec.so.54.35.1
ls -l libboost_thread*
libboost_thread.a
libboost_thread.so -> libboost_thread.so.1.54.0
libboost_thread.so.1.54.0
Ubuntu 16.04:
ls -l libavcodec*
libavcodec.a -> libavcodec-ffmpeg.a
libavcodec-ffmpeg.a
libavcodec-ffmpeg.so -> libavcodec-ffmpeg.so.56.60.100
libavcodec-ffmpeg.so.56 -> libavcodec-ffmpeg.so.56.60.100
libavcodec-ffmpeg.so.56.60.100
libavcodec.so -> libavcodec-ffmpeg.so
ls -l libboost_thread*
libboost_thread.a
libboost_thread.so -> libboost_thread.so.1.58.0
libboost_thread.so.1.58.0
My app
objdump -p ControlStation | grep NEEDED
NEEDED libavcodec-ffmpeg.so.56
NEEDED libavformat-ffmpeg.so.56
NEEDED libavutil-ffmpeg.so.54
NEEDED libswscale-ffmpeg.so.3
NEEDED libboost_system.so.1.58.0
NEEDED libboost_thread.so.1.58.0
....
I compile on Ubuntu 16, so my app uses file libavcodec-ffmpeg.so.56 and libboost_thread.so.1.58.0. Therefore, it couldn't run on other computers.
Normally, a shared library should be
libName.so ---> libName.so.MAJOR
libName.so.MAJOR --> real library file
But ffmpeg has many versions, boost library doesn't have symbolic file libboost_thread.so.1
Could anyone help me about this problem ? Thank you !

How to run a C program with no OS on the Raspberry Pi?

I'd like to experiment using the Raspberry Pi for some different low level embedded applications. The only problem is that, unlike the AVR and PIC microcontroller boards available, Raspberry Pi typically runs an OS (like Raspbian) that distributes CPU time across all running programs and makes it impractical for certain real time applications.
I've recently learned that, assuming you have a bootloader like GRUB installed, running a C program on x86 (in the form of a kernel) takes very little actual setup, just an assembly program to call the main function and the actual C code.
Is there a way to achieve this with a Raspberry Pi?
It'd be a great way to learn about low level ARM programming, and it already has a few complex peripherals to mess around with (USB, Ethernet, etc.)
Fully automated minimal bare metal blinker example
Tested on Ubuntu 16.04 host, Raspberry Pi 2.
https://github.com/dwelch67/raspberrypi is the most comprehensive example set I've seen to date (previously mentioned on this now deleted answer), but this is a minimal easy to setup hello world to get you started quickly.
Usage:
Insert SD card on host
Make the image:
./make.sh /dev/mmblck0 p1
Where:
/dev/mmblck0 is the device of the SD card
p1 is the first partition of the device (/dev/mmblck0p1)
Inset SD card on PI
Turn power off and on
GitHub upstream: https://github.com/cirosantilli/raspberry-pi-bare-metal-blinker/tree/d20f0337189641824b3ad5e4a688aa91e13fd764
start.S
.global _start
_start:
mov sp, #0x8000
bl main
hang:
b hang
main.c
#include <stdint.h>
/* This is bad. Anything remotely serious should use timers
* provided by the board. But this makes the code simpler. */
#define BUSY_WAIT __asm__ __volatile__("")
#define BUSY_WAIT_N 0x100000
int main( void ) {
uint32_t i;
/* At the low level, everything is done by writing to magic memory addresses.
The device tree files (dtb / dts), which are provided by hardware vendors,
tell the Linux kernel about those magic values. */
volatile uint32_t * const GPFSEL4 = (uint32_t *)0x3F200010;
volatile uint32_t * const GPFSEL3 = (uint32_t *)0x3F20000C;
volatile uint32_t * const GPSET1 = (uint32_t *)0x3F200020;
volatile uint32_t * const GPCLR1 = (uint32_t *)0x3F20002C;
*GPFSEL4 = (*GPFSEL4 & ~(7 << 21)) | (1 << 21);
*GPFSEL3 = (*GPFSEL3 & ~(7 << 15)) | (1 << 15);
while (1) {
*GPSET1 = 1 << (47 - 32);
*GPCLR1 = 1 << (35 - 32);
for (i = 0; i < BUSY_WAIT_N; ++i) { BUSY_WAIT; }
*GPCLR1 = 1 << (47 - 32);
*GPSET1 = 1 << (35 - 32);
for (i = 0; i < BUSY_WAIT_N; ++i) { BUSY_WAIT; }
}
}
ldscript
MEMORY
{
ram : ORIGIN = 0x8000, LENGTH = 0x10000
}
SECTIONS
{
.text : { *(.text*) } > ram
.bss : { *(.bss*) } > ram
}
make.sh
#!/usr/bin/env bash
set -e
dev="${1:-/dev/mmcblk0}"
part="${2:-p1}"
part_dev="${dev}${part}"
mnt='/mnt/rpi'
sudo apt-get install binutils-arm-none-eabi gcc-arm-none-eabi
# Generate kernel7.img
arm-none-eabi-as start.S -o start.o
arm-none-eabi-gcc -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding -c main.c -o main.o
arm-none-eabi-ld start.o main.o -T ldscript -o main.elf
# Get the raw assembly out of the generated elf file.
arm-none-eabi-objcopy main.elf -O binary kernel7.img
# Get the firmware. Those are just magic blobs, likely compiled
# from some Broadcom proprietary C code which we cannot access.
wget -O bootcode.bin https://github.com/raspberrypi/firmware/blob/597c662a613df1144a6bc43e5f4505d83bd748ca/boot/bootcode.bin?raw=true
wget -O start.elf https://github.com/raspberrypi/firmware/blob/597c662a613df1144a6bc43e5f4505d83bd748ca/boot/start.elf?raw=true
# Prepare the filesystem.
sudo umount "$part_dev"
echo 'start=2048, type=c' | sudo sfdisk "$dev"
sudo mkfs.vfat "$part_dev"
sudo mkdir -p "$mnt"
sudo mount "${part_dev}" "$mnt"
sudo cp kernel7.img bootcode.bin start.elf "$mnt"
# Cleanup.
sync
sudo umount "$mnt"
QEMU friendly bare metal examples
The problem with the blinker is that it is hard to observe LEDs in QEMU: https://raspberrypi.stackexchange.com/questions/56373/is-it-possible-to-get-the-state-of-the-leds-and-gpios-in-a-qemu-emulation-like-t
Here I describe some bare metal QEMU setups that may be of interest: How to make bare metal ARM programs and run them on QEMU? Writing to the UART is the easiest way to get output out from QEMU.
How well QEMU simulates the Raspberry Pi can be partially inferred from: How to emulate Raspberry Pi Raspbian with QEMU? Since even the Linux terminal shows up, it is likely that your baremetal stuff will also work.
Bonus
Here is an x86 example for the curious: How to run a program without an operating system?
While bare metal is possible on the Pi, I would avoid it since Linux is getting so lightweight and handles a whole bunch of stuff for you.
Here's a tutorial to get you started if you want to still learn bare metal stuff: http://www.valvers.com/open-software/raspberry-pi/step01-bare-metal-programming-in-cpt1/
With all that said, I would just load up your favorite embedded linux distro (RT patched might be preferred based on your requirements) and call it good.
https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ is a great tutorial, and as they'll tell you the best quick and dirty way to run code on bare metal is to hijack a linux distro, to do that, just compile to kernel.img (with the appropriate architecture options) and use it to replace the existing one in the linux distro
for just this section of the tutorial you can go to:
https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ok01.html#pitime
The Pi may be a bit suboptimal for what you are wanting to do, since the SoC design is such that the ARM CPU is a second-class citizen - meaning there are some hoops to jump through to get a bare metal program running on it.
However, you could cheat a bit and use the U-Boot API to give you access to some of the features U-Boot provides but be able to add your own features on the side.

Writing R extensions in C (SHMGET crash in C)

I try to create a shared memory about cygwin in a Windows 7 environment. I compile it as normal c-program, all is working fine. If I try to call the function as R-Extension, the shmget-function is going crashed. The next step is to use semaphore. I hope this will run as well, if I solve this problem.
Is there any compiler option or something like else what I have to do? Maybe, have I to change the mingw to cygwin in R or what can I do. I'm really frustrated!
Actually I try to compile the extension with:
R CMD SHLIB wrappers.c IPC.c -Wall -pthread
And this is the problem child:
_smID = shmget(SHAREDMEMORYID, sizeof(struct sSharedMemory), IPC_CREAT |0666);
My R version:
_
platform x86_64-w64-mingw32
arch x86_64
os mingw32
system x86_64, mingw32
status
major 3
minor 1.0
year 2014
month 04
day 10
svn rev 65387
language R
version.string R version 3.1.0 (2014-04-10)
nickname Spring Dance
cygwin is up to date.

Problem with loading compiled c code in R x64 using dyn.load

I recently went from a 32bit laptop to a 64bit desktop (both win7). I just found out that I get an error now when loading dll's using dyn.load. I guess this is a simple mistake and I am overlooking something.
For example, I write this simple c function (foo.c):
void foo( int *x) {*x = *x + 1;}
Then compile it in command prompt:
R CMD SHLIB foo.c
Then in 32bit R I can use it in R:
> dyn.load("foo.dll")
> .C("foo",as.integer(1))
[[1]]
[1] 2
but in 64bit R I get:
> dyn.load("foo.dll")
Error in inDL(x, as.logical(local), as.logical(now), ...) :
unable to load shared object 'C:/Users/Sacha/Documents/R/foo.dll':
LoadLibrary failure: %1 is not a valid Win32 application.
nd.
Edit:
For reference, R CMD can be forced in an architecture by using --arch 64x :
R --arch x64 CMD SHLIB foo.c
Quite clear actually, I knew I was making a rooky mistake:)
My guess is that you are compiling it to a 32 bit target. You need to build it on your 64 bit machine with 64 bit tools. You can't load a 32 bit DLL into a 64 bit process, and vice versa.
what i did is to compile with --arch x64 and --arch 32 once a time and manually put corresponding .dll ( with the same name ) under separate folders src-x64 and src-i386 respectively, these two folders are under the same directory where the folder src is.

Resources