wxfjog
wxfjog
这家伙很懒,什么也没写!

注册于 4年前

回答
12
文章
0
关注者
1

发布于6月前

CAN接收线程死掉.png

发布于1年前

🙂感谢@道友 回复。
最近研究了下GD32F470芯片手册,发现标称的内存512KB, 其实是连TCMSRAM一起算的,即TCMSRAM+SRAM0+SRAM1+SRAM2+ADDSRAM = 512KB, 其中SRAM0 - ADDSRAM 这段内存地址是连续的,从地址0x20000000开始。而TCMSRAM地址却是从0x10000000 - 0x1000FFFF, 即64KB。如下图:

screenshot_图片.png
所以第一个连续内存只能写448KB。GD32F450芯片也是有类似同上的分存分布。相当于存在两个内存堆了,目前使用RT-thread 提供的memheap 多内存堆使用方法,在 broad.c文件手动加上TCMSRAM初始化,经测试可以正常使用。
部分代码如下:

  1. #define HEAP_TMCSRAM_BEGIN (0x10000000)
  2. #define HEAP_TCMSRAM_SIZE (64*1024)
  3. struct rt_memheap tcmsram;
  4. void rt_hw_board_init()
  5. {
  6. /* NVIC Configuration */
  7. #define NVIC_VTOR_MASK 0x3FFFFF80
  8. #ifdef VECT_TAB_RAM
  9. /* Set the Vector Table base location at 0x10000000 */
  10. SCB->VTOR = (0x10000000 & NVIC_VTOR_MASK);
  11. #else /* VECT_TAB_FLASH */
  12. /* Set the Vector Table base location at 0x08000000 */
  13. SCB->VTOR = (0x08020000 & NVIC_VTOR_MASK);
  14. #endif
  15. SystemClock_Config();
  16. #ifdef RT_USING_COMPONENTS_INIT
  17. rt_components_board_init();
  18. #endif
  19. #ifdef RT_USING_CONSOLE
  20. rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
  21. #endif
  22. #ifdef BSP_USING_SDRAM
  23. rt_system_heap_init((void *)EXT_SDRAM_BEGIN, (void *)EXT_SDRAM_END);
  24. #else
  25. rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
  26. rt_memheap_init(&tcmsram, "tcmsram", (void*)HEAP_TMCSRAM_BEGIN, (rt_size_t)HEAP_TCMSRAM_SIZE);
  27. #endif
  28. }

测试函数:

  1. void testm(void)
  2. {
  3. extern struct rt_memheap tcmsram;
  4. uint8_t *pt = RT_NULL;
  5. uint8_t *ps = RT_NULL;
  6. int i;
  7. pt = (uint8_t*)rt_memheap_alloc(&tcmsram, 1024);
  8. if(pt == RT_NULL)
  9. {
  10. rt_kprintf("pt no memory\n");
  11. }
  12. ps = (uint8_t*)rt_malloc(1024);
  13. if(ps == RT_NULL)
  14. {
  15. rt_kprintf("ps no memory\n");
  16. }
  17. memset(pt, 0x1a, 128);
  18. memset(ps, 0x2c, 128);
  19. for(i = 0; i < 128; i++)
  20. {
  21. rt_kprintf("%x ",*(pt+i));
  22. }
  23. rt_kprintf("\n");
  24. for(i = 0; i < 128; i++)
  25. {
  26. rt_kprintf("%x ",*(ps+i));
  27. }
  28. rt_kprintf("\n");
  29. LOG_D("pt = %x", pt);
  30. LOG_D("ps = %x", ps);
  31. rt_memheap_free(pt);
  32. rt_free(ps);
  33. }
  34. MSH_CMD_EXPORT(testm, test memory);

测试效果图:

screenshot_图片.png

发布于1年前

感谢各位应答,摸索了下,发现程序已经自带有应答状态返回了,稍利用一下就解决了,session->resp_status 这个就是应答状态码主要有以下代码:
200 OK //客户端请求成功
206 Partial Content //服务器已经成功处理了部分 GET 请求
400 Bad Request //客户端请求有语法错误,不能被服务器所理解
403 Forbidden //服务器收到请求,但是拒绝提供服务
404 Not Found //请求资源不存在,eg:输入了错误的URL
500 Internal Server Error //服务器发生不可预期的错误
503 Server Unavailable //服务器当前不能处理客户端的请求
, 我主要是判断文件是否存在,因此判断404这个状态码就可以,在函数webclient_shard_head_function()之后加上以下判断代码即可。

  1. if(session->resp_status == 404)
  2. {
  3. LOG_E("not found the file");
  4. ret = -RT_ERROR;
  5. goto __exit;
  6. }

修改后部分代码如下:

  1. static int http_ota_fw_download(char* partition, const char* uri)
  2. {
  3. int ret = RT_EOK;
  4. struct webclient_session* session = RT_NULL;
  5. int hstate;
  6. /* create webclient session and set header response size */
  7. session = webclient_session_create(GET_HEADER_BUFSZ);
  8. if (!session)
  9. {
  10. LOG_E("open uri failed.");
  11. ret = -RT_ERROR;
  12. goto __exit;
  13. }
  14. /* get the real data length */
  15. webclient_shard_head_function(session, uri, &file_size);
  16. if(session->resp_status == 404)
  17. {
  18. LOG_E("not found the file");
  19. ret = -RT_ERROR;
  20. goto __exit;
  21. }
  22. if (file_size == 0)
  23. {
  24. LOG_E("OTA file size is 0");
  25. ret = -RT_ERROR;
  26. goto __exit;
  27. }
  28. else if (file_size < 0)
  29. {
  30. LOG_E("webclient GET request type is chunked.");
  31. ret = -RT_ERROR;
  32. goto __exit;
  33. }
  34. LOG_I("OTA file size is (%d)", file_size);
  35. LOG_I("\033[1A");

修改后效果:
效果图.jpg

发布于2年前

解决了,flash擦写函数没弄好,👌。

发布于2年前

解决了,换个字体就行,应该是字体的问题😐

发布于2年前

去掉软件包,重新加入软件包就可以了,具体是什么问题引起,我也不太清楚,大家碰到时不防试试这个方法😆,后面等有空再去研究下是啥问题引起的。

发布于2年前

是控制两个半桥的控制有刷电机。,看了管脚资料是有两路PWM,但LCD也已经用了,SPI又外接了flash, 其它IO倒时足够。看来也只能增加单片机才才行了,

发布于4年前

分区分错了吧, 最大512K , param 那里应该从0x64000开始刚好512K,如果从0x74000开始就超过了512K了.

发布于4年前

之前祼机编程时,在发送数据之前都会清空接收缓冲如下代码:

  1. rec_cnt = 0; /*接收计数清空*/
  2. rec_finish = 0; /*接收完成标志清空*/
  3. send_data(buf, 10); /*发送数据*/

如果不清空,那么这前的数据会保留:
如之前有数据在接收缓冲区123,
那再次收到时数据时变成 123456,

显然,有时候我们不想这样,因为新的接收一帧是错误的,本来接收456数据才是正确。这对一问一答的协议非常不好,只有问了才应答,不问时,却收到了数据则要丢弃。
目前查看了源码并未有清除函数操作。但可以用读取函数来清空缓冲,效率可能低了些,经过测试,性能稳定。
读取接收清空操作:rt_device_read(serial, 0, buf,0,config.bufsz);

其中config.bufsz初始化时设置是接收最大接收量。

在中断回调函数里使用邮箱,邮箱只容纳一个邮件,邮件发送数据为串口DMA空闲接收到的一包数据的字节数量。经过优化后程序如下:

  1. while(1)
  2. {
  3. rt_thread_mdelay(5);
  4. rt_device_read(encoder_serial, 0, rx_buf,0,config.bufsz); /*清空接收数据缓冲,*/
  5. rt_mb_recv(&encoder_mb,&rec_size,0); /*清空邮件*/
  6. encoder_t.send_buf[0] = 0x19; /*读角度值*/
  7. rt_device_write(encoder_serial, 0,encoder_t.send_buf, 1);
  8. result = rt_mb_recv(&encoder_mb, &rec_size, 100); /*接收等待超时100ms*/
  9. if(result == RT_EOK)
  10. {
  11. rx_len = rt_device_read(encoder_serial, 0, rx_buf, rec_size); /*接收数据*/
  12. if(rx_len > 6)
  13. {
  14. parse_data((encoder_msg_typedef*)rx_buf); /*解析数据*/
  15. }
  16. }
  17. }

通过以上代码实现了祼机编程思路,如果觉得有用,可以参考,有写得不好,欢迎大家拍砖。

发布于4年前

看打印信息偏移地址写错了,应该改为0x80000

发布于4年前

大家好,通过调试打印输出已经找到问题的所在了,主要是在第一次读取端点0数据返回的wMaxPacketSize = 8, rtthread这个表达式,

  1. send_size = (remain_size > pipe->ep.wMaxPacketSize) ? pipe->ep.wMaxPacketSize : remain_size;

实际赋值 8 = (18 > 8)? 8:18 ,因此发送的只是请求返回前8个字节的设备描述符,使得出现返回的只有8个字节, 和读取18个字节
的设备描述符对不上,打印出get full device descriptor failed,
而U盘之所以能正常是因为第一次读取端点0数据返回wMaxPacketSize = 64, 实际赋值 18 = (18> 64)? 64:18,即send_size = 18,
因此能正常读回完整的设备描述符. 通过读读取全部设备描述符时增加测试debug_dat代码人为更改send_size = 18, 可以读取
全部设备描述符了.,

官方的USB HOST U盘程序 只能枚举wMaxPacketSize > 18字节的,小于的话,像鼠标类8字节会枚举失败。:)

  1. if(debug_dat)
  2. {
  3. send_size = 18;
  4. }
  5. int rt_usb_hcd_pipe_xfer(uhcd_t hcd, upipe_t pipe, void* buffer, int nbytes, int timeout)
  6. {
  7. rt_size_t remain_size;
  8. rt_size_t send_size;
  9. remain_size = nbytes;
  10. rt_uint8_t * pbuffer = (rt_uint8_t *)buffer;
  11. do
  12. {
  13. RT_DEBUG_LOG(RT_DEBUG_USB,("pipe transform remain size,: %d\n", remain_size));
  14. send_size = (remain_size > pipe->ep.wMaxPacketSize) ? pipe->ep.wMaxPacketSize : remain_size;
  15. RT_DEBUG_LOG(RT_DEBUG_USB,("pipe->ep.wMaxPacketSize = %d\r\n", pipe->ep.wMaxPacketSize));
  16. RT_DEBUG_LOG(RT_DEBUG_USB,("send_size = %d\r\n", send_size));
  17. if(debug_dat)
  18. {
  19. send_size = 18;
  20. }
  21. if(hcd->ops->pipe_xfer(pipe, USBH_PID_DATA, pbuffer, send_size, timeout) == send_size)
  22. {
  23. remain_size -= send_size;
  24. pbuffer += send_size;
  25. }
  26. else
  27. {
  28. return 0;
  29. }
  30. }while(remain_size > 0);
  31. return nbytes;
  32. }

发布于4年前

  1. rt_err_t rt_usbh_attatch_instance(uinst_t device)
  2. {
  3. int i = 0;
  4. rt_err_t ret = RT_EOK;
  5. struct uconfig_descriptor cfg_desc;
  6. udev_desc_t dev_desc;
  7. uintf_desc_t intf_desc;
  8. uep_desc_t ep_desc;
  9. rt_uint8_t ep_index;
  10. upipe_t pipe;
  11. ucd_t drv;
  12. RT_ASSERT(device != RT_NULL);
  13. rt_memset(&cfg_desc, 0, sizeof(struct uconfig_descriptor));
  14. dev_desc = &device->dev_desc;
  15. /* alloc address 0 ep0 pipe*/
  16. ep0_out_desc.wMaxPacketSize = 8;
  17. ep0_in_desc.wMaxPacketSize = 8;
  18. rt_usb_hcd_alloc_pipe(device->hcd, &device->pipe_ep0_out, device, &ep0_out_desc);
  19. rt_usb_hcd_alloc_pipe(device->hcd, &device->pipe_ep0_in, device, &ep0_in_desc);
  20. RT_DEBUG_LOG(RT_DEBUG_USB, ("start enumnation\n"));
  21. /* get device descriptor head */
  22. ret = rt_usbh_get_descriptor(device, USB_DESC_TYPE_DEVICE, (void*)dev_desc, 8);
  23. if(ret != RT_EOK)
  24. {
  25. rt_kprintf("get device descriptor head failed\n");
  26. return ret;
  27. }
  28. /* reset bus */
  29. rt_usbh_hub_reset_port(device->parent_hub, device->port);
  30. rt_thread_delay(2);
  31. rt_usbh_hub_clear_port_feature(device->parent_hub, i + 1, PORT_FEAT_C_CONNECTION);
  32. /* set device address */
  33. ret = rt_usbh_set_address(device);
  34. if(ret != RT_EOK)
  35. {
  36. rt_kprintf("set device address failed\n");
  37. return ret;
  38. }
  39. /* free address 0 ep0 pipe*/
  40. rt_usb_hcd_free_pipe(device->hcd,device->pipe_ep0_out);
  41. rt_usb_hcd_free_pipe(device->hcd,device->pipe_ep0_in);
  42. /* set device max packet size */
  43. ep0_out_desc.wMaxPacketSize = device->dev_desc.bMaxPacketSize0;
  44. ep0_in_desc.wMaxPacketSize = device->dev_desc.bMaxPacketSize0;
  45. /* alloc true address ep0 pipe*/
  46. rt_usb_hcd_alloc_pipe(device->hcd, &device->pipe_ep0_out, device, &ep0_out_desc);
  47. rt_usb_hcd_alloc_pipe(device->hcd, &device->pipe_ep0_in, device, &ep0_in_desc);
  48. RT_DEBUG_LOG(RT_DEBUG_USB, ("get device descriptor length %d\n",
  49. dev_desc->bLength));
  50. /* get full device descriptor again */
  51. ret = rt_usbh_get_descriptor(device, USB_DESC_TYPE_DEVICE, (void*)dev_desc, dev_desc->bLength);
  52. if(ret != RT_EOK)
  53. {
  54. rt_kprintf("get full device descriptor failed\n");
  55. return ret;
  56. }
  57. RT_DEBUG_LOG(RT_DEBUG_USB, ("Vendor ID 0x%x\n", dev_desc->idVendor));
  58. RT_DEBUG_LOG(RT_DEBUG_USB, ("Product ID 0x%x\n", dev_desc->idProduct));
  59. /* get configuration descriptor head */
  60. ret = rt_usbh_get_descriptor(device, USB_DESC_TYPE_CONFIGURATION, &cfg_desc, 18);
  61. if(ret != RT_EOK)
  62. {
  63. rt_kprintf("get configuration descriptor head failed\n");
  64. return ret;
  65. }
  66. /* alloc memory for configuration descriptor */
  67. device->cfg_desc = (ucfg_desc_t)rt_malloc(cfg_desc.wTotalLength);
  68. rt_memset(device->cfg_desc, 0, cfg_desc.wTotalLength);
  69. /* get full configuration descriptor */
  70. ret = rt_usbh_get_descriptor(device, USB_DESC_TYPE_CONFIGURATION,
  71. device->cfg_desc, cfg_desc.wTotalLength);
  72. if(ret != RT_EOK)
  73. {
  74. rt_kprintf("get full configuration descriptor failed\n");
  75. return ret;
  76. }
  77. /* set configuration */
  78. ret = rt_usbh_set_configure(device, 1);
  79. if(ret != RT_EOK)
  80. {
  81. return ret;
  82. }
  83. for(i=0; i<device->cfg_desc->bNumInterfaces; i++)
  84. {
  85. /* get interface descriptor through configuration descriptor */
  86. ret = rt_usbh_get_interface_descriptor(device->cfg_desc, i, &intf_desc);
  87. if(ret != RT_EOK)
  88. {
  89. rt_kprintf("rt_usb_get_interface_descriptor error\n");
  90. return -RT_ERROR;
  91. }
  92. RT_DEBUG_LOG(RT_DEBUG_USB, ("interface class 0x%x, subclass 0x%x\n",
  93. intf_desc->bInterfaceClass,
  94. intf_desc->bInterfaceSubClass));
  95. /* alloc pipe*/
  96. for(ep_index = 0; ep_index < intf_desc->bNumEndpoints; ep_index++)
  97. {
  98. rt_usbh_get_endpoint_descriptor(intf_desc, ep_index, &ep_desc);
  99. if(ep_desc != RT_NULL)
  100. {
  101. if(rt_usb_hcd_alloc_pipe(device->hcd, &pipe, device, ep_desc) != RT_EOK)
  102. {
  103. rt_kprintf("alloc pipe failed\n");
  104. return RT_ERROR;
  105. }
  106. rt_usb_instance_add_pipe(device,pipe);
  107. }
  108. else
  109. {
  110. rt_kprintf("get endpoint desc failed\n");
  111. return RT_ERROR;
  112. }
  113. }
  114. /* find driver by class code found in interface descriptor */
  115. drv = rt_usbh_class_driver_find(intf_desc->bInterfaceClass,
  116. intf_desc->bInterfaceSubClass);
  117. if(drv != RT_NULL)
  118. {
  119. /* allocate memory for interface device */
  120. device->intf[i] = (struct uhintf*)rt_malloc(sizeof(struct uhintf));
  121. device->intf[i]->drv = drv;
  122. device->intf[i]->device = device;
  123. device->intf[i]->intf_desc = intf_desc;
  124. device->intf[i]->user_data = RT_NULL;
  125. /* open usb class driver */
  126. ret = rt_usbh_class_driver_enable(drv, (void*)device->intf[i]);
  127. if(ret != RT_EOK)
  128. {
  129. rt_kprintf("interface %d run class driver error\n", i);
  130. }
  131. }
  132. else
  133. {
  134. rt_kprintf("find usb device driver failed\n");
  135. continue;
  136. }
  137. }
  138. return RT_EOK;
  139. }

回到
顶部

发布
问题

投诉
建议