树莓派笔记--基础应用


硬件平台: 树莓派4B
操作系统: raspbian


常用软件源

# 清华大学
deb http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ buster main contrib non-free rpi
deb-src http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ buster main contrib non-free rpi

# 中科大
deb http://mirrors.ustc.edu.cn/raspbian/raspbian/ buster main contrib non-free rpi
deb-src http://mirrors.ustc.edu.cn/raspbian/raspbian/ buster main contrib non-free rpi

修改自动登陆的用户名:

修改 /etc/lightdm 下的 lightdm.conf 文件,如果没有则创建这个文件:

[SeatDefaults]
autologin-user = alex

打开/关闭自动登陆可用raspi-config命令选择。

登陆不显示用户列表:

greeter-hide-users=true

桌面启动项:用户登陆桌面后自动启动

建立以.desktop结尾的文件(如test.desktop),内容如下:

[Desktop Entry]
Name=Chrome
Comment=This session logs you into Chromium
Exec=/usr/bin/chromium-browser --disable-popup-blocking --no-first-run --disable-desktop-notifications --kiosk "http://www.baidu.com"
Icon=
Type=Application

指定用户:放在用户家目录的.config/autostart目录下(如果不存在则创建之)
所有用户:/etc/xdg/autostart目录下


隐藏鼠标指针:
安装unclutter

apt-get install unclutter

在/etc/xdg/lxsession/LXDE/autostart文件中添加一行:

@unclutter -idle 1 -root

隐藏开机logo:
修改/boot/cmdline.txt,添加logo.nologo


隐藏任务栏:
打开~/.config/lxpanel/LXDE-pi/panels/panels文件
修改Golbal项,并删除除Golbal之外的其他项。

Global{
     height=0
     width=0
     autohide=1
}

恢复任务栏: 直接删除panels文件并重启,即可恢复默认设置


修改GPU显存:

# raspi-config
    --> 7 Advanced Options     
        --> A3 Memory Split

提示最大支持256MB,超出此范围可能显示不正常(测试512MB正常)

TF卡分区扩容:

# raspi-config
    --> 7 Advanced Options   
       -->A1 Expand Filesystem Ensures that all of the SD card storage is available

关闭显示器省电模式:

# xset -dpms

打开显示器省电模式:

# xset +dpms

设置省电模式参数: 后面可以有三个参数的时间分别为(standby,suspend, off),单位为秒,0表示不生效。

# xset dpms 10 20 30

关闭屏保:

# xset s off

必须在显示器终端执行才有效,SSH等远程连接命令无效。

可以在/etc/profile.d/目录中添加配置脚本(开机自动使能):

xset s off
xset dpms 0 0 0

命令唤醒屏幕: 普通用户权限即可

$ xset dpms force on

屏幕立即休眠命令:

$ xset dpms force on

错误处理: xset : unable to open display

export DISPLAY=:0

设置屏幕常亮:禁止屏幕休眠

# 编辑/etc/lightdm/lightdm.conf文件
# 找到[SeatDefaults]字段
# 修改xserver-command选项
# xserver-command=X
xserver-command=X -s 0 -dpms

-s 表示关闭屏幕保护
-dpms 表示关闭节能模式


开启/关闭屏幕命令:

# vcgencmd display_power 0
# vcgencmd display_power 1

直接干掉了屏幕电源供电,比较简单暴力,树莓派专用命令,其他系统不支持;
貌似xset dpms force on命令会恢复屏幕供电;


修改桌面默认背景图片:
修改etc/xdg/pcmanfm/LXDE-pi/desktop-items-1.conf文件中相关选项即可

设置静态IP: 修改/etc/dhcpcd.conf文件
如果修改/etc/network/interface文件会造成静态IP与DHCP同时分配两个IP地址。


摄像头测试:

# raspistill -o test.jpg

# raspivid -o test.h264

安装firefox: iceweasel

# apt-get install iceweasel

微雪显示屏配置: 修改config.txt文件

# 设置USB最大输入电流
# 官方文档没有规定这一项,但是如果不写可能会黑屏
hdmi_ignore_edid=0xa5000080
max_usb_current=1
hdmi_group=2
hdmi_mode=87
hdmi_cvt 1024 600 60 6 0 0 0

显示旋转:

display_rotate=1 #1:90;2: 180; 3: 270
# 注释掉 dtoverlay=vc4-fkms-V3D

无屏幕相关操作
开启SSH 服务: 在TF卡的boot分区的根目录下,建立SSH空白文件(无扩展名),重启系统即可。

开启wifi连接: 在TF卡的boot分区的根目录下,建立wpa_supplicant.conf文件,内容如下:

network={
    ssid="wifi"
    psk ="123456"
    key_mgmt=WPA-PSK
}

第一次开机启动时弹出的欢迎菜单:
程序名称:piwiz (基于图形界面的软件),启动脚本位于 /etc/xdg/autostart/piwiz.desktop,设置完成后会删除启动文件,但不删除程序。


查看CPU当前运行的主频:

$ sudo cat /sys/devices/system/cpu/cpufreq/policy0/cpuinfo_cur_freq

或者:

$ vcgencmd measure_clock arm

设置CPU主频:
修改config.txt文件
arm_freq = 1500


双网卡路由设置:
有线连接内网,通过wifi上网, 有线采用静态IP设置时,不要指定gateway。

取消U盘自动挂载:

Accessories
    -->File Manger
        -->Edit
            -->Preferences
                --> Volume Management

取消Auto-Mount选项即可。

https://www.waveshare.net/wiki/10.1inch_HDMI_LCD_(E)

- 阅读全文 -

Linux系统应用--udev语法详细说明


文章摘要:
udev是Linux(linux2.6内核之后)默认的设备管理工具。udev 以守护进程的形式运行,通过侦听内核发出来的 uevent 来管理 /dev目录下的设备文件。

操作符   匹配或赋值   解释
----------------------------------------
==     匹配      相等比较
!=     匹配       不等比较
=     赋值       分配一个特定的值给该键,他可以覆盖之前的赋值。
+=     赋值         追加特定的值给已经存在的键
:=       赋值         分配一个特定的值给该键,后面的规则不可能覆盖它。

键值说明:

ACTION: 事件 (uevent) 的行为,例如:add( 添加设备 )、remove( 删除设备 )。

KERNEL: 内核设备名称,例如:sda, cdrom。

DEVPATH:设备的 devpath 路径。

SUBSYSTEM: 设备的子系统名称,例如:sda 的子系统为 block。

BUS: 设备在 devpath 里的总线名称,例如:usb。

DRIVER: 设备在 devpath 里的设备驱动名称,例如:ide-cdrom。

ID: 设备在 devpath 里的识别号。

SYSFS{filename}: 设备的 devpath 路径下,设备的属性文件“filename”里的内容。

例如:SYSFS{model}==“ST936701SS”表示:如果设备的型号为 ST936701SS,则该设备匹配该 匹配键。

在一条规则中,可以设定最多五条 SYSFS 的 匹配键。

ENV{key}: 环境变量。在一条规则中,可以设定最多五条环境变量的 匹配键。

PROGRAM:调用外部命令。

RESULT: 外部命令 PROGRAM 的返回结果。例如:

PROGRAM=="/lib/udev/scsi_id -g -s $devpath", RESULT=="35000c50000a7ef67"

调用外部命令 /lib/udev/scsi_id查询设备的 SCSI ID,如果返回结果为 35000c50000a7ef67,则该设备匹配该 匹配键。
$kernel, %k:设备的内核设备名称,例如:sda、cdrom。

$number, %n:设备的内核号码,例如:sda3 的内核号码是 3。

$devpath, %p:设备的 devpath路径。

$id, %b:设备在 devpath里的 ID 号。

$sysfs{file}, %s{file}:设备的 sysfs里 file 的内容。其实就是设备的属性值。
例如:$sysfs{size} 表示该设备 ( 磁盘 ) 的大小。

$env{key}, %E{key}:一个环境变量的值。

$major, %M:设备的 major 号。

$minor %m:设备的 minor 号。

$result, %c:PROGRAM 返回的结果。

$parent, %P:父设备的设备文件名。

$root, %r:udev_root的值,默认是 /dev/。

$tempnode, %N:临时设备名。

%%:符号 % 本身。

$$:符号 $ 本身。

自动挂载示例:

# 如果设备名称不是以sd开头的,跳转至结束位置
KERNEL!="sd*", GOTO="media_by_label_auto_mount_end"  

# 子设备名称:硬盘的子设备名称为block(块设备)
SUBSYSTEM!="block",GOTO="media_by_label_auto_mount_end"  

# 调用外部命令(查询设备ID),%N临时设备名
IMPORT{program}="/sbin/blkid -o udev -p %N"  

# 查询环境变量
ENV{ID_FS_TYPE}=="", GOTO="media_by_label_auto_mount_end"  

# 如果卷标不为空,则设置目录名称为卷标
ENV{ID_FS_LABEL}!="", ENV{dir_name}="%E{ID_FS_LABEL}"  
# 如果卷标为空,则设置目录名称为指定值
ENV{ID_FS_LABEL}=="", ENV{dir_name}="Untitled-%k"  

# ACTION表示事件动作,add表示添加设备
# 如果为添加设备时,设置挂载选顶
ACTION=="add", ENV{mount_options}="relatime,sync" 

# 如果文件系统为FAT格式时,设置挂载参数(编码,掩码)
ACTION=="add", ENV{ID_FS_TYPE}=="vfat", ENV{mount_options}="iocharset=utf8,umaskk=000"  

# 如果文件系统为FAT格式时,设置挂载参数(编码,掩码)
ACTION=="add", ENV{ID_FS_TYPE}=="ntfs", ENV{mount_options}="iocharset=utf8,umaskk=000"  

# 创建挂载所需要的目录
ACTION=="add", RUN+="/bin/mkdir -p /mnt/udisk/", RUN+="/bin/mount -o $env{mount_options} /dev/%k /mnt/udisk/"  

#----------------------------------
# 如果是卸载设备时,并且目录不为空时,卸载卷标,并删除目录
ACTION=="remove", ENV{dir_name}!="", RUN+="/bin/umount -l /mnt/udisk/}", RUN+="//bin/rmdir /mnt/udisk/"  

# 脚本结束标标签
LABEL="media_by_label_auto_mount_end"

参考文档:
http://233.sh/2016/07/21/pi-mount-udisk/
https://www.cnblogs.com/fah936861121/p/6496608.html

- 阅读全文 -

Linux系统应用--amixer声音控制


1.查看可操作的接口

# amixer controls

numid=4,iface=MIXER,name='Master Playback Switch'
numid=3,iface=MIXER,name='Master Playback Volume'
numid=2,iface=MIXER,name='Capture Switch'
numid=1,iface=MIXER,name='Capture Volume'

2.查看配置

# amixer contents

numid=4,iface=MIXER,name='Master Playback Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on
numid=3,iface=MIXER,name='Master Playback Volume'
  ; type=INTEGER,access=rw------,values=2,min=0,max=65536,step=1
  : values=38635,38635
numid=2,iface=MIXER,name='Capture Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on
numid=1,iface=MIXER,name='Capture Volume'
  ; type=INTEGER,access=rw------,values=2,min=0,max=65536,step=1
  : values=65536,65536

3.获取指定接口的音量值

# amixer cget numid=3

numid=3,iface=MIXER,name='Master Playback Volume'
  ; type=INTEGER,access=rw------,values=2,min=0,max=65536,step=1
  : values=2000,2000

min表示最小值,max表示最大值,values表示声音的个数;
最后一行的values表示当前音量,个数与上一行的values一致。

4.设置指定接口的音量值

# amixer cset numid=3 200,500
numid=3,iface=MIXER,name='Master Playback Volume'
  ; type=INTEGER,access=rw------,values=2,min=0,max=65536,step=1
  : values=200,500

 # amixer -c 0 set PCM 10db+

-c 指定声卡号
10db+表示音量增加10个db,减小音量用10db-;


设置当前接口的音量值

# amixer -M set PCM 50%

-M表示与alsamixer命令的百分比值相同


图型化控制命令:

# alsamixer

F6选择声卡,上下箭头加减音量


树莓派声音切换: Analog/HDMI

# amixer cset numid=3 1

实际上是‘PCM Playback Route’设备
0 - 自动适配
1 - 模拟输出
2 - HDMI

- 阅读全文 -

Linux进程间通信--信号量


文章摘要:
操作系统: Debian8


创建信号量:

$ ipcmk -S 1 -p 644
Semaphore id: 196609

查看信号量:

$ ipcs -s

------ Semaphore Arrays --------
key        semid      owner      perms      nsems      
0x0c01d24b 196609     user       644        1       

nsems表示信号量数量(非信号数量)

删除信号量:

$ ipcrm -s 196609

函数说明:

#include <sys/sem.h>
#include <sys/ipc.h>
/*
 * 函数原型: int semget(key_t key, int nsems, int oflag) 
 * 参数说明: key   - 键值
 *           nsems - 信号量个数
 *           oflag - 访问权限 
 * 返 回 值: semid
 */
semid = semget(0x1234, 1, IPC_CREAT | 0666);

PV操作

/*
 * 函数原型:int semop(int semid,
 *                    struct sembuf *opsptr, 
 *                    sizt_t nops);
 * 返 回 值:0 - 成功, -1 - Error
 */
struct sembuf semb;
semb.sem_num = 0;        // 信号量编号
semb.sem_op  = 1;        // 正值为V操作/负值为P操作
semb.sem_flg = SEM_UNDO; // {SEM_UNDO,SEM_NOWAIT}
semop(semid, &semb, 1);  // sembuf个数

sem_flg说明:
SEM_UNDO 表示在进程退出时,如果该进程占用其他资源,则操作系统释放该资源
SEM_NOWAIT 表示不阻塞


控制类操作:

/*
 * 函数原型:int semctl(int semid,   // 信号量标识
 *                     int semnum,   // 信号量编号
 *                     int cmd,      // 命令字
 *                     ...);         // 可选参数
 * 返 回 值:与操作相关
 */

设置指定信号量的信号值:

ret = semctl(semid, 0, SETVAL, 1);

获取指定信号量的信号值:

// 返回值表示该信号量的信号值
ret = semctl(semid, 0, GETVAL);

设置所有信号量的信号值:

unsigned short val[10]; 
memset(val, 1, 10);        
ret = semctl(semid, 0, GETALL, val);

获取所有信号量的信号值:

unsigned short val[10];
ret = semctl(semid, 0, GETALL, val);
  1. 信号量编号为0
  2. val数组长度需与nsem相同
  3. 返回值:0 - 成功, 负值 - 失败

删除所有信号:

ret = semctl(semid, 0, IPC_RMID);

- 阅读全文 -

Linux进程间通信--消息队列


文章摘要: 消息队列分为两种:System V消息队列和Posix消息队列。
操作系统: debian8
参考文档: 《UNIX网络编程卷2--进程间通信》


创建消息队列:

$ ipcmk -Q -p 644
Message queue id: 262145

查看消息队列:

$ ipcs -q
 
------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages    
0x08ffd99f 262145     user       644        0            0

删除消息队列:

$ ipcrm -q 262145

System V消息队列:System V消息队列比较简单,一共就那么4个函数就搞掂,但其与操作系统相关,大部分操作系统都支持。

打开消息队列:

#define    MSG_W    0200
#define    MSG_R    0400

int msgget(key_t key, int oflag);

msgid = msgget(0x1234, IPC_CREAT | S_IRUSR | S_IWUSR);

注意事项:
1.如果创建时不指定权限,会造成读写失败;
2.MSG_W与MSG_R未找到定义的头文件,实际上与S_IRUSR/S_IWUSR等值,所以可能新版本改为统一权限表;
3.key可用ftok函数产生,也可以直接指定数值,或者用IPC_PRVATE;

发送消息:

ret = msgsnd(msgid, &buf, 6, 0);

注意事项:
1.推荐第1个字段(4字节)固定为消息ID,后面跟消息内容(非强制要求,做消息筛选用)。

接收消息:

/*
 * 参数说明: msgid   - 消息队列标识
 *           buf     - 接收缓冲区
 *           bufsize - 缓冲区长度
 *           id      - 消息ID, 0表示接收所有消息
 *           flag    -  IPC_NOWAIT表示非阻塞模式,不指定默认为阻塞模式
 * 返 回 值: 正值:返回读取到的字节数,负值:读取失败
 */
ret = msgrcv(msgid, &buf,sizeof(buf), 0, IPC_NOWAIT);
struct msqid_ds info;
msgctl(msgid, IPC_RMID, NULL);    // 清空所有消息
msgctl(msgid, IPC_STAT, &info);   // 获取消息队列状态
msgctl(msgid, IPC_SET,  &info);   // 设置消息队列参数

Posix消息队列: Posix消息队列与文件操作相同,非系统标准库,编译时需指定-lrt选项。

- 阅读全文 -


Copyright©2025 春天花会开, All Rights Reserved. Email: webmaster@oroct.com