本帖最后由 lvben5d 于 2022-2-14 11:05 编辑
截至发稿 GD32E103 LIb v1.2.2 的USBFS device cdc_acm 中,大家会发现 cdc_acm里的成员变量结构体指针 class_data 只有指向结构体 usb_cdc_handler指针数值, 你看不到结构体内容, 而这个指针被官网开发人员作为 static了,既然是static 也占全局变量,就应该设计成全局变量!
在文件cdc_acm_core. c中
static uint8_t cdc_acm_init (usb_dev *udev, uint8_t config_index)
{
static usb_cdc_handler cdc_handler;
。。。。。。
udev->dev.class_data[CDC_COM_INTERFACE] = (void *)&cdc_handler;
}
当然你不怕麻烦,每次可以在 live watch 里 输入 (usb_cdc_handler *) &0x???????? (????????是系统给你这个静态结构体分的内存位置 不同人会不同哦)!
至于为什么要改为全局变量,其1是方便 live watch的时候 直接输入 cdc_handler 其2 里面可以看到例程为什么 设计成 自收后立即自发回你的PC端,而我们实际的串口应用往往是想发的时候 上发, 接收的时候处于接收态,(注意USBFS 接收包 单个包最长是64字节, 每接收完64字节 就必须马上发送接收令牌包 否则PC端发大于64个字节的数据包的时候,就再也收不到了!)。
官网的目的是 可靠运行给你示范,如果不自发回来,那么大家注意 cdc->packet_sent这个标志 就不会置1.程序收到1个包后,就再也不能接收了! 所以cdc_acm_check_ready 函数内
{
if (udev->dev.class_data[CDC_COM_INTERFACE] != NULL) {
usb_cdc_handler *cdc = (usb_cdc_handler *)udev->dev.class_data[CDC_COM_INTERFACE];
if ((1U == cdc->packet_receive))// && (1U == cdc->packet_sent)) {
return 0U;
}
return 1U;
}
GD32E103的 USB 共享 1.25KB 独立RAM(不是程序运行的)TX 和 RX 可以独立分开, 所有数据的接收共享1个RX FIFO , 而TX FIFO 可以根据端点数 分割内存区域, 但FS每次发送的数据包 内容长度是64字节,虽然USBFS速度也很快,用户发送字节大于64的时候,还是要自己管理1个发送结束标志。避免程序特别快速的往TX FIFO塞入数据。 接收数据的时候,每收好64字节(建议 用户把应用代码 写到 static uint8_t cdc_acm_out (usb_dev *udev, uint8_t ep_num)) 这个是USB 中断函数里会callback的函数,把USB RX数据 放到用户自己的处理缓冲区去,然后立即重新使能 RX EP ! |