how to enable the spi to connect mcp251x with yocto? - yocto

I am new to yocto and i have generated a linux image for my raspberrypi-cm3 and i want to connect an mcp2515 to my cm3 to test the can driver.
the mcp251x.ko , can_dev.ko , spidev.ko spi_bcm2835.ko and spi_2835aux.ko modules are loaded and when i write ' dmesg | grep can' i get messages that mcp251x is finely there but when i write ' dmesg | grep spi' nothing shows up.
also in my 'config.txt' file the spi is set to 'off' by default.
Can someone please help me to enable the spi so i can test the mcp251x of the can?

Open .dts file in your kernel and enable spi and set STATUS="okay"
and write platform data for spidev
&spi0 {
pinctrl-names = "default";
pinctrl-0 = <&spi0_pins_a>,
<&spi0_cs0_pins_a>;
status = "okay";
spidev#0x00 {
compatible = "spidev";
spi-max-frequency = <1200000>;
reg = <0>;
};
and open bitbake -c menuconfig virtual/kernel. then enable spidev present in devicer/drivers.

Related

Raspberry Pi not picking up Wii controller or not communicating

I am trying to connect my Wii-mote's to my Raspberry Pi, so I can use them in pygame. I know to use the Wii controller, I need to make some configurations, and I have made them. However, when I run my .sh script to connect the remotes, I am thrown some errors. Here are the scripts:
/mywinput
#WiiMote
Wiimote.A = BTN_A
Wiimote.B = BTN_B
Wiimote.Dpad.X = ABS_Y
Wiimote.Dpad.Y = -ABS_X
Wiimote.Minus = BTN_SELECT
Wiimote.Plus = BTN_START
Wiimote.Home = BTN_MODE
Wiimote.1 = BTN_X
Wiimote.2 = BTN_Y
# Nunchuk
Nunchuk.C = BTN_C
Nunchuk.Z = BTN_Z
Plugin.led.Led1 = 1
#Plugin.led.Led2 = 1
Plugin.led.Led3 = 1
#Plugin.led.Led4 = 1
/wiicontroller.sh
#!/bin/bash
sleep 1 # Wait until Bluetooth services are fully initialized
hcitool dev | grep hci >/dev/null
if test $? -eq 0 ; then
wminput -d -c /home/pi/mywinput CC:FB:65:2C:52:8F &
else
echo "Blue-tooth adapter not present!"
exit 1
fi
I have made wiicontoller.sh executable:
sudo chmod 775 /home/pi/bin/connectwii.sh
Supposedly, I should press one and two one the controller and it should connect. However, the script returns immediately. And even then, when I press one and two, I get thrown errors. I don't think that should be possible as the script has returned, but here is the output:
Socket connect error (control channel)
I am also aware that using cwiid in python is another option. But that doesn't work either, as it does not detect my remote. wmgui also cannot pickup my remote. The only way I am able to detect my remote is through the hcitool scan command. Any help would be appreciated!

Programming NRF52840 dongle from PlatformIO

I am following https://docs.platformio.org/en/latest/boards/nordicnrf52/nrf52840_dk.html but I don't actually have a DK, I have an NRF52840 "Dongle". Does anybody know if it's possible for that to work directly with PlatformIO? It has a built in bootloader, but I don't think it emulates the right kind of programmer. I have nrfutil installed but that wants a package (.zip) and platformio is producing .elf/.hex ... not sure how to connect these tools.
platformio.ini configuration:
[env:nrf52840_dongle]
platform = nordicnrf52
board = nrf52840_dk
framework = zephyr
board_build.zephyr.variant = nrf52840dongle_nrf52840
extra_scripts = dfu_upload.py
upload_protocol = custom
add to project root dfu_upload.py script:
import sys
import os
from os.path import basename
Import("env")
platform = env.PioPlatform()
def dfu_upload(source, target, env):
firmware_path = str(source[0])
firmware_name = basename(firmware_path)
genpkg = "".join(["nrfutil pkg generate --hw-version 52 --sd-req=0x00 --application ", firmware_path, " --application-version 1 firmware.zip"])
dfupkg = "nrfutil dfu serial -pkg firmware.zip -p COM14 -b 115200"
print( genpkg )
os.system( genpkg )
os.system( dfupkg )
print("Uploading done.")
# Custom upload command and program name
env.Replace(PROGNAME="firmware", UPLOADCMD=dfu_upload)
add nrfutil location to your system configuration "path" variable
before upload firmware switch dongle to dfu mode (button reset)
setup dongle COM number in line: dfupkg = "nrfutil dfu serial -pkg firmware.zip -p COM14 -b 115200" in dfu_upload.py
lots of examples you can find here: Zephyr github
You can use nrfutil pkg generate to convert the hex files into a package:
https://infocenter.nordicsemi.com/topic/ug_nrfutil/UG/nrfutil/nrfutil_pkg.html
FYI, you might not get much benefit from using PlatformIO since you don't have a debugging interface. Depending on the framework you're using, there might be other options, like this documentation for Zephyr:
https://docs.zephyrproject.org/latest/boards/arm/nrf52840dongle_nrf52840/doc/index.html

Opening a DGRAM socket from within a docker container fails (permission denied)

I'm running an application which builds and sends ICMP ECHO requests to a few different ip addresses. The application is written in Crystal. When attempting to open a socket from within the crystal docker container, Crystal raises an exception: Permission Denied.
From within the container, I have no problem running ping 8.8.8.8.
Running the application on macos, I have no problem.
Reading the https://docs.docker.com/engine/security/apparmor/ and https://docs.docker.com/engine/security/seccomp/ pages on apparmor and seccomp I was sure I'd found the solution, but the problem remains unresolved, even when running as docker run --rm --security-opt seccomp=unconfined --security-opt apparmor=unconfined socket_permission
update/edit: After digging into capabilities(7), I added the following line to my dockerfile: RUN setcap cap_net_raw+ep bin/ping trying to let the socket get opened but without change.
Thanks!
Relevant crystal socket code, full working code sample below:
# send request
address = Socket::IPAddress.new host, 0
socket = IPSocket.new Socket::Family::INET, Socket::Type::DGRAM, Socket::Protocol::ICMP
socket.send slice, to: address
Dockerfile:
FROM crystallang/crystal:0.23.1
WORKDIR /opt
COPY src/ping.cr src/
RUN mkdir bin
RUN crystal -v
RUN crystal build -o bin/ping src/ping.cr
ENTRYPOINT ["/bin/sh","-c"]
CMD ["/opt/bin/ping"]
Running the code, first native, then via docker:
#!/bin/bash
crystal run src/ping.cr
docker build -t socket_permission .
docker run --rm --security-opt seccomp=unconfined --security-opt apparmor=unconfined socket_permission
And finally, a 50 line crystal script which fails to open a socket in docker:
require "socket"
TYPE = 8_u16
IP_HEADER_SIZE_8 = 20
PACKET_LENGTH_8 = 16
PACKET_LENGTH_16 = 8
MESSAGE = " ICMP"
def ping
sequence = 0_u16
sender_id = 0_u16
host = "8.8.8.8"
# initialize packet with MESSAGE
packet = Array(UInt16).new PACKET_LENGTH_16 do |i|
MESSAGE[ i % MESSAGE.size ].ord.to_u16
end
# build out ICMP header
packet[0] = (TYPE.to_u16 << 8)
packet[1] = 0_u16
packet[2] = sender_id
packet[3] = sequence
# calculate checksum
checksum = 0_u32
packet.each do |byte|
checksum += byte
end
checksum += checksum >> 16
checksum = checksum ^ 0xffff_ffff_u32
packet[1] = checksum.to_u16
# convert packet to 8 bit words
slice = Bytes.new(PACKET_LENGTH_8)
eight_bit_packet = packet.map do |word|
[(word >> 8), (word & 0xff)]
end.flatten.map(&.to_u8)
eight_bit_packet.each_with_index do |chr, i|
slice[i] = chr
end
# send request
address = Socket::IPAddress.new host, 0
socket = IPSocket.new Socket::Family::INET, Socket::Type::DGRAM, Socket::Protocol::ICMP
socket.send slice, to: address
# receive response
buffer = Bytes.new(PACKET_LENGTH_8 + IP_HEADER_SIZE_8)
count, address = socket.receive buffer
length = buffer.size
icmp_data = buffer[IP_HEADER_SIZE_8, length-IP_HEADER_SIZE_8]
end
ping
It turns out the answer is that Linux (and by extension docker) does not give the same permissions that macOS does for DGRAM sockets. Changing the socket declaration to socket = IPSocket.new Socket::Family::INET, Socket::Type::RAW, Socket::Protocol::ICMP allows the socket to connect under docker.
A little more still is required to run the program in a non-root context. Because raw sockets are restricted to root, the binary must also be issued the correct capability for access to a raw socket, CAP_NET_RAW. However, in docker, this isn't necessary. I was able to get the program to run outside of super-user context by running sudo setcap cap_net_raw+ep bin/ping. This is a decent primer on capabilities and the setpcap command
MacOS doesn't use the same system of permissions, so setcap is just an unrecognized command. As a result, to get the above code to compile and run successfully on macOS without super-user context, I changed the socket creation code to:
socket_type = Socket::Type::RAW
{% if flag?(:darwin) %}
socket_type = Socket::Type::DGRAM
{% end %}
socket = IPSocket.new Socket::Family::INET, socket_type, Socket::Protocol::ICMP
Applying the CAP_NET_RAW capability for use in linux happens elsewhere in the build process if needed.
With those changes, I'm not seeing any requirement for changes to seccomp or apparmor from the default shipped with Docker in order to run the program.

kdmf pnp driver cannot find device when installing

I am trying to create a pnp driver but when I run sc start driver-name I get an System error 1058 (disable disabled or no enabled device associated). However if I modify the code for nonpnp WDF_DRIVER_CONFIG_INIT(&config, WDF_NO_EVENT_CALLBACK); and config.DriverInitFlags |= WdfDriverInitNonPnpDriver; the service starts and I am able to debug.
I have tried different hwid values for the device verified through device manager. The DriverEntry runs fine, I've used windbg but the device add function is never called.
Driver Entry Code for pnp.
// prototype for add device function
EVT_WDF_DRIVER_DEVICE_ADD QDeviceAdd;
NTSTATUS DriverEntry(
IN OUT PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
NTSTATUS status = STATUS_SUCCESS;
WDF_DRIVER_CONFIG config;
WDFDRIVER hDriver;
PWDFDEVICE_INIT pInit = NULL;
WDF_OBJECT_ATTRIBUTES attributes;
KdPrint(("enabling wpp tracing\n"));
WPP_INIT_TRACING(DriverObject, RegistryPath);
WDF_DRIVER_CONFIG_INIT(
&config,
QDeviceAdd // WDF_NO_EVENT_CALLBACK This is a non-pnp driver.
);
WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
attributes.EvtCleanupCallback = QEvtDriverContextCleanup;
status = WdfDriverCreate(DriverObject,
RegistryPath,
&attributes,
&config,
&hDriver);
if (!NT_SUCCESS(status)) {
KdPrint(("NonPnp: WdfDriverCreate failed with status 0x%x\n", status));
WPP_CLEANUP(DriverObject);
return status;
}
return status;
}
Apparently previous copies of the inf file remained in the store and registry wasn't being updated so after some digging I ended doing the following:
checking in C:\Windows\Inf\setupapi.dev.log and copying the the missing file.
Then deleted the driver from store using pnputil
pnputil -d oemXX.inf
manually removed the key
HKLM\SYSTEM\CurrentControlSet\Control\Class{your-class-id}
pnputil -i /path/to/inf
Thanks to this site and this post

Change hearbeat led on beaglebone black with device tree overlay

I am using the Debian wheezy filesystem with Robert Nelson's latest kernel.
I want to disable the heartbeat led using a device tree overlay.
I understand there are easier ways of doing this but I am only interested in answers using overlays to disable the heartbeat led.
One way I can achieve this is by changing the gpio-leds,led0 leaf in am335x-boneblack.dts
from:
linux,default-trigger = "heartbeat";
to
linux,default-trigger = "none";
then compiling the device tree and rebooting.
However if I try to implement the same thing using the following overlay the heartbeat led continues to flash after I successfully apply the overlay with echo > $SLOTS.
What am I doing wrong?
/dts-v1/;
/plugin/;
/
{
compatible = "ti,beaglebone", "ti,beaglebone-black";
part-number = "pru";
version = "00A0";
fragment#0
{
target = <&ocp>;
__overlay__
{
gpio-leds
{
compatible = "gpio-leds";
pinctrl-names = "default";
pinctrl-0 = <0x3>;
led0
{
label = "beaglebone:green:usr0";
gpios = <0x5 0x15 0x0>;
linux,default-trigger = "none";
default-state = "off";
};
};
};
};
};
There's a systemd service, leds.service, that overrides the device tree settings for this one led (who knows why).
To see the status of the service, run
root#beaglebone:~# systemctl status leds.service
which gives the output
leds.service - Angstrom LED config
Loaded: loaded (/lib/systemd/system/leds.service; enabled)
Active: active (exited) since Sat 2000-01-01 18:33:24 UTC; 13 years 7 months ago
Process: 125 ExecStart=/usr/bin/led-config start (code=exited, status=0/SUCCESS)
CGroup: name=systemd:/system/leds.service
By looking at the "Loaded" field you can see that the service script is located at /lib/systemd/system/leds.service, and the "Process" field says the this service runs the command "/usr/bin/led-config start".
Looking at this file "/usr/bin/led-config" you'll see that it's a shell script that loads defaults from the file "/etc/default/leds":
#file format: name trigger
beaglebone::usr0 heartbeat
So, you can leave the device tree file alone and set the defaults here, or disable this service with
systemctl disable leds.service
To disable the heartbeat with an overlay is very inefficient in my opinion! How about instead try typing in the bash command: "echo none > /sys/devices/ocp.3/gpio-leds.8/beaglebone\:green\:usr0/trigger" and then to turn them back on 'echo "heartbeat" > trigger' (check the file path first) - tested on Debian Wheezy A5A