本篇日志记录了我在爱立信实习中参与的一个项目:基站监测与调试工具的开发。
WoD工具分为两部分,一部分是在DSP侧,实现在基站freescale的板子上,提供基站端的流量信息/数据信息/signal状态/内存信息等;另一部分是PC侧,负责监视。控制基站与显示,记录数据结果。两部分之间通过socket通信,在自己设计的数据包传输协议基础上交换信息。(在外场测试中,没有PC侧的应用,DSP侧应将各种信息或数据记录在文件中存储,需要时用脚本解析)。
相关代码主要为om_message.c
在DSP0的app.c中,appstart()调用om_init(),这个函数创建了几个低优先级的进程(为了保证基站端物理层处理的实时性,WoD相关的进程优先级都会设为最低的):
void om_init(void)
{
om_pool_id = s_create_pool(0, (OSADDRESS)&om_pool_buf[krn_get_core_id()][0], OM_POOL_BUF_SIZE, omPoolSizes);
pid_wod_send = create_process(OS_PRI_PROC, "wodSendProc", wodSendProc,
(OSADDRESS)4096, WOD_SEND_PRIORITY, 0, 0, 0, 0, 0);
start(pid_wod_send);
pid_wod_recv = create_process(OS_PRI_PROC, "wodRecvProc", wodRecvProc,
(OSADDRESS)4096, WOD_RECV_PRIORITY, 0, 0, 0, 0, 0);
start(pid_wod_recv);
pid_log_to_file = create_process(OS_PRI_PROC,"logToFileProc",logToFileProc,
(OSADDRESS)4096, WOD_LOG_TO_FILE_PRIORITY, 0,0,0,0,0);
start(pid_log_to_file);
om_debug_log_init();
}
下面以通信最基本的send和recv操作来记录进程键通信的用法:
简洁起见,以记录小数据和天线数据(大量)到文件这两个功能为例,涉及到的操作有文件的建立,关闭和写入。
send进程等待信号并判断sig的action,根据action的类别来封装message各个字段内容。除了包头(dspID,coreID,fileID,packetID等)外,payload通过
memcpy(p + 9, sig->send_req.sendbuf, sig->send_req.sendlength);
来具体赋值,及sig中传入了sendbuf中有效信息,如文件名,天线数据等。PS:天线数据因为过大,是从bufpointer开始copy过来的。之后通过socket发送
err = ipcom_sendto(sockcli, sendbuf, sendsize, 0, (struct Ip_sockaddr *)&serveraddr, sizeof(serveraddr));
free_buf(&sig);
OS_PROCESS(wodSendProc)
{
S32 err;
union SIGNAL *sig;
static SIGSELECT sigsel[] = {1,SIG_SEND_REQ};
U32 * p;
struct msgHead* msg_p;
U8 sendbuf[MAX_WOD_SEND_LENGTH];
#pragma align sendbuf 8
U32 sendsize;
Ip_fd_set readset;
Ip_fd sockcli;
sockcli = ipcom_socket(IP_AF_INET, IP_SOCK_DGRAM, 0);
IP_FD_ZERO(&readset);
IP_FD_SET(sockcli, &readset);
for(;;)
{
sig = receive