1.通达信捕捉牛股利器 条件选股公式
2.拉升建仓资金指标源码
3.OpenHarmony 3GPP协议开发深度剖析——一文读懂RIL
通达信捕捉牛股利器 条件选股公式
通达信选股公式:
条件选股公式源码:
年认同价:=MA(C,源码仓);
价格中枢:=(SUM(年认同价,0)/(BARSSINCE(年认同价>0)+));
箱顶:=价格中枢*1.2;
箱底:=价格中枢*0.8;
毛利润率:=FINANCE()/FINANCE();
成长价值:=年认同价*(1+毛利润率);
收益价值:=年认同价+FINANCE();
回调认同:=EMA(EXPMA(C,),);
多头:=(回调认同>REF(回调认同,1))AND(成长价值>REF(成长价值,1))AND(收益价值>REF(收益价值,1))AND(DYNAINFO(7)>0);
回调条件:=COUNT(C<回调认同,5)>=3;
回调突破:=(REF(C,1)<=REF(回调认同,1))AND(C>回调认同)AND(回调条件)AND多头;
成长条件:=COUNT(C<成长价值,5)>=3;
成长突破:=(REF(C,1)<=REF(成长价值,1))AND(C>成长价值)AND(成长条件)AND多头;
收益条件:=COUNT(C<收益价值,5)>=3;
收益突破:=(REF(C,1)<=REF(收益价值,1))AND(C>收益价值)AND(收益条件)AND多头;
箱底条件:=COUNT(C<箱底,5)>=3;
箱底突破:=(REF(C,1)<=REF(箱底,1))AND(C>箱底)AND(箱底条件)AND多头;
价格条件:=COUNT(C<价格中枢,5)>=3;
价格突破:=(REF(C,1)<=REF(价格中枢,1))AND(C>价格中枢)AND(价格条件)AND多头;
箱顶条件:=COUNT(C<箱顶,5)>=3;
箱顶突破:=(REF(C,1)<=REF(箱顶,1))AND(C>箱顶)AND(箱顶条件)AND多头;
突破买点:(回调突破+成长突破+收益突破+箱底突破+价格突破+箱顶突破);
专买老鼠仓
{ 老鼠仓}
AA1:=AMOUNT/V;
BB1:=L<AA1*0.9;
CC1:=(C-REF(C,1))/REF(C,1)*>1.2;
DD1:=L<MA(C,5)*0.;
EE1:=V<MA(V,5)*1.5;
FF1:=BB1 AND CC1 AND DD1 AND EE1;
DRAWTEXT(FF1,(LOW* 0.),'老鼠仓'),COLORFF;
老鼠仓是个很不错的指标,信号发出一般都在一个波段的源码仓底部起涨之时。
根据本人的源码仓实践,使用指标时候要注意几点:
1 该指标可以添加到任何一个主图里面去,源码仓比如MA均线什么的源码仓。
2 出现信号当天买进股票,源码仓移动端商城源码第二天收阳继续持股,源码仓直到出阴为止。源码仓
3 第二天出阴考虑卖出,源码仓非常适合短线操作!源码仓
老鼠仓(选股公式)
AA1:=AMOUNT/V;
BB1:=L<AA1*0.9;
CC1:=(C-REF(C,源码仓1))/REF(C,1)*>1.2;
DD1:=L<MA(C,5)*0.;
EE1:=V<MA(V,5)*1.5;
老鼠仓:BB1AND CC1 AND DD1 AND EE1;
理想选股(选股公式)
VAR1:=MA((LOW+HIGH+CLOSE)/3,5);
VAR2:=CLOSE=HHV(C,4) AND REF(C,1)=LLV(C,4);
VAR3:=REF(C,1)=LLV(C,4) AND C>=REF(C,2) OR REF(C,2)=LLV(C,4) ANDREF(C,1)<=REF(C,3) AND REF(C,2)<REF(C,4) AND C>=REF(C,1);
VAR4:=VAR1>REF(VAR1,1) AND REF(VAR1,1)<REF(VAR1,2);
VAR5:=LOW<HHV(VAR1,) AND HIGH>HHV(VAR1,) AND CLOSE>REF(C,1) ANDCLOSE>OPEN;
VAR6:=VAR5 AND COUNT(VAR4,2);
VAR7:=VAR6 AND NOT(REF(VAR6,1));
VAR8:=*EMA(EMA(C-REF(C,1),6),6)/EMA(EMA(ABS(C-REF(C,1)),6),6);
VAR9:=EMA(MA(C,),);
VAR:=FILTER((LLV(VAR8,2)=LLV(VAR8,7) AND COUNT(VAR8<0,2) ANDCROSS(VAR8,MA(VAR8,2)))=1,5);
VAR:=SMA(EMA((C-REF(C,1))/REF(C,1),5)*,3,1)*;
VAR:=FILTER(((CROSS(VAR,0) OR CROSS(C,VAR9)) AND VAR)=1,3);
VAR:=MA(C,)>=REF(MA(C,),3) AND CROSS(C,MA(C,));
RSV:=(CLOSE-LLV(LOW,9))/(HHV(HIGH,9)-LLV(LOW,9))*;
K:=SMA(RSV,3,1);
D:=SMA(K,3,1);
J:=3*K-2*D;
金叉:=CROSS(J,D);
死叉:=CROSS(D,J);
买1:=(VAROR VAR) AND VAR;
买2:=(VAROR VAR) AND VAR3;
买3:=(VAROR VAR) AND VAR2;
买4:=(VAR2AND VAR) OR (VAR3 AND VAR);
买5:=(金叉AND VAR3) OR (金叉 AND VAR2) OR (金叉 AND VAR);
ST:=EXIST(C/REF(C,1)>1.,);
输出:=(买1OR 买2OR 买3OR 买4OR 买5OR VAR7) AND ST;
MA5:=MA(C,5),COLORWHITE;
X:=(3*C+L+O+H)/6;
多空线:=(*X+*REF(X,1)+*REF(X,2)+*REF(X,3)+*REF(X,4)+*REF(X,5)+*REF(X,6)
+*REF(X,7)+*REF(X,8)+*REF(X,9)+*REF(X,)+9*REF(X,)+8*REF(X,)
+7*REF(X,)+6*REF(X,)+5*REF(X,)+4*REF(X,)+3*REF(X,)+2*REF(X,)+
REF(X,))/,COLORFFFF,LINETHICK1;
AB:=DRAWLINE(HIGH>=HHV(HIGH,),HIGH,LOW<=LLV(LOW,3),HHV(HIGH,3),1),COLORYELLOW;
CROSS(MA5,多空线) and CROSS(C,AB) and 输出 ;
点石成金(选股公式)
KS:=(CLOSE-MA(CLOSE,))/MA(CLOSE,)*(-);
RSV:=(CLOSE-LLV(LOW,))/(HHV(HIGH,)-LLV(LOW,))*;
FASTK:=SMA(RSV,3,1);K:=SMA(FASTK,3,1);D:=SMA(K,5,1);
Var1:=CLOSE/MA(CLOSE,)*<;
Var2:=CLOSE/MA(CLOSE,)*<;
Var3:=HIGH>LOW*1.;
Var4:=Var3 AND COUNT(Var3,5)>1;
Var4 AND (Var1 OR Var2) AND REF(KS,1)>= AND REF(KS,1)/KS>=1.AND
CLOSE/REF(CLOSE,1)>=1.;
牛市绝底(选股公式)
VAR1:=REF(CLOSE,1);
VAR2:=((SMA(MAX((CLOSE - VAR1),0),7,1) / SMA(ABS((CLOSE - VAR1)),7,1)) * );
VAR3:=((SMA(MAX((CLOSE - VAR1),0),,1) / SMA(ABS((CLOSE - VAR1)),,1)) *);
VAR4:=(( * (HHV(HIGH,) - LOW)) / HHV(HIGH,));
VAR5:=(( * (HIGH - LLV(LOW,))) / LLV(LOW,));
牛市绝底:VAR2< AND VAR3 < AND (VAR2 + VAR3) > AND VAR4 > ANDBARSCOUNT(CLOSE) > ;
飞弹一号(选股公式)
var1:=c/ma(c,)*<;
var2:=c/ma(c,)*<;
var3:=h>=l*1.;
var4:=var3 and count(var3,5)>=2;
xg:var4 and (var1 or var2) and count(h=l and c=o and c<ref(c,1),3)=0
and hhv(v/capital,)<0.8;
跟庄建仓源码
A:=DYNAINFO(7);
A:=BARSCOUNT(CLOSE);
A:=(SMA((CLOSE / HHV(HIGH,)),3,1) * );
A:=IF((A > ),A,0);
A:=IF((LOW > A),0,IF((HIGH < A),1,(((A - LOW) + 0.) / ((HIGH -LOW) + 0.))));
A:=DMA(A,(VOL / CAPITAL)) * ;
A:=IF((((A > 0) AND (A > REF(A,1))) AND (A <= )),A,0);
Var1:=3*SMA((CLOSE-LLV(LOW,))/(HHV(HIGH,)-LLV(LOW,))*,5,1)-2*SMA(SMA((CLOSE-LLV(LOW,))/(HHV(HIGH,)-LLV(LOW,))*,5,1),3,1);
Var2:=EMA(Var1,8);
Var3:=3*SMA((C-LLV(L,))/(HHV(H,)-LLV(L,))*,5,1)-2*SMA(SMA((C-LLV(L,))/(HHV(H,)-LLV(L,))*,5,1),3,1);
趋势:=EMA(Var3,3)-;
STICKLINE(趋势>,趋势,,5,0);
DRAWICON(CROSS(趋势,0),0,1);
STICKLINE((A > 0 AND (趋势< OR 趋势>REF(趋势,1)AND趋势<)),0,A,6,0),colorFFff;
机构建仓区:0,LINETHICK0,colorFFFF;
Var4:=(趋势-REF(趋势,1))/REF(趋势,1)*;
STICKLINE(趋势<=,0,,3,0),colorcc;
DRAWTEXT(FILTER(趋势<=,),,'准备现金'),colorcc;
STICKLINE(趋势<= AND Var4>,0,,2,0),colorff;
Var5:=FILTER((趋势<= AND Var4>),);
DRAWTEXT(Var5,,'买入'),colorff;
STICKLINE(趋势>= AND Var4,0,,3,0),colorgray;
Var6:=FILTER((趋势>= AND Var4),);
DRAWTEXT(Var6,,'清仓'),colorgray;
Var7:=LLV(LOW,);
Var8:=HHV(HIGH,);
Var9:=EMA((CLOSE-Var7)/(Var8-Var7)*4,4)*;
STICKLINE(Var9>,,,3,2),COLORRED;
Var:=(Var9-LLV(Var9,4))/(HHV(Var9,4)-LLV(Var9,4))*;
DRAWTEXT(IF(CROSS(Var9,Var) AND Var9>,,0),,'险'),ColorFF;
DRAWICON(CROSS(,Var9),,9);
Var:=SMA(ABS(L-REF(L,1)),3,1)/SMA(MAX(L-REF(L,1),0),3,1)*;
Var:=HHV(Var,)*8;
火焰山:EMA(IF(LOW<=Var7AND 趋势<,(Var+Var),0),3)/,COLORRED,linethick2;
STICKLINE(火焰山>0,0 ,火焰山*1.2,4,0 ),COLORRED;
Var:=(MA(C,1)+MA(C,3)+MA(C,5)+MA(C,7)+MA(C,9))/5;
Var:=(MA(C,2)+MA(C,4)+MA(C,6)+MA(C,8)+MA(C,))/5;
趋势线:趋势,colorff;
Var:=MAX(EMA(Var,2)-EMA(Var,5),0)*;
Var:=EMA(Var,5);
波浪峰:Var,stick,colorffff;
STICKLINE(Var<REF(Var,1),0,Var,1,0),colorff;
Var:=MA(趋势线,8);
if(CROSS(Var2,Var) AND Var2<,,0),COLORRED;
DRAWTEXT(CROSS(趋势线,Var2)AND 趋势线>REF(趋势线,1)AND 趋势线<,,'追涨'),COLORffff;
风险区:IF(趋势>,趋势,),colorffff;
双信号"全仓"选股(选股公式)
FF:=EMA(CLOSE,3);
MA:=EMA(CLOSE,);
TTJ:=CROSS(FF,MA);
上:=EMA(C,3),COLORBLUE,LINETHICK1;
中:=EMA(C,5),COLORWHITE,LINETHICK1;
下:=EMA(中,5),COLORFF,LINETHICK1;
QQ:= C<中;
MM:=上>REF(上,1)AND REF(上,1)<REF(上,2) ;
V1:=ABS((2*CLOSE+HIGH+LOW)/4-MA(CLOSE,))/MA(CLOSE,);
V2:=(1-7/)*(DMA(CLOSE,V1));
V3:=(1+7/)*(DMA(CLOSE,V1));
V5:=MA((LOW+HIGH+CLOSE)/3,5);
MA1:=MEMA(CLOSE,5);
MA2:=ATAN((MA1/REF(MA1,1)-1)*)*/3.;
MA3:=IF(MA2>0,MA2,MA2);
MA5:=MA(CLOSE,5),COLOR;
MA:=MA(CLOSE,),COLORFFF0,LINETHICK2;
VAR:=CLOSE=HHV(C,4) AND (REF(C,1)>=REF(C,2) OR REF(C,1)>=REF(C,3))
OR REF(C,1)=HHV(C,4) AND CLOSE>=REF(C,2) OR REF(C,2)=HHV(C,4) AND
REF(C,3)=LLV(C,4) AND C>=REF(C,1) OR REF(C,3)=HHV(C,4) AND
C>=REF(C,1) AND C>=REF(C,2);
{ 收盘价=4日内收盘价的最高值AND 昨收>=2日前的收盘价}
VAR:=CLOSE=HHV(C,4) AND REF(C,1)=LLV(C,4);
{ 收盘价=4日内收盘价的最高值AND 昨收=4日内收盘价的最低值}
VAR:=CLOSE=LLV(C,4) AND (REF(C,1)<REF(C,2) OR REF(C,1)<REF(C,3)) OR
REF(C,1)=LLV(C,4) AND C<REF(C,2) OR REF(C,2)=LLV(C,4) AND
REF(C,1)=HHV(C,4) AND C<REF(C,1) OR REF(C,3)=LLV(C,4) AND
C<REF(C,1) AND C<REF(C,2);
{ 收盘价=4日内收盘价的最低值AND (昨收<2日前的收盘价}
VAR:=REF(C,1)=LLV(C,4) AND C>=REF(C,2) OR REF(C,2)=LLV(C,4) AND
REF(C,1)<=REF(C,3) AND REF(C,2)<REF(C,4) AND C>=REF(C,1);
{ 昨收=4日内收盘价的最低值AND 收盘价>=2日前的收盘价}
VAR:=REF(C,1)=HHV(C,4) AND C<REF(C,2) OR (REF(C,2)=HHV(C,4) AND
REF(C,1)>REF(C,3) OR REF(C,3)=HHV(C,4) AND REF(C,1)>REF(C,2)) AND
REF(C,2)>=REF(C,4) AND C<REF(C,1);
{ 昨收=4日内收盘价的最高值AND 收盘价<2日前的收盘价}
VAR:=V5>REF(V5,1) AND REF(V5,1)<REF(V5,2);
{ 今日V5向上形成拐点}
VAR:=LOW<HHV(V5,) AND HIGH>HHV(V5,) AND CLOSE>REF(C,1) ANDCLOSE>OPEN;
VAR:=VAR AND COUNT(VAR,2);
VAR:=*EMA(EMA(C-REF(C,1),6),6)/EMA(EMA(ABS(C-REF(C,1)),6),6);
VAR:=EMA(MA(C,),);
VAR:=FILTER((LLV(VAR,2)=LLV(VAR,7) AND COUNT(VAR<0,2) AND
CROSS(VAR,MA(VAR,2)))=1,5);
VAR:=FILTER((HHV(VAR,2)=HHV(VAR,7) AND COUNT(VAR>,2) AND
CROSS(MA(VAR,2),VAR))=1,1);
VAR:=SMA(EMA((C-REF(C,1))/REF(C,1),5)*,3,1)*;
VAR:=FILTER(((CROSS(VAR,0) OR CROSS(C,VAR)) AND VAR)=1,3);
VAR:=MA(C,)>=REF(MA(C,),3) AND CROSS(C,MA(C,));
VAR:=VAR AND NOT(REF(VAR,1));
RSV:=(CLOSE-LLV(LOW,9))/(HHV(HIGH,9)-LLV(LOW,9))*;
K:=SMA(RSV,3,1);
D:=SMA(K,3,1);
J:=3*K-2*D;
金叉:=CROSS(J,D);
死叉:=CROSS(D,J);
买1:=(VAROR VAR) AND VAR;
买2:=(VAROR VAR) AND VAR;
买3:=(VAROR VAR) AND VAR;
买4:=(VARAND VAR) OR (VAR AND VAR);
买5:=(金叉AND VAR) OR (金叉 AND VAR) OR (金叉 AND VAR);
TTJ0:=VAR;
TTJ1:=买1OR 买2OR 买3OR 买4OR 买5AND MM;
XG0:=TTJ AND TTJ0;
XG1:=TTJ AND TTJ1;
XG:=XG0 OR XG1;
{ 以下波浪理论浪底重叠"买底"选股原码}
PL5:=ZIG(3,5);
EN1:=ZIG(3,5)>REF(ZIG(3,5),1) AND REF(ZIG(3,5),1)<=REF(ZIG(3,5),2) ANDREF(ZIG(3,5),2)<=REF(ZIG(3,5),3);
EX1:=ZIG(3,5)<REF(ZIG(3,5),1) AND REF(ZIG(3,5),1)>=REF(ZIG(3,5),2) ANDREF(ZIG(3,5),2)>=REF(ZIG(3,5),3);
PL:=ZIG(3,);
EN2:=ZIG(3,)>REF(ZIG(3,),1) AND REF(ZIG(3,),1)<=REF(ZIG(3,),2)AND REF(ZIG(3,),2)<=REF(ZIG(3,),3);
EX2:=ZIG(3,)<REF(ZIG(3,),1) AND REF(ZIG(3,),1)>=REF(ZIG(3,),2)AND REF(ZIG(3,),2)>=REF(ZIG(3,),3);
PL:=ZIG(3,);
EN3:=ZIG(3,)>REF(ZIG(3,),1) AND REF(ZIG(3,),1)<=REF(ZIG(3,),2)AND REF(ZIG(3,),2)<=REF(ZIG(3,),3);
EX3:=ZIG(3,)<REF(ZIG(3,),1) AND REF(ZIG(3,),1)>=REF(ZIG(3,),2)AND REF(ZIG(3,),2)>=REF(ZIG(3,),3);
PL:=ZIG(3,);
走强1:=BARSLAST(PL5<REF(PL5,1));
走弱1:=BARSLAST(PL5>REF(PL5,1));
走强2:=BARSLAST(PL<REF(PL,1));
走弱2:=BARSLAST(PL>REF(PL,1));
走强3:=BARSLAST(PL<REF(PL,1));
走弱3:=BARSLAST(PL>REF(PL,1));
ZTJZ5:=IF(PL>REF(PL,1),COUNT(EN1,走强2),0);
ZTJD5:=IF(PL>REF(PL,1),COUNT(EX1,走强2),0);
DTJZ5:=IF(PL<REF(PL,1),COUNT(EN1,走弱2),0);
DTJD5:=IF(PL<REF(PL,1),COUNT(EX1,走弱2),0);
ZTJZ:=IF(PL>REF(PL,1),COUNT(EN2,走强3),0);
ZTJD:=IF(PL>REF(PL,1),COUNT(EX2,走强3),0);
DTJZ:=IF(PL<REF(PL,1),COUNT(EN2,走弱3),0);
DTJD:=IF(PL<REF(PL,1),COUNT(EX2,走弱3),0);
TJ:=EN2 AND ZTJZ5=1;
TJ:=EN1 AND PL>REF(PL,1) AND ZTJZ5=2;
TJ:=EN2 AND DTJZ=1;
TJ:=EN3 AND ZTJZ=1;
TJ:=EN2 AND PL>REF(PL,1) AND ZTJZ=2;
XG:=TJ OR TJ OR TJ OR TJ OR TJ;
{ 以下二者结合共同选股}
XG:=XG OR XG;
W:EXIST(XG,1);
拉升建仓资金指标源码
拉升建仓资金指标源码并不是一个固定或标准化的代码,它依赖于特定的源码仓交易策略、市场条件以及编程语言。源码仓通常,源码仓这种指标是源码仓由交易者或开发者根据他们的交易系统和需求自定义编写的。因此,我不能提供一个普遍适用的青云志源码分析“拉升建仓资金指标源码”。
拉升建仓资金指标是技术分析中的一个工具,用于帮助交易者识别可能的买入点,特别是在股价经历一段时期的横盘或下跌后,出现资金大量流入、买盘增强、股价有拉升迹象的情况。这个指标可能是基于成交量、价格动向、资金流向等多个因素的综合分析。
在编写这样的指标源码时,交易者首先需要确定他们所使用的交易平台和编程语言。流行的交易平台如MetaTrader(使用MQL4或MQL5语言)、TradeStation(使用EasyLanguage)或ZigZagTrader等,都有自己的编程环境。
源码的编写通常从定义指标的计算逻辑开始。例如,免费论坛源码搭建交易者可能想要跟踪特定时间段内的成交量增加情况,同时结合价格的上涨来确定拉升建仓的信号。这涉及到编写代码来计算成交量的移动平均、价格的变动率等,并设置适当的阈值来确定买入信号。
示例代码片段(假设使用MQL4语言):
mql4
// 定义一个简单的拉升建仓资金指标
// 该指标基于成交量和价格的上涨
// 输入参数
input int Period = ; // 计算平均值所用的周期
input double VolumeThreshold = 1.5; // 成交量增加的阈值
input double PriceIncreaseThreshold = 0.; // 价格上涨的阈值
// 变量声明
double VolumeMA; // 成交量的移动平均值
double PriceChange; // 价格变动量
// 主函数
int OnInit()
{
// 初始化代码
return(INIT_SUCCEEDED);
}
void OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[])
{
// 计算成交量的移动平均值
double sum_volume = 0;
for(int i = 0; i < Period; i++)
{
sum_volume += volume[i];
}
VolumeMA = sum_volume / Period;
// 计算价格变动量
PriceChange = (close[0] - close[1]) / close[1];
// 判断是否满足拉升建仓条件
if(tick_volume[0] > VolumeMA * VolumeThreshold && PriceChange > PriceIncreaseThreshold)
{
// 输出信号或执行交易操作
// ...
}
}
请注意,上述代码仅作为一个非常基础的示例,实际中的拉升建仓资金指标可能会更加复杂,并可能包含更多的市场分析和风险管理组件。此外,编写交易指标或策略时,务必进行充分的回测和风险评估,以确保其在实际交易中的有效性。
OpenHarmony 3GPP协议开发深度剖析——一文读懂RIL
市场上针对终端操作系统3GPP协议开发的相关资料较为稀缺,即便在Android领域,相关学习文档也较为有限,学习源码的技巧更不用说专门的协议开发书籍了。这可能与市场需求有关,目前市场上从事前后端软件开发的人员最多,包括我自己。
鉴于我在某手机协议开发团队工作过一段时间,对协议的AP侧和CP侧开发都有所涉猎,因此我尝试基于OpenAtom OpenHarmony(以下简称“OpenHarmony”)源码编写一些内容,旨在帮助大家了解协议开发领域,尽可能将3gpp协议内容与OpenHarmony电话子系统模块相结合进行讲解。据我所知,目前终端协议开发人才非常紧缺。首先声明,我不是协议专家,且已离开该领域五六年,如有错误,欢迎指正。吉祥兔棋牌源码
谈到终端协议开发,我首先想到的就是RIL。
CP:Communication Processor(通信处理器),通常理解为modem侧,也可以理解为底层协议,这部分由各个modem芯片厂商完成(如海思、高通)。
AP:Application Processor(应用处理器),通常指手机终端,通常理解为上层协议,主要由操作系统Telephony服务进行处理。
RIL:Radio Interface Layer(无线电接口层),通常理解为硬件抽象层,即AP侧将通信请求传给CP侧的中间层。
AT指令:AT指令是应用于终端设备与PC应用之间连接与通信的指令。
常规的Modem开发与调试可以使用AT指令进行操作,而各家的Modem芯片的AT指令都会有各自的差异。因此,手机终端厂商为了能在各种不同型号的产品中集成不同modem芯片,需要进行解耦设计来屏蔽各家AT指令的差异。
于是,OpenHarmony采用RIL对Modem进行HAL(硬件抽象),作为系统与Modem之间的通信桥梁,为AP侧提供控制Modem的接口,各Modem厂商则负责提供对应于AT命令的Vender RIL(这些一般为封装好的so库),从而实现操作系统与Modem间的解耦。
框架层:Telephony Service,电话子系统核心服务模块,主要功能是初始化RIL管理、SIM卡和搜网模块。对应OpenHarmony的源码仓库OpenHarmony/telephony_core_service。这个模块也是非常重要的一个模块,后期单独再做详细解读。
硬件抽象层:即我们要讲的RIL,对应OpenHarmony的源码仓库OpenHarmony/telephony_ril_adapter。RIL Adapter模块主要包括厂商库加载,业务接口实现以及事件调度管理。主要用于屏蔽不同modem厂商硬件差异,为上层提供统一的接口,通过注册HDF服务与上层接口通讯。
芯片层:Modem芯片相关代码,即CP侧,这些代码各个Modem厂商是不开放的,不出现在OpenHarmony中。
硬件抽象层又被划分为hril_hdf层、hril层和venderlib层。
hril_hdf层:HDF服务,基于OpenHarmony HDF框架,提供hril层与Telephony Service层进行通讯。
hril层:hril层的各个业务模块接口实现,比如通话、短彩信、数据业务等。
vendorlib层:各Modem厂商提供的对应于AT命令库,各个厂商可以出于代码闭源政策,在这里以so库形式提供。目前源码仓中已经提供了一套提供代码的AT命令操作,至于这个是针对哪个型号modem芯片的,我后续了解清楚再补充。
下面是ril_adapter仓的源码结构:
本文解读RIL层很小一部分代码,RIL是如何通过HDF与Telephony连接上的,以后更加完整的逻辑梳理会配上时序图讲解,会更加清晰。首先,我们要对OpenHarmony的HDF(Hardware Driver Foundation)驱动框架做一定了解,最好是动手写一个Demo案例,具体的可以单独去官网查阅HDF资料。
首先,找到hril_hdf.c文件的代码,它承担的是驱动业务部分,源码中是不带中文注释的,为了梳理清楚流程,我给源码关键部分加上了中文注释。
上述代码中配置了对应该驱动的moduleName为"hril_hdf",因此我们需要去找到对应驱动的配置文件,以HiDV开发板为例,它的驱动配置在vendor_hisilicon/HiDV/hdf_config/uhdf/device_info.hcs代码中可以找到,如下:
这里可以发现该驱动对应的服务名称为cellular_radio1,那么telephony_core_service通过HDF与RIL进行通信肯定会调用到该服务名称,因此无查找telephony_core_service的相关代码,可以很快定位到telephony_core_service/services/tel_ril/src/tel_ril_manager.cpp该代码,该代码中有一个关键类TelRilManager,它用来负责管理tel_ril。
看tel_ril_manager.cpp中的一个关键函数ConnectRilAdapterService,它就是用来通过HDF框架获取RIL_ADAPTER的服务,之前定义过RIL_ADAPTER_SERVICE_NAME常量为"cellular_radio1",它就是在vendor_hisilicon/XXXX/hdf_config/uhdf/device_info.hcs中配置的hril_hdf驱动对应的服务名称。