Zephyr-RTOS logging with DMA on STM32L432KC - stm32

I'm trying to run Zephyr Logging by using DMA on UART on STM32L432KC.
That's simple main loop:
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(example, LOG_LEVEL_DBG);
int main(void)
{
while (1) {
LOG_INF("main loop");
k_msleep(1000);
}
}
That's full configuration:
CONFIG_SOC_SERIES_STM32L4X=y
CONFIG_SOC_STM32L432XX=y
# Enable MPU
CONFIG_ARM_MPU=y
# Enable HW stack protection
CONFIG_HW_STACK_PROTECTION=y
# enable uart driver
CONFIG_SERIAL=y
# enable GPIO
CONFIG_GPIO=y
# Enable Clocks
CONFIG_CLOCK_CONTROL=y
# console
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y
CONFIG_UART_ASYNC_API=y
# enable DMA
CONFIG_DMA=y
# enable pin controller
CONFIG_PINCTRL=y
# config logging
CONFIG_LOG=y
CONFIG_LOG_BACKEND_UART_ASYNC=y
CONFIG_LOG_MODE_IMMEDIATE=y
Then build it and flash:
west flash -b nucleo_l432kc
In logs I see following output:
*** Booting Zephyr OS build zephyr-v3.2.0-863-g78809549ee4c ***
[00:00:01.001,000] <inf> example: main loop
When I change CONFIG_LOG_MODE_IMMEDIATE=y to CONFIG_LOG_MODE_DEFERRED=y it prints log every second like I expect.
I discovered that code stops here on k_sem_take(&sem, K_FOREVER) and this uart_callback is never called to release this mutex.
Also discovered when following options are enabled it's working fine with CONFIG_LOG_MODE_DEFERRED=y option:
CONFIG_LOG_PROCESS_THREAD=y
CONFIG_LOG_PROCESS_THREAD_SLEEP_MS=100
But that makes me wondering why another thread must be created? DMA is no blocking. Really confusing.
What am I missing? I would like to delegate all logging to DMA buffer with Logging subsystem features, without additional threads and buffering. Is there someone experienced who can point what is wrong?

Related

Multiple ebpf hooks cgroup_skb

I have basic question on ebpf behavior when multiple ebpf hooks are loaded(not using chaining) simultaneously in kernel. Are all of those hooks invoked? For example, I loaded my ebpf program which has cgroup_skb/ingress hook. The ebpf hooks functions loaded by my program are not getting invoked by kernel during packet ingress. When I list loaded programs on "Linux 5.13.0-30-generic", I see that systemd has already loaded cgroup_skb/ingress hooks by default. I do understand why these cgroup/skb hooks are loaded by systemd. My question is specifically on kernel's behavior when multiple hooks of same type(cgroup_skb/ingress) are loaded.
yes. All the hooks will be called. We need to attach it with "multi" keyword.
bpftool  prog load test1.o /sys/fs/bpf/test1 type cgroup/skb
bpftool cgroup attach /sys/fs/cgroup/mygrp   egress pinned /sys/fs/bpf/test1 multi
bpftool  prog load test2.o /sys/fs/bpf/test2 type cgroup/skb
bpftool cgroup attach /sys/fs/cgroup/mygrp   egress pinned /sys/fs/bpf/test2 multi
My simple program with different debug print statement (test2.c):
SEC("cgroup/skb")
int cgrp_dump_pkt(struct __sk_buff *skb) {
bpf_printk("welcome test 2");
return 1;
}
ping-446804 [000] d... 374792.037025: bpf_trace_printk: welcome test 1
ping-446804 [000] d... 374792.037038: bpf_trace_printk: welcome test 2

Why might `i2c_smbus_write_byte_data` be returning "Operation not permitted" on uClinux 2.4?

I am writing a C program with the aim of configuring a peripheral device (the CS5368 ADC) via the I2C interface of a Dante Brooklyn II, a board based on a Microblaze soft-core processor running uClinux 2.4.
I have implemented the configuration following the Dante OEM docs for guidance, however when running my program I am encountering an "Operation not permitted" (EPERM) error when attempting to write data to I2C using i2c_smbus_write_byte_data.
Here is the section of code containing the culprit call to i2c_smbus_write_byte_data:
// Set ADC I2S to "Slave mode all speeds".
printf("Set the CS5368 I2S mode to slave\n");
unsigned char adc_dif = 0x01; // I2S mode
unsigned char adc_mode = 0x03; // Slave mode all speeds
unsigned char data = 0x90 | (adc_dif << 2) | adc_mode;
result = i2c_smbus_write_byte_data(i2c_fd, CS5368_GCTL_MDE, data);
if (result < 0) {
perror("Failed to write to the 'Global Mode Control' register");
return -1;
}
Here is the code within context of the full source of the small program. The program begins by resetting the CS5368 via a GPIO pin before doing the configuration via I2C.
EPERM is returned whether or not I have the CS5368 wired up. I've been able to successfully configure the CS5368 using the I2C interface of an Arduino Uno, so the issue does not appear to be related to the CS5368.
To run the program I login to the board via telnet as root, so I doubt the error has anything to do with user permissions.
The OEM docs state:
The Brooklyn II module can operate as an I2C controller running at
100Khz and using 7 bit addressing mode. It supports multi-master
operation. I2C devices can be accessed from user application running
on the Brooklyn II module. The interface supports the SMBus (System
Management Bus) protocol, which is a subset from the I2C protocol.
It goes on to list the supported i2c_smbus_* functions including i2c_smbus_write_byte_data, so the issue does not appear to be related to lack of support for SMBus or I2C.
I came across a related issue where a user was getting an EPERM error code when attempting to use the I2C write API, however the solution appears to have been to use the i2c_smbus_* API instead which I am already doing.
Any advice on what could be causing this error code to be returned or how to debug the issue further would be greatly appreciated!
Edit: In case it helps, here is the full output, starting from logging onto the board via telnet after having moved the exe to /tmp via ftp:
$ telnet 169.254.72.245
Trying 169.254.72.245...
Connected to 169.254.72.245.
Escape character is '^]'.
login: root
Password:
BusyBox v1.23.2 (2018-05-31 11:33:18 AEST) hush - the humble shell
/ # cd /tmp
/var/tmp # ./cs5368-i2c-config
Open GPIO device
Set GPIO tristate outputs
Set GPIO pins low
Sleep for 10 secs
Set GPIO pins high
Close GPIO file descriptor
Searching for I2C device
Opening /dev/i2c-0
Setting I2C_SLAVE 4c...
I2C Interface found: /dev/i2c-0
Set the CS5368 as the slave
Set the CS5368 I2S mode to slave
Failed to write to the 'Global Mode Control' register: Operation not permitted

Atollic couldn't verify ST device?

trying to program and debug STM32F103 (Bluepill) from Atollic TrueStudio 9.3 I got following message:
STMicroelectronics ST-LINK GDB server. Version 5.1.0 Copyright (c)
2018, STMicroelectronics. All rights reserved.
Starting server with the following options:
Persistent Mode : Disabled
Logging Level : 1
Listen Port Number : 61234
Status Refresh Delay : 15s
Verbose Mode : Disabled
SWD Debug : Enabled
Vendor = 0x55
Error in initializing ST-LINK device. Reason: ST-LINK: Could not
verify ST device! Abort connection.
Trying to do the same thing in St-Link utility works without any problems (also erasing and programming):
What could be the problem with this, why does it have problems with verification ?
Tnx for helping in advance!
The problem is that the ID of the STM32F103 on the BluePill and the ID, defined the debugger config files are different. Often the BluePills have counterfeit ICs on them in order to keep the price low, but these do not have the same ID as genuine ICs.
The Instructions/video below are made for STM32CubeIDE however they should also work for TrueSTUDIO.
Video about a workaround: https://youtu.be/bJYp8o7FoYo
Open the Debug Configuration Window
Select ST-LINK(OpenOCD) in the Debug Probe Dropdown
Search stm32f1x.cfg file the C:\ST\STM32CubeIDE_1.2.0\STM32CubeIDE and open it using notepad.
Search for this Line
Now change the ID from 0x1ba01477 to 0x2ba01477 as shown here
Save the file, now debugging should work
this solution also works for clone chips like CH32F103 which is in some cases on BluePill
the other solution is to change a parameter in "stm32f1x.cfg"
open it with a text editor and find this line:
swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID
change "$_CPUTAPID" to zero at the end of line it should be like this:
swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0
after that :Open the Debug Configuration Window like picture above and choose "Select ST-LINK(OpenOCD)" in the Debug Probe Dropdown
then click "Show generator options…” and in Mode setup change"Reset Mode”For“Software system reset”.
both of ways works and i've tested them with CubeIDE and CH32f103c8t6.
remember to change jumper on board
jumpers : up = 0 ; down = 1

stm32 factory bootloader possibly overwritten with openocd?

tl;dr: flashed firmware to 0x00000000 instead of 0x08000000, am I lost?
Hello,
my device is based on a STM32F103CBTx which came with a proprietary firmware and had readout protection on.
I connect to it with a ST-Link v2 SWDIO and SWCLK connected to PA13 and PA14 and this command:
sudo openocd -f /usr/share/openocd/scripts/interface/stlink-v2.cfg -f /usr/share/openocd/scripts/target/stm32f1x.cfg
I don't remember how I removed flash protection, but it worked as the original firmware didn't work anymore. Then I created a simple hello world firmware which pulls up and down three gpios and flashed it. The gpios are pulled up and down in 700ms intervals.
After flashing, I can't connect with openocd anymore. I forgot to specify the offset, the manual says the offset defaults to 0 and as it worked, I suppose instead of the boot loader my shitty hello world is pulling up and down some random pins happily… Is this possible? All other threads I found say the boot loader is write protected.
This is the last contact I had:
> halt
halt
target halted due to debug-request, current mode: Handler HardFault
xPSR: 0x01000003 pc: 0xfffffffe msp: 0xffffffdc
> flash write_image erase fw.hex
flash write_image erase fw.hex
auto erase enabled
target halted due to breakpoint, current mode: Handler HardFault
xPSR: 0x61000003 pc: 0x2000003a msp: 0xffffffdc
wrote 4096 bytes from file fw.hex in 0.285697s (14.001 KiB/s)
> reset
reset
jtag status contains invalid mode value - communication failure
Polling target stm32f1x.cpu failed, trying to reexamine
Examination failed, GDB will be halted. Polling again in 100ms
Any directions highly appreciated.
Edit:
What I get now, also tried another st-link:
% sudo openocd -f /usr/share/openocd/scripts/interface/stlink-v2.cfg -f /usr/share/openocd/scripts/target/stm32f1x.cfg
Open On-Chip Debugger 0.10.0
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "hla_swd". To override use 'transport select '.
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
adapter speed: 1000 kHz
adapter_nsrst_delay: 100
none separate
Info : Unable to match requested speed 1000 kHz, using 950 kHz
Info : Unable to match requested speed 1000 kHz, using 950 kHz
Info : clock speed 950 kHz
Info : STLINK v2 JTAG v17 API v2 SWIM v4 VID 0x0483 PID 0x3748
Info : using stlink api v2
Info : Target voltage: 3.244356
Error: init mode failed (unable to connect to the target)
in procedure 'init'
in procedure 'ocd_bouncer'
flashed firmware to 0x00000000 instead of 0x08000000, am I lost?
No, it doesn't matter at all, they are the same.
After reset, the MCU loads the word at address 0 in SP, and the next one at address 4 in PC. The BOOT0 and BOOT1 pins control which memory gets mapped to 0x00000000. Usually, BOOT0 is tied low, and flash memory at 0x08000000 gets mirrored at 0x00000000.
instead of the boot loader my shitty hello world is pulling up and down some random pins happily… Is this possible? All other threads I found say the boot loader is write protected.
The factory bootloader is indeed write protected, openocd can't overwrite it.
However, your application could have reconfigured the SWD pins, by writing a wrong value in GPIOA->CRH or AFIO->MAPR, thereby preventing openocd from working. It's the most common cause of this problem.
Fortunately, there is a way to recover.
Connect under Reset
If the reset pin of the controller is held low for a while when openocd is started, the application is prevented from starting, and messing up the GPIO configuration.
Openocd can do this automatically, when
It's told to do so, the line reset_config srst_only srst_nogate is present somewhere in the configuration script.
The MCU reset pin is connected to the debugger hardware, pin 15 on an official ST-Link/V2.
Or you can do it manually, by whatever means your board provides. If you are lucky, it has a reset button, if not, you must find a way to somehow ground the MCU reset pin.
Pull the reset pin low
Start openocd
Wait until the Info : Target voltage line appears. Maybe a second longer.
Release the reset pin.
It requires a bit of trial and error, you'll get better with practice.
Then you can flash your improved application, which carefully avoids reconfiguring the SWD pins.

first driver -- spi framework for linux

This is first time i am writing a driver for linux SPI framework for ADS7846.
Found this excellent tutorial to understand the concept of linux SPI :---
http://www.jumpnowtek.com/index.php?option=com_content&view=article&id=57&Itemid=62
It also have a sample co-de.
https://github.com/scottellis/spike/blob/part3/spike.c
1> Few points which i was not able to get why we are using semaphore
befor accessing -- spike_dev.user_buff.
do we really need semaphore ? Because at a time my application program willonly read() or write() or open() the driver ?
2> Also to select the chip select we are using :--
/* specify a chip select line */
SPI_BUS_CS1
Here why we are not specifing which PORT will the CS - line be connected to ?
3> As what i have read spinlock should be used with interupt handler. Also what is the use of this spinlock in the driver.
Here we do not have spi Interupt handler.But while accessing -- spi_async & spi_device -- we are using spinlock ?
spin_lock_irqsave
spi_async
spin_unlock_irqrestore
4> Also can we have multiple "protocol drivers" registered to same SPI device ?
Any suggestion will be appreciated.
2> it is could be mentioned in .controllerdata the bus num and chipselect is to enumerate the SPI devices
3> it is used for taks which can sleep