How to execute system commands using raspberry pi pico - c

I wanted to know if it is possible to run system commands on computer using raspberry pi pico when plugging it into the USB?
I've tried to do it like a normal C program :
#include "pico/stdlib.h"
#include <stdlib.h>
#include <stdio.h>
int main() {
printf("Start");
stdio_init_all();
char *cmd = "ls";
system(cmd);
return 0;
}
Although printf works very well, system functions (eg: readfile) doesn't work.
Is there any way that i could run some kind of actions on PC using pico usb output ?
Also, there is a project called picoducky which allows the pico to run commands on system but unfortunately it has written in python and i'm looking for c code.

Pico communicates with Pc using usb-to-serial and vice versa. Unless there is a server on Pc that interprets data send through serial than executes a cmd command, its not possible with the convetional way. However, you can make Pico emulate a USB HID device and send keystrokes. Check Tinyusb and this pico-superkey-board project

To be able to run system() function call in C in an embedded system, you need to know several things first:
system() calls the user shell with the string passed as argument as a parameter. Are you running an operating system at all? A shell is normally an operating system component, and it is not normally present in many embedded systems.
system() requires /bin/sh normally to work. To run ls, you need in adition to have it (the ls command) installed.
You don't say what operating system you have in your Raspberry pi pico, but I'm afraid it is not linux (or any unix flavour) so probably all of this is forbidden to you.
Normally, the requirements to have a unix like environment in a small system impede to use a high technology operating system in such systems. Linux requires large amoutns of memory (as there are in the normal raspberry pi, but not in the small versions), a large capacity storage system (bein a usb disk, flash memory card, etc. but normally several Gb for a minimum installation)
In your case, 264kb of ram are very small to have a non-mmu handled microprocessor, capable of addressing virtual memory spaces. Also 2Mb of flash gives you to write large programs, but not to install an operating system like linux.
Had you an emulator of system() you should be able to run other programs, but how? A raspberry pi pico has space to run just one program (the one you write to the flash and nothing else) Even if you write a kernel of a multitasking operating system, you would lack space to run filesystem stored programs, as you normally have limited access to the flash where programs are installed.

Related

Writing a task in VxWorks

I am trying to understand how can I write tasks for VxWorks. I have VxWorks on a board that is mounted on a development board.
I can access the board through Putty and a serial terminal connected to the UART of the system. How can I write other tasks (maybe to communicate with other UARTs or other Serial Interfaces) ?
And how do I know where to find the documentation describing how I can access those serial interfaces? (for example write/read methods, which file to include etc)*
Thank you
VxWorks is cross development environment, so you need a licensed development system on Windows or Linux desktop to create applications.
Then you load the compiled code on the target reference board as process/RTP or LKM/DKM. How you get it there varies by board: FTP, TFTP, removable USB or SD card....
At the C shell on booted system you can start a task in the kernel context with any public symbol. But if your working with deployed system, it shouldn't have the C shell, that's a serious security risk :)
Try..
-> sp printf, "\nHello VxWorks World!\n"

Running pipe of subprocess in ESP32 using ANSI C

I am getting into the ESP32 using esp-idf and I would like to make a program able to run subprocess while using C.
Banally, I have tried to call a function like the following:
...
#include <stdio.h>
char *cmd = "ls -l";
char buf[BUFSIZE];
FILE *fp;
if ((fp = popen(cmd, "r")) == NULL) {
printf("############## Error opening pipe!\n");
return -1;
}
while (fgets(buf, BUFSIZE, fp) != NULL) {
printf("############## OUTPUT: %s", buf);
}
if(pclose(fp)) {
printf("############## Command not found or exited with error status\n");
return -1;
}
return 0;
...
but the application returns
c:\esp\../main/app_main.c:139: undefined reference to `popen`
Has somebody experience with this one?
popen() is a system call available on POSIX-compliant and similar systems (UNIX, Linux, FreeBSD). The software that the ESP32 runs is not remotely POSIX-compliant.
Pipes and subprocesses are meaningless on the ESP32 - they're not supported. There is no popen() call.
The ESP32 runs a lightweight operating system called FreeRTOS. FreeRTOS provides lightweight tasks and very simple memory management and not much else.
FreeRTOS tasks share an address space; they are generally non-preemptive, voluntarily yield the processor to allow other tasks to run, and execute a subroutine (C function). POSIX processes each have their own address space, are preemptive and run POSIX binary applications. They're totally different, incompatible things. The ESP32 does not have the resources or memory management hardware to properly support POSIX processes.
ESP-IDF ("IoT Development Framework") is a layer built above FreeRTOS that provides a thin API providing access to the ESP32's hardware (I2C, SPI, wifi, Bluetooth, timers and the like).
Other programming environments like the Arduino Core, Python and LUA are all built on top of ESP-IDF.
ESP-IDF runs one program at a time, unlike POSIX-style systems. That program is the one you compiled, linked, and stored in its flash memory. POSIX-style systems run hundreds or thousands of programs at once. The ESP32 and ESP-IDF do not have the ability to do that.
As you start building applications for the ESP32, not only can you not use POSIX-compatible system calls, you'll also need to learn to program in a very resource-limited environment. On Linux and similar systems programmers commonly write code as if there were no constraints on memory, filesystem size and durability. None of these things are true on the ESP32 - it's trivial to write a program that accidentally needs more memory than its 520KB available to it; it's trivial to write a program that expects more persistent storage than is available in its flash memory; it's trivial to write a program that writes to the flash memory so frequently that it destroys it. You'll need to learn how to program within the constraints of the ESP32, not just how to write code that calls the ESP-IDF instead of a POSIX system.
Take a read through the ESP-IDF documentation that you linked to. That's the environment you're working in. You may find starting out in the Arduino Core to be easier - it's a C/C++ environment, there are a ton of tutorials out there for it, and it's an easier build environment, and you can still easily call ESP-IDF functions from it if you need to.

How to debug Bootloader Qemu ARM?

I'm trying to boot a kernel (extracted from a firmware) using QEMU.
Qemu emulation seems to start at 0x0.
The problem is that the memory from 0x0 to 0x04000000 is only filled with 0.
How can i debug the bootloader?
You don't say what your command line is. The address where QEMU starts execution depends on many things:
the guest CPU architecture
which board model you are emulating
whether you passed QEMU a BIOS image file
the file format of any file passed to -kernel (ELF, plain kernel image, uImage, etc)
In general, though, you should not expect to be able to pull a random kernel image out of a firmware dump for a piece of Arm hardware and run it under QEMU. This is because every Arm board or machine is different -- RAM may be in different places, the devices such as the serial port are at different addresses, and so on -- and the kernel will only boot on systems which it has been compiled to support. The chances are very high that (a) QEMU does not have a specific emulation of the bit of hardware that the firmware dump is for and (b) the kernel from the firmware has not been built to also run on any of the board types that QEMU does support. So it will almost certainly simply crash very early on in bootup without producing any output.
If you want to debug what's going on in early bootup, the best approach is probably to use QEMU's built in gdbstub, and attach a guest-architecture-aware gdb to it. You may also find QEMU's internal logging via the '-d' option useful, though it requires some familiarity with how QEMU works to make sense of the output.

Shutdown Linux from C program meant to be ran as init process

I'm writing a C program to do various stuff on a Linux system, then shut it down. This program will be started with the command line option init=/path/to/program with PID 1, and because of that, I can't use execl("/sbin/poweroff", "poweroff", NULL);, because the poweroff command doesn't shutdown the system itself, it asks the process with PID 1 to do it. So what code does init use to shutdown the system?
Why doesn't poweroff work?
A number of programs assume the kernel has booted with init as PID 1. On many systems init is a symbolic link to the systemd program; similarly on these systems, poweroff is often a symbolic link to the systemctl program.
In your setup, systemd is never started since you set your custom init=/path/to/program kernel parameter line. This is why the poweroff command doesn't work: systemctl is trying to contact a systemd instance which was never created.
How to power off without systemd.
The reboot function is described in the Linux Programmer's Manual. Under glibc, you can pass the RB_POWER_OFF macro constant to perform the reboot.
Note that if reboot is not preceded by a call to sync, data may be lost.
Using glibc in Linux:
#include <unistd.h>
#include <sys/reboot.h>
sync();
reboot(RB_POWER_OFF);
See also
How to restart Linux from inside a C++ program?

What can I use to debug/trace step-by-step Freebsd kernel booting process on Pandaboard?

To start with - I don't have JTAG hardware debugger.
What I have:
Pandaboard and serial-USB cable to connect to console and my computer with Freebsd and GNU/Linux distribution.
What I'm looking for
- convinient way to trace/debug bootprocess inside FreeBSD kernel ( I'm mostly interested in this fragment: https://github.com/freebsd/freebsd/blob/master/sys/arm/arm/locore-v6.S and https://github.com/freebsd/freebsd/blob/master/sys/arm/arm/mp_machdep.c as I'm, going to modyfy those files ).
Based on my experience, there are few ways:
KDB / DDB: add call kdb_enter("A", "XYZ") to stop processing and enter interactive debug mode of DDB via serial.
printf-s in machine dependent (mach_dep) code
bootverbose, BUSDEBUG, VERBOSE_SYSINIT in machine independent code
Also it's worth to mention that DDB code contains functions to print registers, stack trace and etc.

Resources