运行环境:pikapython+rtthread,keil5.38,测试目的:串口1接收数据后送去做CRC验证。
运行pikaRTFunctionModule.DEVICE.CRCCheck模块后,总是报硬件错误,跟踪调试发现,经过pika预编译后,args的值总会被莫名改变,请大神赐教。
py代码如下:
num_list = PikaStdData.List()
list1 = PikaStdData.List()
while True:
time_out = pikaRTFunctionModule.INTTIME.timer_check_flag() # 定时2S
if time_out == 1:
time_out = 0
com1_comd = pikaRTFunctionModule.DEVICE.SerialOut('com1',cmd1) #发送串口查询命令
del com1_comd
list1 = pikaRTFunctionModule.DEVICE.SerialIn('com1',13,num_list) # 串口接收,接收数据存到list1列表里边
if len(list1) >0 :
num_list = []
crc_data = pikaRTFunctionModule.DEVICE.CRCCheck(list1) #将list1数据送去做CRC校验
print(crc_data)
if crc_data == list1[-1]+(list1[-2]*256):
print('ok')
thread.mdelay(100)
C程序代码如下:
#ifndef PIKA_MODULE_PIKARTFUNCTIONMODULE_DISABLE
void pikaRTFunctionModule_DEVICE_CRCCheckMethod(PikaObj *self, Args *args){
PikaObj* da = args_getPtr(args, "da"); // 刚进入时,args=0x20004248,args->firstNode =0x20004390
int res = pikaRTFunctionModule_DEVICE_CRCCheck(self, da); // 该条执行结束时,args=0x3aa58503,args->firstNode =0xaaaaaaaa
method_returnInt(args, res); // 出现错误报警 hard fault on thread: main
}
method_typedef(
pikaRTFunctionModule_DEVICE_CRCCheck,
"CRCCheck", "da"
);
当全速运行metho_returnInt(args,res);后,出现报错:
psr: 0x21000000
pc: 0x000201ec
lr: 0x00014d2b
r12: 0x00000003
r03: 0x00000074
r02: 0x0b87d24b
r01: 0x20004494
r00: 0x3aa58503
hard fault on thread: main
根据lr查找程序代码,发现发生错误前入口函数是
PIKA_RES args_pushArg(Args* self, Arg* arg) {
Arg* new_arg = NULL;
if (!arg_isSerialized(arg)) {
new_arg = arg_copy(arg);
arg_deinit(arg);
} else {
new_arg = arg;
}
link_addNode(self, new_arg);
return PIKA_RES_OK; // 发生报错前地址
}
请各位高手指教,该问题是如何导致的,如何排查,多谢。
@耳东陈
append之后加一个arg_deinit(),因为list的append操作会拷贝一份arg可以参考一下这个例子:
请问,这个arg_deinit()函数都用在什么情况下?只是list下面的append后面需要用?还是说只要用到Arg* arg_i = ***这样定义的就需要arg_deinit?
问题已解决,需要在for()循环内部对arg进行删除操作arg_deinit(str_arg1),之前也有删除操作,只不过是放在了for循环的外部,结果就导致了内存的不断占用。不是很明白为啥需要在for里边进行这样做,如果循环100次,那就要创建删除100次?这样岂不是会增大代码空间?
case '0':
{
uart0_read(tempda,maxnum,&rece_num);
for(char i=0;i<rece_num;i++)
{
Arg* str_arg1 = arg_newInt(tempda[i]);
PikaStdData_List_append(list, str_arg1);
arg_deinit(str_arg1); /* 销毁 arg */
}
}break;
测试发现执行
for(char i=0;i<rece_num;i++)
{
str_arg1 = arg_newInt(tempda[i]);
PikaStdData_List_append(list, str_arg1);
}
这两条命令后,heap剩余空间不断减小,如下是heap查询结果,每接收一组数据,heap剩余空间就不断减小,直到最后空间不足报错。各位大咖如何解决?
16:00:15<-[S18]: total : 17744
16:00:15<-[S18]: used : 16472
16:00:15<-[S18]: maximum : 17104
16:00:15<-[S17]: available: 1272
16:00:16<-[S06]: msh />
16:00:16->[S05]: free
16:00:16<-[S06]: free
16:00:16<-[S18]: total : 17744
16:00:16<-[S18]: used : 16632
16:00:16<-[S18]: maximum : 17392
16:00:16<-[S17]: available: 1112
16:00:17<-[S06]: msh />
16:00:18->[S05]: free
16:00:18<-[S06]: free
16:00:18<-[S18]: total : 17744
16:00:18<-[S18]: used : 16920
16:00:18<-[S18]: maximum : 17680
16:00:18<-[S16]: available: 824
16:00:18<-[S06]: msh />
16:00:18<-[S47]: Error: No heap space! Please reset the device.
在rt_thread系统下,通过pikapython控制2个串口传递数据,把从com4接收到的数据通过com1发送出去。PC端串口助手定时5s自动发送5个数据,运行发现在接收到14组数据后,系统报错Error: No heap space! Please reset the device.之后不再接收数据。
仿真发现程序停止在
void* pikaMalloc(uint32_t size) {
···
if (NULL == mem) {
pika_platform_printf("Error: No heap space! Please reset the device.\r\n");
while (1) {
}
}
}
中的while(1){}里边。另两个串口开辟接收空间大小均为100,
pikapython中的函数如下:
while True:
list = pikaRTFunctionModule.DEVICE.SerialIn('com4',list,13)
com1_comd = pikaRTFunctionModule.DEVICE.SerialOut('com1',list)
thread.mdelay(5000)
PikaObj* pikaRTFunctionModule_DEVICE_SerialIn(PikaObj *self, char* com, PikaObj* tempreceive,int maxnum)
{
PikaObj* list = newNormalObj(New_PikaStdData_List);
PikaStdData_List___init__(list);
Arg* str_arg1 = 0;
char tempda[30];
rt_uint8_t rece_num = 0;
char *p;
char ch;
p = com;
p +=3;
ch = *p;
switch(ch)
{
case '0':
{
uart1_rs485_read(tempda,maxnum,&rece_num);
for(char i=0;i<rece_num;i++)
{
str_arg1 = arg_newInt(tempda[i]);
PikaStdData_List_append(list, str_arg1);
}
}break;
······
default:break;
}
memset(tempda,0x00,sizeof(tempda));
arg_deinit(str_arg1); /* 销毁 arg */
return list;
}
void pikaRTFunctionModule_DEVICE_SerialOut(PikaObj *self, char* com, PikaObj* command)
{
char *p;
char ch;
p = com;
p +=3;
ch = *p;
rt_device_t serial;
rt_size_t result;
PikaList* list = obj_getPtr(command, "list");
switch(ch)
{
case '0':
{
serial = rt_device_find (RS232_UART_NAME2);
for(int i =0; i< pikaList_getSize(list); i++)
{
Arg* arg_i = pikaList_getArg(list, i);
result = rt_device_write(serial,0,arg_getStr(arg_i),1);
if (result != 1)
{
rt_kprintf("RS232_UART_NAME2 write failed\r\n");
return ;
}
}
}break;
······
default:break;
}
}
请教各位高手,pikapython这样操作是否会有空间占用不放开的问题?尝试过更改串口接收空间大小,从50增大到500,仍然存在接收十几组数据后报错的问题,请高手支招。
rtt系统下,通过串口打印输出脚本发送的数据
1、想在pyi文件下传递一个数组到单片机,该数组类型不定,可能是字符型,整型,浮点型,之前想通过定义可变参数模块def vals(a:int, *val):...,但是测试发现如果传递的是一个字符串‘hello’,按照如下执行后:
for(int i =0; i< pikaTuple_getSize(val); i++)
{
Arg* arg_i = pikaTuple_getArg(val, i);
rt_device_write(serial,0,arg_getStr(arg_i),1);
}
串口输出的只是一个字符‘h’,不明白为什么。
2、如果我不是可变参数传递而是用list传递,该怎么设置
3、如果想打印list内容,如何确定其长度?是否可用Tuple类下的len方法
非常感谢高手支招!
因为你当前的libc的vsnprintf不是完整实现,不支持%ld的打印
解决方法是在requestments.txt里面加一个模块,pika_libc,这里面提供了一套完整的vsnprintf,添加编译就可用了,会覆盖原有的vsnprintf
非常感谢,按照提示增加了pika_libc模块,编译过程中提示platform_vsnprintf重定义,后来去掉了pika_config.c中的
//int __platform_vsnprintf(char* buff, size_t size, const char* fmt, va_list args){
// return rt_vsnprintf(buff, size, fmt, args);
//}
编译通过,经验证,数据打印正常。
RT_thread系统下,应用v5.38版本keil5进行编译,pikascript相关软件版本为:
pikascript-core==v1.12.2
PikaStdLib==v1.12.2
pikaRTThread==v1.3.2
在运行例程时发现无法正常打印数字,程序代码如下:
print('mem use max:')
mem.max()
print('mem use now:')
mem.now()
list = PikaStdData.List()
list.append(23)
list.append(45)
print(list.get(0))
print(list.get(1))
print(100)
输出结果为:
mem use max:
2.14 kB
mem use now:
1.15 kB
%ld
%ld
%ld
求指教为什么数字不能正确的输出。