移植到stm32f1,实现手动线赋码控制器功能

This commit is contained in:
ranchuan
2023-09-09 17:27:06 +08:00
parent 8d779a68f3
commit 7baa63de05
382 changed files with 36618 additions and 148064 deletions

View File

@@ -6,7 +6,7 @@
#include "debug.h"
#include "board.h"
#define CMD_RETURN_BUFF_SIZE 4096
#define CMD_RETURN_BUFF_SIZE 1024

View File

@@ -15,23 +15,15 @@
/**
*
* 批检仪
* BUS1(UART5)->slave 1,2,3,4
* BUS2(UART2)->slave 5,6,7,8
* BUS3(UART3)->slave 9,10,11,12
* BUS4(UART6)->slave 13,14,15,16
* BUS5(UART1)->slave 17,18,19,20
*
* 注码仪
* UART5->1,2,3,4
* UART2->5,6,7,8
* UAER3->9,10
* UART2->1
* UART3->2
*
**/
#define PORT_MUN 5
#define PORT_MUN 2
typedef struct{
@@ -54,11 +46,8 @@ int port_init(void)
{
self_def *s=&g_self;
if(s->init==0){
s->protm[0]=protm_creat(dev_get("uart5"),(int []){1,2,3,4},4);
s->protm[1]=protm_creat(dev_get("uart2"),(int []){5,6,7,8},4);
s->protm[2]=protm_creat(dev_get("uart3"),(int []){9,10,11,12},4);
s->protm[3]=protm_creat(dev_get("uart6"),(int []){13,14,15,16},4);
s->protm[4]=protm_creat(dev_get("uart1"),(int []){17,18,19,20},4);
s->protm[0]=protm_creat(dev_get("uart2"),(int []){1,},1);
s->protm[1]=protm_creat(dev_get("uart3"),(int []){2,},1);
s->init=1;
}
return 0;
@@ -205,8 +194,8 @@ int port_start(port_mcu *p,handle_def *h)
#define MCU_APP_ADDR_BASE 0x8002400
#define MCU_TASKID_ADDR_BASE 0x800f400
#define MCU_APP_ADDR_BASE 0x8004000
#define MCU_TASKID_ADDR_BASE 0x803f000

View File

@@ -158,6 +158,123 @@ commend_export(code,code,"write uidcode to slave,uid_len=8,pw_len=4")
// 检测赋码
typedef struct{
handle_def h;
uint8_t uid_size;
uint8_t pw_size;
uint8_t data[24];
}code2_def;
static void code2_start(handle_def *h)
{
code2_def *c=(code2_def *)h;
port_set_busy(h->p,1);
array_def *a=arr_creat();
arr_append(a,c->uid_size);
arr_append(a,c->pw_size);
arr_append(a,1);// 此项为1检测中赋码
arr_appends(a,c->data,c->uid_size+c->pw_size);
list_def *l=list_creat_int();
int cmds[]={0x0b};
list_appends(l,cmds,1);
l=list_temp(l);
emit port_send_signal(h->p,port_get_addr(h->p),0x0b,l,arr_temp(a),60,5);
}
static void code2_dolater(handle_def *h,uint8_t src,uint8_t cmd,array_def *data,char *err_str)
{
if(port_get_busy(h->p)==0) return;
if(cmd==0x02)
{
if(arr_get(data,0)==0)
{
port_set_busy(h->p,0);
port_timer_stop(h->p);
DBG_LOG("slave:%d, recv check data",src);
arr_remove(data,0,1);
DBG_LOG("slave:%d, recv:%s",src,str_temp(arr_string(data)));
//emit port_end_signal(h->p,h->p,tappend(scheme_check_returns(c->sch,data),0),0,"ok");
// 直接返回原始数据
emit port_end_signal(h->p,h->p,data,0,"ok");
// }else if(arr_get(data,0)==2){
}else{
// 检测中则继续发送
list_def *l=list_creat_int();
int arr[]={0x02};
list_appends(l,arr,1);
emit port_send_signal(h->p,port_get_addr(h->p),0x02,list_temp(l),arr_temp(arr_creat()),60,130);
}
// else{
// port_set_busy(h->p,0);
// port_timer_stop(h->p);
// DBG_WARN("slave:%d,get check_result err,%s",src,str_temp(arr_string(data)));
// emit port_end_signal(h->p,h->p,0,arr_get(data,0),"get check_result err");
// }
}
else if(cmd==0x0b)
{
if(arr_get(data,0)==0)
{
int timeout =h->interval;
DBG_LOG("slave:%d, check first ack,timeout=%d",src,timeout);
list_def *l=list_creat_int();
int arr[]={0x02};
list_appends(l,arr,1);
emit port_send_signal(h->p,port_get_addr(h->p),0x02,list_temp(l),arr_temp(arr_creat()),60,timeout/60);
}
else{
port_set_busy(h->p,0);
port_timer_stop(h->p);
DBG_WARN("slave:%d,get start_check err,%s",src,str_temp(arr_string(data)));
emit port_end_signal(h->p,h->p,0,-1,"get start_check err");
}
}
}
static void code2_timeout(handle_def *h)
{
// 从机没有指定数目时从这里返回
port_timer_stop(h->p);
port_set_busy(h->p,0);
DBG_WARN("slave:%d,%s timeout.",port_get_addr(h->p), h->name);
emit port_end_signal(h->p,h->p,0,-1,"timeout");
}
// uid_size+pw_size不应大于24
handle_def *code2_creat(int uid_size,int pw_size,uint8_t *data)
{
code2_def *c=calloc(1,sizeof(code2_def));
param_check(c);
if(uid_size+pw_size>24)
{
free(c);
return 0;
}
c->uid_size=uid_size;
c->pw_size=pw_size;
memcpy(c->data,data,c->uid_size+c->pw_size);
handle_def *h=(handle_def *)c;
h->static_=0;// 动态内存这项设置为0
h->start=code2_start;
h->dolater=code2_dolater;
h->del=(void (*)(handle_def *))free;
h->timeout=code2_timeout;
h->interval=10000;
h->name="code2";
return h;
}

View File

@@ -10,6 +10,7 @@
handle_def *code_creat(int uid_size,int pw_size,uint8_t *data);
handle_def *code2_creat(int uid_size,int pw_size,uint8_t *data);

View File

@@ -64,7 +64,7 @@ typedef struct{
}send_data_def;
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>
// 定义事件
#define EVENT_RECV 0x1
#define EVENT_SEND 0x2
#define EVENT_TIMEOUT 0x4
@@ -82,7 +82,7 @@ struct _protm_def{
list_def *slaves;//protm_slave
list_def *slaves_addr;//int
list_def *send_data;//send_data_def
int in_send;//<EFBFBD>ڷ<EFBFBD><EFBFBD><EFBFBD>״̬ʱΪ1
int in_send;//在发送状态时为1
uint8_t recv_cmd;
uint8_t recv_src;
@@ -115,7 +115,7 @@ static void recv_irq(void *t,uint8_t d)
default:
break;
}
// <EFBFBD><EFBFBD>ʱһ֡<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 此时一帧数据已完成
if(p->num_to_recv>0&&p->num_to_recv==arr_length(p->buff))
{
rt_event_send(p->event,EVENT_RECV);
@@ -125,8 +125,8 @@ static void recv_irq(void *t,uint8_t d)
/*
* <EFBFBD><EFBFBD><EFBFBD>ӻ<EFBFBD>ͨ<EFBFBD>ŵĴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǵ<EFBFBD><EFBFBD>еģ<EFBFBD>һ<EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֮<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܿ<EFBFBD>ʼ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD>
* Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD>ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Dz<EFBFBD><EFBFBD>еģ<EFBFBD>Ӧ<EFBFBD>ò<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* 与从机通信的串口是串行的,一个通信事务完成之后才能开始下一个通信
* 协议层接收的通信事务是并行的,应用层来的通信任务会被放入队列
*/
static void protm_send_next(void *t);
@@ -173,13 +173,13 @@ static void protm_run(void *t)
}
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>
// 发送下一个
static void protm_send_next(void *t)
{
protm_def *p=t;
rt_timer_stop(p->timer);
list_remove(p->send_data,0);
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 如果发送列表中有数据,此时发送
if (list_length(p->send_data)>0)
{
// DBG_LOG("protmcu:EVENT_SEND.");
@@ -199,7 +199,7 @@ static void protm_send_timeout_cb(void *t)
rt_event_send(p->event,EVENT_TIMEOUT);
}
// <EFBFBD><EFBFBD><EFBFBD>ճ<EFBFBD>ʱ
// 接收超时
static void protm_send_timeout(void *t)
{
protm_def *p=t;
@@ -213,7 +213,7 @@ static void protm_send_timeout(void *t)
DBG_WARN("slave:%d retry timeout,remove the send data.",s->addr);
list_remove(p->send_data,0);
}
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 如果发送列表中有数据,此时发送
if (list_length(p->send_data)>0)
{
// DBG_LOG("protmcu:EVENT_SEND.");
@@ -230,7 +230,7 @@ static void protm_send_timeout(void *t)
// <EFBFBD><EFBFBD><EFBFBD>Ͷ<EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
// 发送队列删除条目
static int _list_send_data_del(void *t)
{
send_data_def *a=t;
@@ -253,7 +253,7 @@ protm_def *protm_creat(uart_def *uart,int *addrs,int num)
p->slaves=list_creat(sizeof(protm_slave),protm_slave_sub,protm_slave_del,0);
p->slaves_addr=list_creat_int();
p->send_data=list_creat(sizeof(send_data_def),0,_list_send_data_del,0);
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٵȴ<EFBFBD><EFBFBD>ӻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 创建超时定时器,超过指定时间则不再等待从机返回
p->timer=rt_timer_create("port_timer",protm_send_timeout_cb,p,
rt_tick_from_millisecond(55),
RT_TIMER_FLAG_ONE_SHOT|RT_TIMER_FLAG_SOFT_TIMER);
@@ -269,7 +269,7 @@ protm_def *protm_creat(uart_def *uart,int *addrs,int num)
}
// <EFBFBD>õ<EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD>Ĵӻ<EFBFBD>,<2C>Ҳ<EFBFBD><D2B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 得到指定地址的从机,找不到则添加
protm_slave *protm_get_slave(protm_def *p,uint8_t addr)
{
protm_slave *r=0;
@@ -290,7 +290,7 @@ protm_slave *protm_get_slave(protm_def *p,uint8_t addr)
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>дӻ<EFBFBD><EFBFBD><EFBFBD>ˮ<EFBFBD><EFBFBD>
// 设置所有从机流水号
void protm_set_no_all(protm_def *p,uint16_t no,list_def *cmd/*int*/)
{
for(int i=0;i<list_length(p->slaves);i++)
@@ -303,7 +303,7 @@ void protm_set_no_all(protm_def *p,uint16_t no,list_def *cmd/*int*/)
}
// <EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӻ<EFBFBD><EFBFBD><EFBFBD>ˮ<EFBFBD><EFBFBD>
// 设置单个从机流水号
void protm_set_no(protm_def *p,uint8_t addr,uint16_t no,list_def *cmd/*int*/)
{
protm_slave *s=protm_get_slave(p,addr);
@@ -316,7 +316,7 @@ void protm_set_no(protm_def *p,uint8_t addr,uint16_t no,list_def *cmd/*int*/)
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 解码
array_def *protm_decode(protm_def *p,array_def *data)
{
array_def *r=arr_creat();
@@ -334,7 +334,7 @@ array_def *protm_decode(protm_def *p,array_def *data)
uint8_t crc=crc_crc8(arr_data(data),arr_length(data)-1);
if(len!=arr_length(data))
{
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݶ<EFBFBD>ʧ
// 如果长度不相等则产生了数据丢失
DBG_WARN("recv data have lossed.");
str_set(p->str_err,"recv data have lossed.");
return r;
@@ -343,7 +343,7 @@ array_def *protm_decode(protm_def *p,array_def *data)
uint16_t h_no=protm_get_slave(p,src)->no;
if(no!=h_no)
{
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD>أ<EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>ˮ<EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD>ͬ
// 发送一条指令等待其返回,此时流水号应相同
//DBG_WARN("slave_addr=%d cmd_no error:h_no=%d,no=%d.",src,h_no,no);
//str_set(p->str_err,"cmd no err.");
//return r;
@@ -356,7 +356,7 @@ array_def *protm_decode(protm_def *p,array_def *data)
p->recv_cmd=arr_get(data,6);
list_def *cmds=protm_get_slave(p,src)->cmds;
if(list_contains(cmds,(int []){p->recv_cmd})==0){
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><EFBFBD><EFBFBD>
// 命令号校验不对
DBG_WARN("cmd check err.cmds=%s,recv_cmd=%d",tappend(list_string(cmds),0),p->recv_cmd);
str_set(p->str_err,"cmd check err.");
}
@@ -365,7 +365,7 @@ array_def *protm_decode(protm_def *p,array_def *data)
}
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 编码
array_def *protm_encode(protm_def *p,uint8_t dst,uint8_t cmd,list_def *comp_cmd/*int*/,array_def *data)
{
array_def *t=arr_creat();
@@ -378,9 +378,9 @@ array_def *protm_encode(protm_def *p,uint8_t dst,uint8_t cmd,list_def *comp_cmd/
arr_append(t,'e');
arr_append(t,len&0xff);
arr_append(t,len>>8);
arr_append(t,0);// Դ<EFBFBD><EFBFBD>ַ
arr_append(t,dst);// Ŀ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ
arr_append(t,cmd);// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
arr_append(t,0);// 源地址
arr_append(t,dst);// 目标地址
arr_append(t,cmd);// 命令码
arr_append(t,slave->no&0xff);
arr_append(t,slave->no>>8);
arr_appends_from(t,data);
@@ -388,7 +388,7 @@ array_def *protm_encode(protm_def *p,uint8_t dst,uint8_t cmd,list_def *comp_cmd/
return t;
}
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD>ȿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>
// 发送数据,发送前先开启超时定时器
int protm_send(protm_def *p,send_data_def *d)
{
rt_tick_t tick=0;
@@ -406,7 +406,7 @@ int protm_send(protm_def *p,send_data_def *d)
}
//// <EFBFBD>ۺ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ
//// 槽函数,发送数据到指定地址
//void protm_send_call(protm_def *p,list_def *addrs/*int*/,uint8_t cmd,list_def *comp_cmd/*int*/,array_def *data)
//{
// param_check(p);
@@ -425,7 +425,7 @@ int protm_send(protm_def *p,send_data_def *d)
// <EFBFBD>ۺ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ
// 槽函数,发送数据到指定地址
void protm_send_call(protm_def *p,uint8_t addr,uint8_t cmd,list_def *comp_cmd/*int*/,array_def *data,int timeout_ms,int retry)
{
param_check(p);
@@ -435,7 +435,7 @@ void protm_send_call(protm_def *p,uint8_t addr,uint8_t cmd,list_def *comp_cmd/*i
t=protm_encode(p,addr,cmd,comp_cmd,data);
//protm_send(p,t);
//arr_delete(t);
// <EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͷ<EFBFBD><EFBFBD>У<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȵ<EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD>ܷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>
// 添加到发送队列,发送必须等到回应或超时才能发送下一个
DBG_LOG("send to:%d",addr);
send_data_def sd={0};
sd.addr=addr;sd.data=t;
@@ -456,7 +456,7 @@ void protm_send_call(protm_def *p,uint8_t addr,uint8_t cmd,list_def *comp_cmd/*i
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD><EFBFBD>ʾ<EFBFBD>˵<EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD>Է<EFBFBD><EFBFBD>͵<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˿<EFBFBD>
// 返回1表示此地址可以发送到这个端口
int protm_contains(protm_def *p,uint8_t addr)
{
param_check(p);

186
source/task/input.c Normal file
View File

@@ -0,0 +1,186 @@
#include "board.h"
#include "rtthread.h"
#include "debug.h"
#include "string.h"
#include "dev_flash.h"
#include "prot_uc.h"
#include "input.h"
#include "mystdlib.h"
#include "transmit.h"
/*
读取所有输入通道
*/
// 定义输入通道数
#define INPUT_CHANNEL_NUM 10
typedef struct{
gpioin_def *dev;
int input;
int input_lock;
int turn_true_call_always;// 为0时单次回调为1时永久回调
int turn_false_call_always;// 同上
void (*turn_true_to_call)(void *turn_true_obj);
void (*turn_false_to_call)(void *turn_false_obj);
void *turn_true_obj;
void *turn_false_obj;
}input_def;
// 判断此通道状态是否发生了翻转
// 0翻转为false1翻转为true-1未翻转
static int input_check_state(input_def *s)
{
s->input=(s->dev->state(s->dev));
if(s->input!=s->input_lock){
DBG_LOG("%s=%d",s->dev->name, s->input);
s->input_lock=s->input;
if((s->input)==0){
return 0;
}else{
return 1;
}
}else{
return -1;
}
}
// 根据输入通道的状态调用回调函数
static void input_run(input_def *s)
{
int state=input_check_state(s);
if(state==1)
{
if(s->turn_true_to_call)
s->turn_true_to_call(s->turn_true_obj);
irq_disable();
if(s->turn_true_call_always==0)
{
s->turn_true_to_call=0;
s->turn_true_obj=0;
}
irq_enable();
}else if(state==0)
{
if(s->turn_false_to_call)
s->turn_false_to_call(s->turn_false_obj);
irq_disable();
if(s->turn_false_call_always==0)
{
s->turn_false_to_call=0;
s->turn_false_obj=0;
}
irq_enable();
}
}
typedef struct{
int inited;
int run;
void *tran;
input_def input[INPUT_CHANNEL_NUM];
}self_def;
static self_def g_self;
static void input_thread(void *arg)
{
self_def *s=arg;
char gpioin_name[]="gpioin0";
for(int i=0;i<INPUT_CHANNEL_NUM;i++)
{
gpioin_name[6]='0'+i;
s->input[i].dev=dev_get(gpioin_name);
s->input[i].dev->init(s->input[i].dev);
}
while (s->run)
{
rt_thread_mdelay(20);
for(int i=0;i<INPUT_CHANNEL_NUM;i++)
{
input_run(&s->input[i]);
}
}
}
static int init_thread(void)
{
self_def *s=&g_self;
s->inited=1;
s->run=1;
rt_thread_t rt_t=rt_thread_create("input_t",input_thread,s,1024,15,20);
rt_thread_startup(rt_t);
return 0;
}
app_init_export(init_thread)
static int input_set_callback(int always,int channel,int state_to_call,void (*fun)(void *t),void *t)
{
self_def *s=&g_self;
input_def *in=0;
if(channel<0||channel>=INPUT_CHANNEL_NUM)
return -1;
irq_disable();
in=&s->input[channel];
if(state_to_call){
in->turn_true_to_call=fun;
in->turn_true_obj=t;
in->turn_true_call_always=always;
}else{
in->turn_false_to_call=fun;
in->turn_false_obj=t;
in->turn_false_call_always=always;
}
irq_enable();
return 0;
}
// 设置永久回调函数
// channel:通道(0~9);state_to_call:回调调用时的输入状态;fun:回调函数
// 返回0成功
int input_set_callback_always(int channel,int state_to_call,void (*fun)(void *t),void *t)
{
return input_set_callback(1,channel,state_to_call,fun,t);
}
// 设置单次回调函数
int input_set_callback_once(int channel,int state_to_call,void (*fun)(void *t),void *t)
{
return input_set_callback(0,channel,state_to_call,fun,t);
}

28
source/task/input.h Normal file
View File

@@ -0,0 +1,28 @@
#ifndef input_h__
#define input_h__
#include "rtthread.h"
#include "transmit.h"
#include "signal.h"
#include "bytearray.h"
int input_set_callback_always(int channel,int state_to_call,void (*fun)(void *t),void *t);
int input_set_callback_once(int channel,int state_to_call,void (*fun)(void *t),void *t);
#endif

View File

@@ -1,115 +0,0 @@
#include "board.h"
#include "rtthread.h"
#include "debug.h"
#include "string.h"
#include "dev_flash.h"
#include "prot_uc.h"
#include "key.h"
#include "mystdlib.h"
#include "transmit.h"
// 作为批检仪使用时读取按键
typedef struct{
int inited;
int run;
int input;
int input_lock;
void *tran;
}self_def;
static self_def g_self;
static void request_check(void *p);
static void key_thread(void *arg)
{
self_def *s=arg;
gpioin_def *in1;
in1=dev_get("gpioin1");
in1->init(in1);
s->input=0;
s->input_lock=1;
while (s->run)
{
rt_thread_mdelay(20);
s->input=(in1->state(in1));
if(s->input!=s->input_lock)
{
DBG_LOG("key=%08X",s->input);
s->input_lock=s->input;
if((s->input&1)==0)
{
// 主机交互存在且非忙的时候才发送请求
if(s->tran&&(tran_get_busy(s->tran)==0))
request_check(s);
}
}
}
}
// 获取实时按键状态,1按下
int key_pressed(void)
{
self_def *s=&g_self;
return !s->input;
}
// cmd=0x37
static void request_check(void *p)
{
const sys_param_def *par=sys_param();
array_def *d=arr_creat();
arr_append(d,0);
emit key_send_signal(p,0x37,arr_temp(d));
//DBG_LOG("tcp liver:%s",str_temp(arr_string(d)));
}
static void init_later(void *t)
{
void *protu=app_variable("protu",0,0);
if(protu){
protu_codec_set(protu,protu_find_codec("ym_checker"));
connect(t,key_send_signal,0,protu,protu_send_call);
DBG_LOG("key thread created");
}else{
DBG_WARN("can not fond variable \"protu\"");
}
}
static void init_tran(void *t)
{
self_def *s=t;
s->tran=app_variable("tran",0,0);
}
static int init_thread(void)
{
if(strcmp(sys_param()->device_type,"checker")==0)
{
self_def *s=&g_self;
s->inited=1;
s->run=1;
rt_thread_t rt_t=rt_thread_create("key_t",key_thread,s,1024,15,20);
rt_thread_startup(rt_t);
app_valid_call("protu",init_later,s);
app_valid_call("tran",init_tran,s);
}
return 0;
}
app_init_export(init_thread)

View File

@@ -1,29 +0,0 @@
#ifndef key_h__
#define key_h__
#include "rtthread.h"
#include "transmit.h"
#include "signal.h"
#include "bytearray.h"
signal key_send_signal(void *obj,uint8_t cmd,array_def *data);
int key_pressed(void);
#endif

View File

@@ -4,9 +4,10 @@
#include "handle.h"
#include "handle_for_checker.h"
#include "handle_for_coder.h"
#include "key.h"
#include "input.h"
#include "log.h"
#include "moter.h"
#include "process.h"
#include "prot_mcu.h"
#include "prot_uc.h"
#include "tcp.h"
@@ -14,6 +15,7 @@
#include "tran_for_checker.h"
#include "tran_for_coder.h"
#include "tran_for_coder2.h"
#include "tran_for_coder2ch.h"
#include "udp.h"
@@ -60,17 +62,6 @@ signal_export(port_end_signal);
uint32_t param[4];
param[0]=(uint32_t)src;
param[1]=(uint32_t)data;
param[2]=(uint32_t)ack;
param[3]=(uint32_t)err_str;
_signal_emit(obj,port_end_signal,param,4);
}
signal_export(port_end_signal);
param[2]=(uint32_t)ack;
param[3]=(uint32_t)err_str;
_signal_emit(obj,port_end_signal,param,4);
@@ -79,6 +70,17 @@ signal_export(moter_end_signal);
void moter_end_signal(void *m)
{
_signal_emit(m,moter_end_signal,0,0);
}
signal_export(moter_end_signal);
@@ -166,6 +168,25 @@ signal_export(coder2_live_send_signal);
_signal_emit(p,tran_reply_signal,param,1);
}
signal_export(tran_reply_signal);
void tran_send_signal(tran_def *p,uint8_t cmd,array_def *data)
{
uint32_t param[2];
param[0]=(uint32_t)cmd;
param[1]=(uint32_t)data;
_signal_emit(p,tran_send_signal,param,2);
}
signal_export(tran_send_signal);

View File

@@ -6,7 +6,7 @@
#include "board.h"
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬
// 运行状态
typedef enum{
STOP=0,
INITING=1,
@@ -68,7 +68,7 @@ static void moter_run(void *t)
s->count+=s->want_count;
}else if(s->stat==UPING)
{
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ s->want_count Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȼ<EFBFBD>Ǽ<EFBFBD>
// 向上时 s->want_count 为负数,所以依然是加
s->count+=s->want_count;
if(s->count<0) s->count=0;
}
@@ -88,7 +88,7 @@ static void moter_run(void *t)
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>ص<EFBFBD>
// 电机下降,完成时回调
void moter_down(void (*fun)(void *t),void *t)
{
self_def *s=&g_self;
@@ -99,7 +99,7 @@ void moter_down(void (*fun)(void *t),void *t)
moter_start(0,s->max_count-s->count);
}
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>ص<EFBFBD>
// 电机上升,完成时回调
void moter_up(void (*fun)(void *t),void *t)
{
self_def *s=&g_self;
@@ -194,7 +194,7 @@ int init_moter(void)
}
return 0;
}
app_init_export(init_moter)
//app_init_export(init_moter)

569
source/task/process.c Normal file
View File

@@ -0,0 +1,569 @@
#include "board.h"
#include "rtthread.h"
#include "debug.h"
#include "string.h"
#include "dev_flash.h"
#include "prot_uc.h"
#include "input.h"
#include "mystdlib.h"
#include "transmit.h"
#include "mymisc.h"
#include "process.h"
#include "tran_for_coder2ch.h"
#include "coder_judge.h"
/*
赋码操作流程控制
*/
// 定义输入通道别名
//#define INPUT_STOP_KEY 0
//#define INPUT_CHECK_KEY 1
//#define INPUT_MARK_END 2
//#define INPUT_POS_LEFT 6
//#define INPUT_POS_RIGHT 7
// 调试用输入通道别名
#define INPUT_STOP_KEY 0
#define INPUT_CHECK_KEY 1
#define INPUT_MARK_END 2
#define INPUT_POS_LEFT 3
#define INPUT_POS_RIGHT 4
// 定义输出通道别名
#define OUTPUT_PUSH_CYLINDER 0
#define OUTPUT_SHELL_BAFFLE 1
#define OUTPUT_CLAMP_CYLINDER 2
#define OUTPUT_LED_OK 3
#define OUTPUT_LED_ERR 4
#define OUTPUT_MARK 7
// 定义总线选择
#define BUS_SELECT_LEFT 0
#define BUS_SELECT_RIGHT 1
// 定义推料气缸方向
#define PUSH_DIR_TO_RIGHT 1
#define PUSH_DIR_TO_LEFT 0
// 定义输出通道数量
#define OUTPUT_CHANNEL_NUM 10
// 急停时不动作
#define SAFE_CHECK(s)\
if(s->stop_state) return
// 设置当前步骤
#define SET_STEP(s,d)\
if(s/right_idle){s=right_##d;}else{s=left_##d;}
// 校验当前步骤是返回1不是返回0
#define CHECK_STEP(s,d)\
(s/right_idle)?(s==right_##d):(s==left_##d)
// 获取到位传感器通道
#define GET_POS_CHANNEL(s) \
(s/right_idle)?INPUT_POS_RIGHT:INPUT_POS_LEFT
// 获取当前使用的总线
#define GET_BUS_CHANNEL(s)\
(s/right_idle)?BUS_SELECT_RIGHT:BUS_SELECT_LEFT
// 获取当前推料气缸的方向
#define GET_PUSH_DIR(s)\
(s/right_idle)?PUSH_DIR_TO_LEFT:PUSH_DIR_TO_RIGHT
// 重置状态
#define RESET_STEP(s)\
if(s<right_idle){s=right_idle;}else{s=left_idle;}
// 设置指示灯状态
#define SET_LED_OK()\
{output_set(&s->output[OUTPUT_LED_ERR],0);\
output_set(&s->output[OUTPUT_LED_OK],1);}
#define SET_LED_ERR()\
{output_set(&s->output[OUTPUT_LED_ERR],1);\
output_set(&s->output[OUTPUT_LED_OK],0);}
#define SET_LED_OFF()\
{output_set(&s->output[OUTPUT_LED_ERR],0);\
output_set(&s->output[OUTPUT_LED_OK],0);}
// 设置输出通道状态
#define SET_OUTPUT(c,p)\
output_set(&s->output[c],p);
// 复位输出状态
#define RESET_OUTPUT()\
{output_set(&s->output[OUTPUT_SHELL_BAFFLE],0);\
output_set(&s->output[OUTPUT_CLAMP_CYLINDER],0);\
output_set(&s->output[OUTPUT_MARK],0);}
typedef struct{
gpioout_def *dev;
int state;
}output_def;
// 设置输出状态
static int output_set(output_def *s,int state)
{
s->dev->set(s->dev,state);
s->state=state;
return 0;
}
typedef enum{
left_idle=0,
left_push,
left_requst,
left_code,
right_idle,
right_push,
right_requst,
right_code,
}process_step;
typedef struct{
int inited;
int run;
void *tran;
array_def *code_data;// 赋码数据
rt_timer_t timer;
int busy;// 忙,此时不再响应启动按键
process_step step;// 流程步数0为空闲
int stop_state;// 急停标志值1时不运行
output_def output[OUTPUT_CHANNEL_NUM];
output_def led;
output_def mod1_use;
output_def bus_sel;
output_def mod_sel;
}self_def;
static self_def g_self;
static const char *g_errinfo_table[]={
"",
"左侧到位检测失败",
"左侧请求三码数据失败",
"左侧赋码失败",
"",
"右侧到位检测失败",
"右侧请求三码数据失败",
"右侧赋码失败",
};
//static const char *g_errinfo_table[]={
// "",
// "left pos check failed",
// "left 3code request failed",
// "left code failed",
// "",
// "right pos check failed",
// "right 3code request failed",
// "right code failed",
//};
// 急停按钮响应函数
static void process_stop(void *arg)
{
self_def *s=arg;
s->stop_state=1;
SET_LED_ERR();
DBG_LOG("stop key pressed.");
}
static void process_run(void *arg)
{
self_def *s=arg;
s->stop_state=0;
SET_LED_OFF();
DBG_LOG("stop key unpressed.");
}
// 异常上报函数
static void process_send_errinfo(void *arg)
{
self_def *s=arg;
const char *err_info=g_errinfo_table[s->step];
int errlen=strlen(err_info);
array_def *a=arr_creat();
arr_append(a,s->step);
arr_appends(a,err_info,errlen);
process_send_signal(s,0x8c,arr_temp(a));
}
// 超时响应函数
static void process_timeout(void *arg)
{
self_def *s=arg;
SAFE_CHECK(s);
// 上报异常信息
process_send_errinfo(s);
DBG_WARN("timeout,errcode=%d",s->step);
if(CHECK_STEP(s->step,push)){
// 取消到位回调
input_set_callback_once(GET_POS_CHANNEL(s->step),1,0,0);
}
// 重置状态
RESET_STEP(s->step);
// 复位输出状态
RESET_OUTPUT();
s->busy=0;
SET_LED_ERR();
}
// 重置定时器
static void process_timer_start(void *arg)
{
self_def *s=arg;
SAFE_CHECK(s);
if(s->timer==0)
{
s->timer=rt_timer_create("proc_tim",process_timeout,s,
rt_tick_from_millisecond(5000),
RT_TIMER_FLAG_ONE_SHOT|RT_TIMER_FLAG_SOFT_TIMER);
}
rt_timer_start(s->timer);
}
// 停止定时器
static void process_timer_stop(void *arg)
{
self_def *s=arg;
if(s->timer){
rt_timer_stop(s->timer);
}
}
// 检测按键响应函数
static void process_check_start(void *arg)
{
self_def *s=arg;
SAFE_CHECK(s);
if(s->busy) {
DBG_WARN("check is running.");
return;
}
s->busy=1;
SET_LED_OFF();
process_timer_start(s);
SET_STEP(s->step,push);
// 启动推料气缸
SET_OUTPUT(OUTPUT_PUSH_CYLINDER,GET_PUSH_DIR(s->step));
// 设置到位回调
void process_pos(void *arg);
input_set_callback_once(GET_POS_CHANNEL(s->step),1,process_pos,s);
// 选择当前使用的总线
output_set(&s->bus_sel,GET_BUS_CHANNEL(s->step));
DBG_LOG("check_start key pressed.");
}
// 到位响应函数
static void process_pos(void *arg)
{
self_def *s=arg;
SAFE_CHECK(s);
int chip=coder_extract_chip(0);
// 请求三码数据
array_def *a=arr_creat();
arr_append(a,chip);
emit process_send_signal(s,0x8b,arr_temp(a));
SET_STEP(s->step,requst);
process_timer_start(s);
// 打开线夹
SET_OUTPUT(OUTPUT_CLAMP_CYLINDER,1);
DBG_LOG("pos in place.");
}
// 开始注码响应函数
static void process_start_slot(void *arg)
{
self_def *s=arg;
SAFE_CHECK(s);
SET_STEP(s->step,code);
process_timer_stop(s);
DBG_LOG("start code.");
}
// 赋码结束响应函数
static void process_end_slot(void *obj,int ack,array_def *data)
{
self_def *s=obj;
SAFE_CHECK(s);
if(ack){
SET_LED_ERR();
// 发送异常信息
process_send_errinfo(s);
// 发送赋码结果
emit tran_send_signal(s->tran,0x82,data);
// 复位输出状态
RESET_OUTPUT();
// 复位步骤
RESET_STEP(s->step);
s->busy=0;
return;
}else{
SET_LED_OK();
}
// 保存到内部存储
if(s->code_data){
arr_delete(s->code_data);
}
s->code_data=arr_duplicate(data);
// 关闭线夹
SET_OUTPUT(OUTPUT_CLAMP_CYLINDER,0);
// 打开挡板
SET_OUTPUT(OUTPUT_SHELL_BAFFLE,1);
// 400ms 后开始打标
void process_mark_start(void *arg);
later_execute(process_mark_start,s,400);
// 5s 后打标结束
void process_mark_end(void *arg);
later_execute(process_mark_end,s,5000);
}
// 开始打标回调函数
static void process_mark_start(void *arg)
{
self_def *s=arg;
SAFE_CHECK(s);
SET_OUTPUT(OUTPUT_MARK,1);
DBG_LOG("mark start.");
}
// 打标结束回调函数
static void process_mark_end(void *arg)
{
self_def *s=arg;
SAFE_CHECK(s);
// 关闭挡板
SET_OUTPUT(OUTPUT_SHELL_BAFFLE,1);
SET_OUTPUT(OUTPUT_MARK,0);
// 发送注码结果
if(s->code_data){
emit tran_send_signal(s->tran,0x82,s->code_data);
}
// 复位输出状态
RESET_OUTPUT();
// 复位步骤
RESET_STEP(s->step);
s->busy=0;
DBG_LOG("mark end.");
}
// 线程初始化
static void process_init(void *arg)
{
self_def *s=arg;
// 初始化输出通道
char gpioout_name[]="gpioout0";
for(int i=0;i<OUTPUT_CHANNEL_NUM;i++)
{
gpioout_name[7]='0'+i;
s->output[i].dev=dev_get(gpioout_name);
s->output[i].dev->init(s->output[i].dev);
}
// 初始化led
s->led.dev=dev_get("led");
s->led.dev->init(s->led.dev);
// 初始化模块1使用0把模块1连接到总线11不连接到总线1
// 如果要两个总线同时使用则模块0必须连接到总线2
s->mod1_use.dev=dev_get("mod1_use");
s->mod1_use.dev->init(s->mod1_use.dev);
output_set(&s->mod1_use,1);
// 初始化总线选择0选择bus11选择bus2
s->bus_sel.dev=dev_get("bus_sel");
s->bus_sel.dev->init(s->bus_sel.dev);
output_set(&s->bus_sel,0);
// 初始化模块选择,0选择模块01选择模块1
s->mod_sel.dev=dev_get("mod_sel");
s->mod_sel.dev->init(s->mod_sel.dev);
output_set(&s->mod_sel,0);
// 设置急停按钮
input_set_callback_always(INPUT_STOP_KEY,1,process_stop,s);
input_set_callback_always(INPUT_STOP_KEY,0,process_run,s);
// 设置启动按钮
input_set_callback_always(INPUT_CHECK_KEY,1,process_check_start,s);
}
static void process_thread(void *arg)
{
self_def *s=arg;
process_init(s);
while (s->run)
{
rt_thread_mdelay(200);
output_set(&s->led,1);
rt_thread_mdelay(200);
output_set(&s->led,0);
}
}
static void init_later(void *t)
{
void *protu=app_variable("protu",0,0);
if(protu){
protu_codec_set(protu,protu_find_codec("ym_checker"));
connect(t,process_send_signal,0,protu,protu_send_call);
DBG_LOG("process thread created");
}else{
DBG_WARN("can not fond variable \"protu\"");
}
}
static void init_tran(void *t)
{
self_def *s=t;
s->tran=app_variable("tran",0,0);
if(s->tran){
connect(s->tran,code2_end_signal,0, t,process_end_slot);
connect(s->tran,code2_start_signal,0,t,process_start_slot);
}else{
DBG_WARN("can not fond variable \"tran\"");
}
}
static int init_thread(void)
{
self_def *s=&g_self;
s->inited=1;
s->run=1;
rt_thread_t rt_t=rt_thread_create("process_t",process_thread,s,1024,15,20);
rt_thread_startup(rt_t);
app_valid_call("protu",init_later,s);
app_valid_call("tran",init_tran,s);
return 0;
}
app_init_export(init_thread)
// 定义接收上位机命令用于模拟输入通道触发
typedef struct{
ucport_def u;
}pccmd_def;
void (*g_input_fun_table[])(void *t)={
process_stop,
process_run,
process_check_start,
process_pos,
};
static ucport_def *process_pccmd(tran_def *t, uint8_t cmd,array_def *data)
{
if(arr_length(data)<1){
DBG_WARN("cmd format err.");
return 0;
}
int ret=0;
pccmd_def *u=calloc(1,sizeof(pccmd_def));
int table_len=LENGTH(g_input_fun_table);
int index=arr_get(data,0);
if(index>=0&&index<table_len){
DBG_LOG("call the pccmd fun.index=%d",index);
g_input_fun_table[index](&g_self);
}else{
DBG_WARN("can not find the pccmd fun.index=%d",index);
}
return (ucport_def *)u;
}
transmit_export(ym_checker,0x90,process_pccmd)

21
source/task/process.h Normal file
View File

@@ -0,0 +1,21 @@
#ifndef process_h__
#define process_h__
#include "list.h"
#include "bytearray.h"
#include "signal.h"
signal process_send_signal(void *obj,uint8_t cmd,array_def *data);
#endif

View File

@@ -315,7 +315,7 @@ protm_def *protm_creat(uart_def *uart,int *addrs,int num)
RT_TIMER_FLAG_ONE_SHOT|RT_TIMER_FLAG_SOFT_TIMER);
list_appends(p->slaves_addr,addrs,num);
sprintf(name,"protm_t#%d",count);
rt_thread_t rt_t=rt_thread_create(name,protm_run,p,2048,5+count,20);
rt_thread_t rt_t=rt_thread_create(name,protm_run,p,1024,5+count,20);
rt_thread_startup(rt_t);
p->uart->init(p->uart,0);
//p->uart->set_irq(p->uart,recv_irq,p);

View File

@@ -167,7 +167,7 @@ static void protu_run(void *t)
arr_appends(data,p->buff,p->buff_index);
p->num_to_recv=0;
p->buff_index=0;
DBG_LOG("recv:%s",str_temp(arr_string(data)));
//DBG_LOG("recv:%s",str_temp(arr_string(data)));
decode_data=protu_try_decode(p,data);
//DBG_LOG("decode:%s",str_temp(arr_string(decode_data)));
if(p->codec)
@@ -199,21 +199,12 @@ static void protu_set_endecode_fun(protu_def *u)
static int protu_init(void)
{
const sys_param_def *par=sys_param();
const char *name="uart4";
if(strcmp((par->host_if),"utcp")==0)
name="utcp";
const char *name="uart1";
protu_def *protu=protu_creat(dev_get(name));
app_variable("protu",protu,0);
// 如果通信接口不是用的串口,则增加一个串口的通信
if(strcmp(par->host_if,"uart4")==0)
{
app_variable("protu2",protu,0);
}else
{
protu_def *protu2=protu_creat(dev_get("uart4"));
app_variable("protu2",protu2,0);
}
// 复制一个引用,用于命令行调试
app_variable("protu2",protu,0);
return 0;
}
app_init_export(protu_init)
@@ -234,7 +225,7 @@ protu_def *protu_creat(uart_def *uart)
p->cmd=0xff;// 命令字不可能是0xff
protu_set_endecode_fun(p);
sprintf(name,"protu_t#%d",count);
rt_thread_t rt_t=rt_thread_create(name,protu_run,p,2048,5,20);
rt_thread_t rt_t=rt_thread_create(name,protu_run,p,1024,5,20);
rt_thread_startup(rt_t);
int bsp=sys_param()->uartbsp;
if(bsp==9600)
@@ -254,7 +245,7 @@ protu_def *protu_creat(uart_def *uart)
int protu_send(protu_def *p,array_def *data)
{
DBG_LOG("send:%s",str_temp(arr_string(data)));
//DBG_LOG("send:%s",str_temp(arr_string(data)));
return p->uart->write(p->uart,arr_data(data),arr_length(data));
}

View File

@@ -10,7 +10,7 @@
#include "compiler_info.h"
#include "dev_backup.h"
#include "moter.h"
#include "key.h"
//#include "key.h"
@@ -160,7 +160,8 @@ static ucport_def *check(tran_def *t, uint8_t cmd,array_def *data)
u->u.doend=check_end;
DBG_LOG("check: skip=%d",u->ret_skip);
array_def *a=arr_creat();
if(key_pressed())
//if(key_pressed())
if(1)
{
tran_set_busy(t,1);
moter_down(check_when_moter_down,u);

View File

@@ -59,7 +59,7 @@ static void write_uid_upmit(write_uid_def *w)
array_def *a=arr_creat();
arr_append(a,w->addrs_num);
// arr_appends(a,w->ack,390);
for(int i=0;i<10;i++)
for(int i=0;i<w->addrs_num;i++)
{
uint8_t *d=&w->ack[i*39];
if(sys_param()->coder_ret_mode)
@@ -94,7 +94,7 @@ static void write_uid_fillret(write_uid_def *w,int addr,int ack)
memcpy(&d[2],w->item[addr].shell_code,13);
memcpy(&d[2+13],w->item[addr].uid_code,16);
memcpy(&d[2+13+16],w->item[addr].password,8);
if(w->ack_num>=10)
if(w->ack_num>=w->addrs_num)
{
write_uid_upmit(w);
}
@@ -107,7 +107,7 @@ static void write_uid_end(ucport_def *u,port_mcu *src,void *data,int ack,char *e
{
write_uid_def *w=(write_uid_def *)u;
uint8_t addr=port_get_addr(src);
if(addr<=0||addr>10){
if(addr<=0||addr>w->addrs_num){
DBG_WARN("addr err:%d",addr);
return;
}
@@ -123,7 +123,7 @@ static void write_uid_return_ok(void *p)
write_uid_def *u=p;
array_def *a=arr_creat();
arr_append(a,u->addrs_num);
for(int i=0;i<10;i++)
for(int i=0;i<u->addrs_num;i++)
{
arr_append(a,i+slave_addr_off());
arr_append(a,0);
@@ -170,7 +170,7 @@ static ucport_def *write_uid(tran_def *t, uint8_t cmd,array_def *data)
uint8_t *d_off=arr_data(data)+4+1;
uint8_t *d_;
tran_set_busy(t,1);
for(int i=0;i<10;i++)
for(int i=0;i<u->addrs_num;i++)
{
memcpy(u->item[i].shell_code,d_off+i*14+1,13);
DBG_LOG("slave:%d, shell=%s",i,u->item[i].shell_code);
@@ -229,7 +229,7 @@ static ucport_def *write_uid(tran_def *t, uint8_t cmd,array_def *data)
}
transmit_export(ym_checker,0x02,write_uid)
//transmit_export(ym_checker,0x02,write_uid)
@@ -341,7 +341,7 @@ static void check_end(ucport_def *u,port_mcu *src,void *data,int ack,char *err_s
{
check_def *w=(check_def *)u;
uint8_t addr=port_get_addr(src);
if(addr<=0||addr>10){
if(addr<=0||addr>w->addrs_num){
DBG_WARN("addr err:%d",addr);
return;
}
@@ -371,7 +371,7 @@ static void check_end(ucport_def *u,port_mcu *src,void *data,int ack,char *err_s
}
w->ack_num++;
if(w->ack_num>=10)
if(w->ack_num>=w->addrs_num)
{
array_def *a=arr_creat();
arr_append(a,w->addrs_num);
@@ -394,7 +394,7 @@ static void check_return_ok(void *p)
arr_append(a,u->addrs_num);
arr_append(a,u->type);
// 固定返回6*10个字节如果不检测某通道则该通道填充占位符
for(int i=0;i<10;i++){
for(int i=0;i<u->addrs_num;i++){
arr_append(a,i+slave_addr_off());
arr_append(a,0);// 成功
arr_append(a,i+1);// 返回真是序号
@@ -433,13 +433,13 @@ static ucport_def *check(tran_def *t, uint8_t cmd,array_def *data)
u->addrs_num=arr_get(data,0);
u->type=arr_get(data,0);
// 默认失败
for(int i=0;i<10;i++)
for(int i=0;i<u->addrs_num;i++)
{
u->ack[i*6+0]=i+slave_addr_off();
u->ack[i*6+1]=1;
}
tran_set_busy(t,1);
for(int i=0;i<10;i++)
for(int i=0;i<u->addrs_num;i++)
{
if(1){
port_mcu *mcu=tran_get_portm(u->u.p,i);
@@ -502,7 +502,7 @@ static void live_send(void *p)
if(t)
slave_online=tran_get_slave_online(t);
array_def *d=arr_creat();
arr_append(d,0);
arr_append(d,0);// 改为模块类型
arr_append(d,0xff);
arr_append(d,0x03);
arr_append(d,par->local_id&0xff);
@@ -548,6 +548,6 @@ static int init_live_keeper(void)
}
return 0;
}
app_init_export(init_live_keeper);
//app_init_export(init_live_keeper);

View File

@@ -0,0 +1,406 @@
#include "tran_for_coder2.h"
#include "tran_for_coder2ch.h"
#include "debug.h"
#include "mymisc.h"
#include "mystdlib.h"
#include "board.h"
#include "dev_flash.h"
#include "tcp.h"
#include "prot_uc.h"
#include "handle_for_coder.h"
#include "handle_for_checker.h"
#include "coder_lib.h"
#include "JQ_PSDGenerate.h"
#include "mystring.h"
#include "coder_judge.h"
#include "JQ_UIDGenerate.h"
// JQ模块在检测时注码
typedef struct{
int step;// 检测注码顺序
}self_def;
static self_def g_self;
// 从机地址偏移
static inline int slave_addr_off(void)
{
if(sys_param()->slave_addr_start)
return 1;
else
return 0;
}
typedef struct{
ucport_def u;
uint8_t addrs_num;
char year[10];
struct{
char shell_code[20];
char uid_code[20];
char password[10];
uint8_t uid_pw_hex[15];
}item[10];
uint8_t ack[390];
uint8_t ack_num;
void (*doexert)(ucport_def *u);
}write_uid_def;
// 上报注码结果
static void write_uid_upmit(write_uid_def *w)
{
int ack=0;
array_def *a=arr_creat();
arr_append(a,w->addrs_num);
// arr_appends(a,w->ack,390);
for(int i=0;i<w->addrs_num;i++)
{
uint8_t *d=&w->ack[i*38];
ack|=d[1];
if(sys_param()->coder_ret_mode)
{
// 完整模式
arr_appends(a,d,38);
}
else{
// 精简模式
arr_appends(a,d,2);
d+=2+13+15;
arr_appends(a,d,8);
}
}
// emit tran_send_signal(w->u.p,0x82,arr_temp(a));
// 发送赋码结束信号
emit code2_end_signal(w->u.p,ack,arr_temp(a));
g_self.step=0;
// 把命令字改为0x82用于接收主机应答
tran_set_busy(w->u.p,0);
w->u.cmd=0x82;
}
// 填充注码结果
static void write_uid_fillret(write_uid_def *w,int addr,int ack)
{
addr-=1;
uint8_t *d=&w->ack[(addr)*38];
w->ack_num++;
d[0]=addr+slave_addr_off();
//d[1]=((ack==0xff)||(ack==0x00))?ack:(ack+0xc0);
d[1]=ack;
memcpy(&d[2],w->item[addr].shell_code,13);
memcpy(&d[2+13],w->item[addr].uid_code,15);
memcpy(&d[2+13+15],w->item[addr].password,8);
if(w->ack_num>=w->addrs_num)
{
write_uid_upmit(w);
}
}
// 判断检测数据错误码
// 返回 errcode,1=param/0=execute,taskindex,paramindex
static uint32_t in_range_err(const uint8_t *src_data,const uint8_t *errbit)
{
const scheme_def *s=check_scheme();
const scheme_task_def *t;
int temp;
int index=0;
uint32_t ret=0;
for(int i=0;i<s->task_num;i++)
{
t=&s->task[i];
if((errbit[i/8]&(1<<(i%8)))!=0)
{
ret=(t->err&0xff)|(i<<16);
return ret;
}
for(int j=0;j<t->item_num;j++)
{
temp=src_data[index*2]|(src_data[index*2+1]<<8);
if(temp>=t->range[j].min&&temp<=t->range[j].max){
// 正常
}else{
ret=(t->range[j].err&0xff)|(1<<8)|(i<<16)|(j<<24);
return ret;
}
index++;
}
}
return ret;
}
// 注码完成
static void write_uid_end(ucport_def *u,port_mcu *src,void *data,int ack,char *err_str)
{
write_uid_def *w=(write_uid_def *)u;
uint8_t addr=port_get_addr(src);
if(addr<=0||addr>w->addrs_num){
DBG_WARN("addr err:%d",addr);
return;
}
uint32_t errcode=0;
if(ack==0)
{
if(data)
{
errcode=in_range_err(arr_data(data)+8+8,arr_data(data));
ack=coder_judge_jq(arr_data(data));
if(ack==0){
ack=errcode&0xff;
}
}else{
ack=0xd0;
DBG_WARN("check return data is none.");
}
}else{
ack=0xd0;// 通信超时
}
DBG_LOG("addr=%d,errcode=%d",addr,ack);
write_uid_fillret(w,addr,ack);
}
static void write_uid_return_ok(void *p)
{
write_uid_def *u=p;
array_def *a=arr_creat();
arr_append(a,u->addrs_num);
for(int i=0;i<u->addrs_num;i++)
{
arr_append(a,i+slave_addr_off());
arr_append(a,0);
arr_append_num(a,37,'0');
}
emit tran_send_signal(u->u.p,0x82,arr_temp(a));
tran_set_busy(u->u.p,0);
g_self.step=0;
}
static void write_del(ucport_def *u)
{
free(u);
}
static int write_uid_dolater(ucport_def *u,uint8_t cmd,array_def *data,char *err_str)
{
DBG_LOG("recv write_uid end signal.");
tran_set_busy(u->p,0);
return 0;
}
static ucport_def *write_uid(tran_def *t, uint8_t cmd,array_def *data)
{
if(arr_length(data)<14+4+1){
DBG_WARN("cmd format err.");
DBG_WARN("data=%s",str_temp(arr_string(data)));
return 0;
}
int ret=0;
write_uid_def *u=calloc(1,sizeof(write_uid_def));
u->u.p=t;
u->u.del=write_del;
u->u.doend=write_uid_end;
u->u.dolater=write_uid_dolater;
u->addrs_num=arr_get(data,0);
memcpy(u->year,arr_data(data)+1,4);
DBG_LOG("coder, year=%s",u->year);
// 数据固定140字节如果不检测某通道则该通道填充占位符
uint8_t *d_off=arr_data(data)+4+1;
uint8_t *d_;
tran_set_busy(t,1);
for(int i=0;i<u->addrs_num;i++)
{
memcpy(u->item[i].shell_code,d_off+i*14+1,13);
DBG_LOG("slave:%d, shell=%s",i,u->item[i].shell_code);
// 生成uid码
ret|=coder_shell_to_uid_jq(u->year,u->item[i].shell_code,u->item[i].uid_code);
DBG_LOG("slave:%d, uid=%s",i,u->item[i].uid_code);
// 生成存储码
//ret|=coder_uid_to_save(u->item[i].uid_code,u->item[i].uid_pw_hex);
UidCode_YM2JQ((PST_JQUID_TYPEDEF)u->item[i].uid_pw_hex,(PST_YMUID_TYPEDEF)u->item[i].uid_code);
// 生成密码
JQ_GetPasswordByUidCode((uint8_t *)u->item[i].uid_code,&u->item[i].uid_pw_hex[8]);
d_=u->item[i].uid_pw_hex;
DBG_LOG("slave:%d, uid_pw=%02X %02X %02X %02X %02X %02X %02X %02X "
"%02X %02X %02X %02X ",i,d_[0],d_[1],d_[2],d_[3],d_[4],d_[5],d_[6],d_[7],
d_[8],d_[9],d_[10],d_[11]);
// 生成密码字符串
sprintf(u->item[i].password,"%02X%02X%02X%02X",u->item[i].uid_pw_hex[8],
u->item[i].uid_pw_hex[9],u->item[i].uid_pw_hex[10],u->item[i].uid_pw_hex[11]);
// 默认失败
u->ack[i*38+0]=i+slave_addr_off();
u->ack[i*38+1]=1;
if(1){
port_mcu *mcu=tran_get_portm(u->u.p,i);
// 这里打开赋码操作
if(mcu){
if(check_shell_code(u->item[i].shell_code)){
port_start(mcu,code2_creat(8,4,u->item[i].uid_pw_hex));
}else{
// 管壳码无效,不注码,此时默认已ack
// 管壳码无效不视为失败
ret=0;
write_uid_fillret(u,i+1,0xff);
}
}
}
}
array_def *a=arr_creat();
arr_append(a,u->addrs_num);
// if(g_self.step==1){
if(ret==0)
arr_append(a,TRAN_ERR_NONE);
else
arr_append(a,TRAN_ERR_PARAM);
// }else{
// arr_append(a,TRAN_ERR_STEP);
// }
emit tran_reply_signal(u->u.p,arr_temp(a));
// test:稍后返回成功
//later_execute(write_uid_return_ok,u,500);
// 发送注码开始信号
emit code2_start_signal(u->u.p);
return (ucport_def *)u;
}
transmit_export(ym_checker,0x02,write_uid)
typedef struct{
rt_timer_t timer;
void *protu;
}live_keeper_def;
static void live_start(live_keeper_def *t)
{
rt_tick_t tick=0;
tick=rt_tick_from_millisecond(1000);
rt_timer_control(t->timer,RT_TIMER_CTRL_SET_TIME,&tick);
rt_timer_start(t->timer);
}
static void live_recv(live_keeper_def *t)
{
rt_tick_t tick=0;
tick=rt_tick_from_millisecond(5000);
rt_timer_control(t->timer,RT_TIMER_CTRL_SET_TIME,&tick);
//rt_timer_start(t->timer);
rt_timer_stop(t->timer);
}
// cmd=0x8a
static void live_send(void *p)
{
live_keeper_def *live=p;
const sys_param_def *par=sys_param();
tran_def *t=app_variable("tran",0,0);
uint16_t slave_online=0;
if(t){
slave_online=tran_get_slave_online(t);
}
protu_codec_set(live->protu,protu_find_codec("ym_checker"));
array_def *d=arr_creat();
arr_append(d,coder_extract_chip(0));// 模块类型
arr_append(d,0xff);
arr_append(d,0x03);
arr_append(d,par->local_id&0xff);
arr_append(d,slave_online&0xff);// 在线的小板
arr_append(d,(slave_online>>8)&0xff);
emit coder2_live_send_signal(p,0x8a,arr_temp(d));
//DBG_LOG("send liver data.");
}
static void init_for_coder2ch(void *t)
{
void *protu=app_variable("protu",0,0);
if(protu){
live_keeper_def *live=calloc(1,sizeof(live_keeper_def));
live->protu=protu;
live->timer=rt_timer_create("live_t",live_send,live,
rt_tick_from_millisecond(1000),
RT_TIMER_FLAG_PERIODIC|RT_TIMER_FLAG_SOFT_TIMER);
protu_codec_set(protu,protu_find_codec("ym_checker"));
connect(protu,protu_recv_signal,0,live,live_recv);
connect(live,coder2_live_send_signal,0,protu,protu_send_call);
DBG_LOG("coder2ch liver created");
live_start(live);
}else{
DBG_WARN("can not fond variable \"protu\"");
}
}
// 如果本机为赋码仪并且连接类型为tcp
// 初始化心跳
static int init_live_keeper(void)
{
const sys_param_def *par=sys_param();
app_valid_call("protu",init_for_coder2ch,0);
return 0;
}
app_init_export(init_live_keeper);

View File

@@ -0,0 +1,26 @@
#ifndef tran_for_coder2ch_h__
#define tran_for_coder2ch_h__
#include "list.h"
#include "bytearray.h"
#include "signal.h"
signal code2_end_signal(void *obj,int ack,array_def *data);
signal code2_start_signal(void *obj);
#endif

View File

@@ -20,7 +20,7 @@
#define PORT_NUM 20
#define PORT_NUM 2
typedef struct _tran_def{