shell脚本之位运算+for循环+返回值承接+shell小数运算
用shell脚本实现某个寄存器的某几位设置
坑位1:
开发板上不认(ubuntu上可以)
for (( i=0;i<6;i++ ))
do
done
换成:
for i in `seq 0 6`
do
done
坑位2:
返回值承接用#?时默认只截取低8位
setbits $1 $2 $3 $4
regv=$?
printf "regv= %#x\n" $regv
发现只剩低八位
所以,换种承接方式吧:
regv=`regread $1`
这种方式是直接将命令执行或在屏幕上输出的东西接过来,是字符串。
坑位3:
如上面,reg=`regread $1`得到的字符串若用printf "%d" 是打印不到的,直接echo才行
坑位4:
reg=setbits $1 $2 $3 $4 这种方式来承接会爆语法错误,不是C语言。
坑位5:
$(( ))不支持浮点运算
得用bc 或者awk
坑位6:
用awk做小数运算时传入变量做参数要加一堆“‘”
如:
voltage=`awk 'BEGIN{print ("'"$interger1"'"+0.1*"'"$float1"'")*(1/1024)+0.1 }'`
最终测试成功,如下:
#######################################################
# test the sar-adc in SOC
#######################################################
regwrite()
{
devmem $1 32 $2
}
regread()
{
devmem $1
}
##argv[1] :origin data
##argv[2] :start bit
##argv[3] :end bit
##argv[4] :result
setbits()
{
value=$1
for i in `seq $2 $3`
do
mask=$(( 0x1 << $i ))
#printf "mask = %#x\n" $mask
value=$(( $value & ~$mask ))
#printf "clean bit %d value = %#x\n" $i $value
mask1=$(( 0x1 << ($i - $2) ))
#printf "mask1 = %#x\n" $mask1
bitv=$(( $4 & mask1 ))
#printf "bitv = %#x\n" $bitv
value=$(( $value | ($bitv << $2) ))
#printf "set bit %d value = %#x\n" $i $value
done
printf "%#x\n" $value
return $value
}
reg_set_bits()
{
regv=`regread $1`
regv=`setbits $regv $2 $3 $4 `
regwrite $1 $regv
}
reg_set_bits $1 $2 $3 $4
最终目的:
shell脚本实现adc读取转换结果:
#######################################################
# test the sar-adc in SOC
#######################################################
SAR_ADC_BASE_ADDR=0x03000c6c
SAR_ADC_REG1_ADDR=$(( $SAR_ADC_BASE_ADDR + 4 ))
SAR_ADC_REG2_ADDR=$(( $SAR_ADC_BASE_ADDR + 8 ))
SAR_ADC_OUT0_ADDR=$(( $SAR_ADC_BASE_ADDR + 0x0C ))
SAR_ADC_OUT1_ADDR=$(( $SAR_ADC_BASE_ADDR + 0X20 ))
SAR_ADC_OUT2_ADDR=$(( $SAR_ADC_BASE_ADDR + 0X24 ))
SAR_ADC_OUT3_ADDR=$(( $SAR_ADC_BASE_ADDR + 0x28 ))
SAR_TURN_ON_REG_ADDR=0x03000e04
SAR_ADC_STATE_REG_ADDR=0x03000c30
regwrite()
{
devmem $1 32 $2
}
regread()
{
devmem $1
}
##argv[1] :origin data
##argv[2] :start bit
##argv[3] :end bit
##argv[4] :result
setbits()
{
value=$1
for i in `seq $2 $3`
do
mask=$(( 0x1 << $i ))
#printf "mask = %#x\n" $mask
value=$(( $value & ~$mask ))
#printf "clean bit %d value = %#x\n" $i $value
mask1=$(( 0x1 << ($i - $2) ))
#printf "mask1 = %#x\n" $mask1
bitv=$(( $4 & mask1 ))
#printf "bitv = %#x\n" $bitv
value=$(( $value | ($bitv << $2) ))
#printf "set bit %d value = %#x\n" $i $value
done
printf "%#x\n" $value
return $value
}
reg_set_bits()
{
regv=`regread $1`
regv=`setbits $regv $2 $3 $4 `
regwrite $1 $regv
}
sar_turn_on()
{
reg_set_bits $SAR_TURN_ON_REG_ADDR 28 28 1
reg_set_bits $SAR_TURN_ON_REG_ADDR 27 27 1
}
saradc_enable()
{
reg_set_bits $SAR_ADC_BASE_ADDR 0 0 1
}
saradc_disable()
{
reg_set_bits $SAR_ADC_BASE_ADDR 0 0 0
}
soft_trigger()
{
if [ $1 -eq 1 ]; then
reg_set_bits $SAR_ADC_BASE_ADDR 8 8 1
else
reg_set_bits $SAR_ADC_BASE_ADDR 8 8 0
fi
}
#argv[1]: x MHz
set_bauderate()
{
diver=$(( 40 / $1 ))
reg_set_bits $SAR_ADC_BASE_ADDR 24 31 $diver
}
#argv[1]: n * bauderate
delay_before_scan()
{
reg_set_bits $SAR_ADC_REG1_ADDR 0 31 $1
}
#argv[1]: (n+2) * 1/40MHz
delay_before_capture()
{
reg_set_bits $SAR_ADC_REG2_ADDR 0 15 $1
}
#argv[1]: channel0~channel3 --> bit0~bit3
sarctrl_chsel()
{
reg_set_bits $SAR_ADC_BASE_ADDR 20 23 $1
}
#argv[1]: sample 2^n times
saradc_cycletimes()
{
reg_set_bits $SAR_ADC_BASE_ADDR 9 17 $1
}
saradc_init()
{
sar_turn_on
saradc_disable
set_bauderate 10
delay_before_scan 5
delay_before_capture 3
sarctrl_chsel 0x0f
saradc_cycletimes 1
}
read_ad()
{
saradc_enable
soft_trigger 1
tmp=`regread $SAR_ADC_STATE_REG_ADDR`
tmp=$(( $tmp & 0x80000000 ))
timeout=200;
timeout_flag=0
while [ $tmp -eq 0 ]
do
sleep 0.01
timeout=$(( $timeout - 1 ))
if [ $timeout -lt 3 ]; then
timeout_flag=1
break;
fi
done
if [ $timeout_flag -eq 0 ]; then
out0=`regread $SAR_ADC_OUT0_ADDR`
echo "out0= $out0"
interger0=$(( $out0 >> 8 ))
printf "INTERGER0= %d \n" $interger0
float0=$(( $out0 & 0xff ))
printf "adc_val0 = 0.1 + ref/2^n * %d.%d = " $interger0 $float0
voltage=`awk 'BEGIN{print ("'"$interger0"'"+0.1*"'"$float0"'")*(1/1024)+0.1 }'`
echo "$voltage V"
#voltage=`bc <<< "scale=4;77.0*(1/1024)+0.1"`
#echo "= $voltage V"
out1=`regread $SAR_ADC_OUT1_ADDR`
interger1=$(( $out1 >> 8 ))
float1=$(( $out1 & 0xff ))
printf "adc_val1 = 0.1 + ref/2^n * %d.%d = " $interger1 $float1
voltage=`awk 'BEGIN{print ("'"$interger1"'"+0.1*"'"$float1"'")*(1/1024)+0.1 }'`
echo "$voltage V"
out2=`regread $SAR_ADC_OUT2_ADDR`
interger2=$(( $out2 >> 8 ))
float2=$(( $out2 & 0xff ))
printf "adc_val2 = 0.1 + ref/2^n * %d.%d = " $interger2 $float2
voltage=`awk 'BEGIN{print ("'"$interger2"'"+0.1*"'"$float2"'")*(1/1024)+0.1 }'`
echo "$voltage V"
out3=`regread $SAR_ADC_OUT3_ADDR`
interger3=$(( $out3 >> 8 ))
float3=$(( $out3 & 0xff ))
printf "adc_val3 = 0.1 + ref/2^n * %d.%d = " $interger3 $float3
voltage=`awk 'BEGIN{print ("'"$interger3"'"+0.1*"'"$float3"'")*(1/1024)+0.1 }'`
echo "$voltage V"
echo "note: if output is 0.1V , it maybe lower then 0.1V."
else
echo "waite saradc_done flag bit timeout"
fi
soft_trigger 0
saradc_disable
}
saradc_init
read_ad
浙公网安备 33010602011771号