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