rt-thread-packages / ppp_device Goto Github PK
View Code? Open in Web Editor NEWlwIP PPP porting for GSM modem (like sim800)
License: Apache License 2.0
lwIP PPP porting for GSM modem (like sim800)
License: Apache License 2.0
文档中说明建议不要打开RT_DEVICE_FLAG_DMA_TX
,现实情况是一定不能打开该标志。原因是RTT串口发送时,是直接将数据地址传送给DMA(在打开DMA时并且开启RT_DEVICE_FLAG_DMA_TX),这样在DMA发送数据时,一定不能修改传给serial层的数据,如果是动态分配的内存更不能释放该内存,否则会导致发送数据出错或者崩溃。
但是,某些情况下,需要开启DMA以节省CPU资源,这时需要ppp_device能够保证数据不出错而且还能异步(DMA)发送,这就需要简单实现一下异步发送的功能。我简单写了一个串口异步发送数据的示例,你看是否可行或者是否有必要:
#define MIN(a,b) (((a) > (b)) ? (b) : (a))
#define SEND_TIMEOUT 1000
uint8_t ppp_tx_buf[1500] = {0};
/*发送完成信号*/
rt_sem_t tx_sem;
rt_inline rt_err_t __send_complete_callback(rt_device_t dev, void *buffer)
{
rt_sem_release(tx_sem);
return RT_EOK;
}
int ppp_serial_write(rt_device_t dev, const uint8_t *data, int data_len)
{
int ret = RT_EOK;
if (!dev)
{
return -RT_EINVAL;
}
if (!data || data_len == 0)
{
log_w("Invalid data!");
return 0;
}
ret = rt_sem_take(tx_sem, SEND_TIMEOUT);
if (RT_EOK != ret)
{
log_e("Write %s failed,err: %d", uart->name, ret);
return -RT_EBUSY;
}
ret = MIN(data_len,sizeof(ppp_tx_buf));
memcpy(ppp_tx_buf, data, ret);
ret = rt_device_write(dev, 0,tx_buf, ret);
if (ret <= 0)
{
log_e("Write %s failed,err: %d", uart->name, ret);
}
else if (ret < data_len)
{
//待优化,连续发送大量数据可能导致栈溢出
ret = ppp_serial_write(fd, data + ret, data_len - ret);
}
return ret;
}
[W/ppp.dev] receive ppp frame is lagger than 1550
[W/ppp.dev] receive ppp frame is lagger than 1550
[W/ppp.dev] receive ppp frame is lagger than 1550
[W/ppp.dev] receive ppp frame is lagger than 1550
[W/ppp.dev] receive ppp frame is lagger than 1550
[W/ppp.dev] receive ppp frame is lagger than 1550
[W/ppp.dev] receive ppp frame is lagger than 1550
[W/ppp.dev] receive ppp frame is lagger than 1550
[W/ppp.dev] receive ppp frame is lagger than 1550
[W/ppp.dev] receive ppp frame is lagger than 1550
[W/ppp.dev] receive ppp frame is lagger than 1550
[W/ppp.dev] receive ppp frame is lagger than 1550
psr: 0x01070000
r00: 0x2000eb98
r01: 0x000000b4
r02: 0x20040001
r03: 0x20040000
r04: 0xdeadbeef
r05: 0xdeadbeef
r06: 0xdeadbeef
r07: 0x20011828
r08: 0xdeadbeef
r09: 0xdeadbeef
r10: 0xdeadbeef
r11: 0xdeadbeef
r12: 0xffffffff
lr: 0x0802b3e7
pc: 0x0802b388
hard fault on thread: ppp_recv
thread pri status sp stack size max used left tick error
-------- --- ------- ---------- ---------- ------ ---------- ---
Sal_whil 19 suspend 0x0000009c 0x00001000 29% 0x00000004 OK
ppp_recv 9 running 0x000000ac 0x00000600 48% 0x00000005 **OK**
tshell 20 suspend 0x000000cc 0x00001000 10% 0x00000007 OK
cmuxrec1 8 suspend 0x000000d8 0x00000200 60% 0x0000000a OK
sys work 23 suspend 0x00000084 0x00000800 54% 0x00000004 OK
tcpip 10 ready 0x000000d0 0x00000800 83% 0x00000004 OK
etx 12 suspend 0x000000b0 0x00000400 17% 0x00000010 OK
erx 12 suspend 0x000000b8 0x00000400 17% 0x00000010 OK
tidle0 31 ready 0x00000060 0x00000100 56% 0x00000001 OK
timer 4 suspend 0x00000080 0x00000200 32% 0x00000009 OK
main 10 suspend 0x000000b8 0x00000800 26% 0x0000000c OK
bus fault:
SCB_CFSR_BFSR:0x82 PRECISERR SCB->BFAR:20040000`
i am using cmux and ppp-device 1.1.0. all setting and stack sizes are default just tcptack is increased to 2048. i am sending http request(using thread) every 2 second to a webserver which respond a very simple html page to GET request. after several http request by SAL functions i get above error in terminal.
i tested cmux(using thread) alone and ppp(using thread) alone all are ok but when i use them together this happens.
(edited) i changed ppp_recv priority to 3 (under everything) and it seems it's ok but it is not good as i know for RTOS.
(edited_2) if i use one channel of cmux(ppp) with lowering the priority of ppp_recv, it's working properly but when i use second virtual channel of cmux for another job+ppp it doesen't work properly and i get these non-sense data:
[D/Cmux_at] 0 ,Recieve Úa»hF7½F½È
[D/Cmux_at] 0 ,Recieve °
[D/Cmux_at] 0 ,Recieve
[D/Cmux_at] 0 ,Recieve ðúúF+Ð@òªRGIHHð
[D/Cmux_at] 0 ,Recieve Yý;h
[D/Cmux_at] 0 ,Recieve §ø8a{hÚi;hC{hÚa?K
[D/Cmux_at] 0 ,Recieve
[D/Cmux_at] 0 ,Recieve ÿ÷HùF
[D/Cmux_at] 0 ,Recieve ;û`Oðÿ3»aûhø@0ð
[D/Cmux_at] 0 ,Recieve
[D/Cmux_at] 0 ,Recieve Ñ
[D/Cmux_at] 0 ,Recieve ÐûhÚk{hÛi@
[D/Cmux_at] 0 ,Recieve {hÛi@ûhÚc
[D/Cmux_at] 0 ,Recieve [øoð (àûiûa»i
[D/Cmux_at] 0 ,Recieve ûhø@0ð
[D/Cmux_at] 0 ,Recieve ÛkÛC@{hÚaøhðù#{a
[D/Cmux_at] 0 ,Recieve {hñûiB¨Ñ8iþ÷5ø{i
[D/Cmux_at] 0 ,Recieve +Ñðþû
[D/Cmux_at] 0 ,Recieve 9ì
[D/Cmux_at] 0 ,Recieve
[D/Cmux_at] 0 ,Recieve ÅbIHðµüûhFðIúF
[D/Cmux_at] 0 ,Recieve +Ð@ò)b{I}Hð¨üý÷þÿ
[D/Cmux_at] 0 ,Recieve øaðýF
[D/Cmux_at] 0 ,Recieve @ò,brIvHðüý÷ìÿ¸að
[D/Cmux_at] 0 ,Recieve ÉþF
[D/Cmux_at] 0 ,Recieve iImHðüý÷Úÿxa
[D/Cmux_at] 0 ,Recieve
[D/Cmux_at] 0 ,Recieve ðrüxiý÷Ëÿ¸iý÷Èÿøiý÷
[D/Cmux_at] 0 ,Recieve Åÿ»h
[D/Cmux_at] 0 ,Recieve ðþ8a;i
目前只支持4种网卡的选择,而且必须选择一种。若用户使用自己的网卡如N720等,需要自己修改Kconfig文件。一旦更新了Kconfig文件,就会覆盖之前的设置,需要重新设置。建议可参考AT DEVICE的选项,即可使用列表中的网卡,也可自己在其他地方添加网卡。
在查看 lwIP 代码时,ppp 数据包的解析,在 pppos.c 文件下 pppos_input 函数里已有实现
/** Pass received raw characters to PPPoS to be decoded.
*
* @param ppp PPP descriptor index, returned by pppos_create()
* @param s received data
* @param l length of received data
*/
void
pppos_input(ppp_pcb *ppp, u8_t *s, int l)
{
pppos_pcb *pppos = (pppos_pcb *)ppp->link_ctx_cb;
struct pbuf *next_pbuf;
u8_t cur_char;
u8_t escaped;
PPPOS_DECL_PROTECT(lev);
#if !PPP_INPROC_IRQ_SAFE
LWIP_ASSERT_CORE_LOCKED();
#endif
PPPDEBUG(LOG_DEBUG, ("pppos_input[%d]: got %d bytes\n", ppp->netif->num, l));
while (l-- > 0) {
cur_char = *s++;
···
···
}
if (device->state == PPP_STATE_PREPARE)
{
......
/* throw away the dirty data in the uart buffer */
rt_device_read(device->uart, 0, buffer, PPP_RECV_READ_MAX);
.....
}
在ppp_recv_entry中,模块拨号成功后,加了清理脏数据处理。如果真有脏的数据,这样最多也只能清理掉PPP_RECV_READ_MAX(32字节)长度的数据吧,如果RT_SERIAL_RB_BUFSZ比PPP_RECV_READ_MAX大,是清理不干净的
使用PPP拨号上网后,其他的通讯都没有问题
但是使用webclient Demo 中的 webclient_file.c webclient_get_file下载文件,ppp_device会提示:
D/ppp.dev ppp_recv: found continuous 0x7e
一直在这里死循环,无法下载文件
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.