[Linux]嵌入式系统中栈的地址空间传入

根据系统的memory mapping,链接脚本中规定有栈顶的地址(栈地址变换为从上往下,从大到小,因此规定栈顶)
  __stack_top = ORIGIN(SRAM) + LENGTH(SRAM); //在此规定从ram胡最后开始为栈顶
__stack_bottom = __stack_top – __stack_size
也可以动态计算栈地址
.stack (NOLOAD) : {
. = ALIGN(4) ;
__irq_stack_start = .;
. += 1024;
__irq_stack = .;
__stack_start = .;
__stack_size = __RAM_END – ABSOLUTE(.) – 4;
. += __stack_size;
__stack = .;
} > REGION_BSS

在start.S中,需要拿到栈顶地址
.import __stack_top
会将__stack_top这个变量的地址load到cpu的sp寄存器,从而规定其初始地址
后续栈的使用由程序调用过程决定。这可以理解成编译器维护?

[Ffmpeg]语音文件采样率转换,左右双声道数据分离

单声道-多声道互转
ffpmeg -i test.mp3 -ar 16000 -ac 2 test.wav
test.mp3为原文件,可以为单声道,test.wav为输出文件
-ar表示新文件的采样率
-ac 2 为新文件的声道数
以上命令完成了将单声道test.mp3文件转为16k 双声道wav文件。
左右声道分拆
ffmpeg -i test.wav -map_channel 0.0.0 left.wav -map_channel 0.0.1 right.wav
以上命令表示将双声道test.wav分别拆成左声道右声道两个文件。
只用于双声道,具体解释见链接
PCM转wav
ffmpeg -f s16le -ar 16k -ac 1 -i file.pcm file.wav
s16le 表示16bit’小端

[Linux]静态库.a文件通过链接脚本加入特定段section

部分情况下我们需要将特定文件的特定段进行放入特定位置,在有源码的情况下,比较简单,但是有时候我们之后编译好的静态库。
由于.a文件是由.o文件压缩而来,所以想要修改.a文件,需要分别控制.o的链接位置。
可以通过ar -x libXXX.a解压,或者使用objdump -t libXXX.a查看所有文件。得到文件名之后(假设test0.o test1.o test2.o)
我们现在想把libXXX.a的data放入特定段,可以修改链接脚本
.data : {
. = ALIGN(0x4) ;
__sdata = .;
*(.data)
*(.data*)
修改为:
.data : {
. = ALIGN(0x4) ;
__sdata = .;
*(EXCLUDE_FILE(*test0.o test1.o test2.o).data*)
#此语句表示“除了3个.o文件之外的所有data*段”,所以需要删除下面两行,否则还是会链接到此处
*(.data)
*(.data*)
然后在需要放的位置修改链接脚本
.new_data :
{
. = ALIGN(0x4) ;
__newdata_start = . ;
*(.new_data) ;
*test0.o(.data*)
*test1.o(.data*)
*test2.o(.data*)
__newdata_end = . ;
} > NEW_PLACE
注意文件名前面的星号
NOLOAD :该section在程序运行时,不被载入内存。

[Ubuntu]修正Ubuntu从1604升级1804之后php无法解析问题

这两天把VPS系统从1604升级到1804,升级之后php无法解析,所有php页面都显示源码。

使用网上网上搜到的方法已经解决,具体步骤如下:

sudo apt-get –purge remove php*
sudo apt autoremove
sudo apt-get install php

安装如下插件,如果不需要可以不安装。

libapache2-mod-php* libapache2-mod-php7.2* php-common* php-curl* php-mbstring* php-mysql* php-xml* php-zip* php7.2-curl* php7.2-cli* php7.2-common* php7.2-curl*
php7.2-json* php7.2-mbstring* php7.2-mysql* php7.2-opcache* php7.2-readline* php7.2-xml* php7.2-zip*

重启apache(或者其他http服务端)

/etc/init.d/apache2 restart

数字信号处理中一些基本概念

最近在看数字信号处理相关内容,其中遇到各种名词概念。虽然名称都听说过也确定学过,这么多年了基本一点印象也没有了。下面整理了一些学习过程中遇到的一些基本概念,后续还会持续更新。
==================================================================

复数:a+bi
模:sqrt(a*a+b*b),复平面上点到原点距离
共轭,实部相同,虚部相反
对于复频域,一个频率上的模的平方,表示这个频率分量能量的大小

复数乘法的定义为:(a+bi)(c+di)=(ac-bd)+(bc+ad)i

信号的频谱由两部分构成:幅度谱和相位谱。

所谓的能量谱,也称为能量谱密度,是指用密度的概念表示信号能量在各频率点的分布情况。也即是说,对能量谱在频域上积分就可以得到信号的能量。能量谱是信号幅度谱的模的平方

所谓的功率谱,也称为功率谱密度,是指用密度的概念表示信号功率在各频率点的分布情况。也就是说,对功率谱在频域上积分就可以得到信号的功率。从理论上来说,功率谱是信号自相关函数的傅里叶变换。

功率谱是功率谱密度函数(PSD)的简称,它定义为单位频带内的信号功率。
一段信号的功率谱等于这段信号自相关函数的傅里叶变换。

互相关函数是描述随机信号x(t),y(t)在任意两个不同时刻t1,t2的取值之间的相关程度,
自相关函数是描述随机信号x(t)在任意两个不同时刻t1,t2的取值之间的相关程度。
设原函数是f(t),则自相关函数定义为R(u)=f(t)*f(-t),其中*表示卷积;
设两个函数分别是f(t)和g(t),则互相关函数定义为R(u)=f(t)*g(-t),它反映的是两个函数在不同的相对位置上互相匹配的程度。

偏度(Skewness):是描述数据分布形态的统计量,其描述的是某总体取值分布的对称性,简单来说就是数据的不对称程度。。
偏度是三阶中心距计算出来的。
(1)Skewness = 0 ,分布形态与正态分布偏度相同。
(2)Skewness > 0 ,正偏差数值较大,为正偏或右偏。长尾巴拖在右边,数据右端有较多的极端值。
(3)Skewness < 0 ,负偏差数值较大,为负偏或左偏。长尾巴拖在左边,数据左端有较多的极端值。
(4)数值的绝对值越大,表明数据分布越不对称,偏斜程度大。
计算公式:
Skewness=E[((x-E(x))/(\sqrt{D(x)}))^3]
| Skewness| 越大,分布形态偏移程度越大。

分位数(英语:Quantile),亦称分位点,是指用分割点(cut point)将一个随机变量的概率分布范围分为几个具有相同概率的连续区间。分割点的数量比划分出的区间少1,例如3个分割点能分出4个区间。

频谱平坦度也叫做维纳熵,即各个频率分量的几何平均数与算术平均数的比值。

算术平均数[公式]
几何平均数[公式]

白噪声,是一种功率谱密度为常数的随机信号或随机过程。即此信号在各个频段上的功率一致。由于白光是由各种频率(颜色)的单色光混合而成,因而此信号的平坦功率谱性质称为“白色”,此信号也因此得名为白噪声。相对的,其他不具有这一性质的噪声信号则称为有色噪声。

[Linux]ELF中.eh_frame段的简单说明

最近在进行某个So文件的size优化,通过命令(readelf -t/objdump -h)发现.eh_frame段占了一定的空间,如下:
12 .rodata 0001a9f0 000de060 000de060 000de060 2**5
CONTENTS, ALLOC, LOAD, READONLY, DATA
13 .eh_frame_hdr 00005914 000f8a50 000f8a50 000f8a50 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
14 .eh_frame 0001b984 000fe364 000fe364 000fe364 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA

网上搜了一下,发现这个段主要用于系统运行时调试使用的,便于栈展开调试(跟-g选项不同,-g信息可以通过strip命令去掉)。

若要去掉此段信息,可以通过-fno-asynchronous-unwind-tables编译选项,但是可能无法完全去除,原因是编译使用的的其他.o可能未加此选项。

12 .rodata 0001a9f0 000de060 000de060 000de060 2**5
CONTENTS, ALLOC, LOAD, READONLY, DATA
13 .eh_frame_hdr 00000034 000f8a50 000f8a50 000f8a50 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
14 .eh_frame 000000fc 000f8a84 000f8a84 000f8a84 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA

eh_frame_hdr保存着eh_frame的额外信息,包括指向eh_frame数据起始地址的指针以及a binary search table of pointers to the .eh_frame records are found in this section.

关于eh_frame_hdr信息:
https://refspecs.linuxfoundation.org/LSB_1.3.0/gLSB/gLSB/ehframehdr.html

相关信息来源:https://stackoverflow.com/questions/26300819/why-gcc-compiled-c-program-needs-eh-frame-section

[LINUX]Linux终端快速输入上一条命令的某个参数

在很多时候,我们在Linux终端输入的命令之间有一定的关联。

比如,新建一个目录,然后进入到这个目录,我们需要输入两条命令:
mkdir newdir
cd newdir

为了方便,在输入第二条命令进入到新目录的时候,我们可以使用快捷键快速输入“newdir”,这个快捷键就行ALT+.    输入之后自动会将newdir补上。

ALT+.即为上一条命令最后一个参数的快捷键。

如果上一条命令有多个参数,比如mkdir a b c,

现在要进入到目录b,我们可以输入cd !!:2  (第二个参数)

 

[Video]ffmpeg将视频文件转为YUV420

ffmpeg是一个很强大的视频编解码工具,最近使用了其解码为yuv420格式的功能。

命令如下:ffmpeg -i inputfile.avi -ss 00:00:00 -t 00:00:20 -s 320*240 -r 24 output.yuv

-ss表示截取视频的起始时间 -t为截取的总时间
-s表示输出文件的分辨率 -r表示输出文件的帧率

生成的YUV为l420格式,针对一帧的视频来说,所有的Y都在前面,然后是所有的U,最后是所有的V。针对320*240的一帧来说,数据量为320*240+320*240/4+320*240/4

即YYYYYYYYYYYYYYYYY…(320*240)UUUUUUUUUU…(320*240/4)VVVVV….(320*240/4)

然后是下一帧。

[Linux]推荐一个Ubuntu下socks客户端 proxychains

proxychains可以通过配置代理,让本机的应用通过代理访问互联网。

安装:apt-get install proxychains

配置:sudo vi /etc/proxychains.conf

在[ProxyList]之后加上自己的代理方式跟地址,如

socks5 127.0.0.1 1080​

使用:proxychains 要使用代理的命令

如:proxychains curl www.baidu.com