【问题标题】:STM32F412 using FreeRTOS and USB to do audio processingSTM32F412使用FreeRTOS和USB做音频处理
【发布时间】:2018-01-06 19:39:26
【问题描述】:

我正在使用 stm32f4 核板。我可以在没有 FreeRTOS 的情况下通过 USB 将音频数据传输到 PC。现在我想学习如何将 FreeRTOS 和 USB 集成在一起。但我对线程和 ISR 如何从根本上相互交互有一些疑问。
下面我有两个文件。

在 main.c 中,创建了两个线程。
在 usb_thread 中,我初始化了 usb dirver,没有做任何其他事情。
在 vr_thread 中,它等待 state == 1 并处理 PCM_Buffer。

/* main.c */
extern uint16_t PCM_Buffer[16];
int state = 0;

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();

  osThreadDef(usb_t, usb_thread, osPriorityNormal, 0, configMINIMAL_STACK_SIZE);
  osThreadDef(vr_t, vr_thread, osPriorityNormal, 0, configMINIMAL_STACK_SIZE);
  usb_thread_handle = osThreadCreate (osThread(usb_t), NULL);
  usb_thread_handle = osThreadCreate (osThread(vr_t), NULL);
  osKernelStart();

  for (;;) {}
}

static void usb_thread(void const *argument)
{       
  /*Do some initialization here.*/

  for (;;) {}
}

static void vr_thread(void const *argument)
{
  /*Do some initialization here.*/

  for (;;) {
    if (state == 1) {
      state = 0;
      process_buffer(PCM_Buffer);
    }
  }
}

在 app.c 中,USB_AUDIO_CallBack 将被 USB ISR 每 1 毫秒调用一次。它首先将 PCM_Buffer 传输到 PC,因为它非常重要,然后将状态更改为 1。

/* app.c */
uint16_t PCM_Buffer[16];
extern int state;

void USB_AUDIO_CallBack(void) //It will be called by usb ISR every 10^-3 second.
{
  Send_Audio_to_USB((int16_t *)(PCM_Buffer), NUM_AUDIO_BUF);
  state = 1;

}

这是我的问题。
1、如何查看FreeRTOS的单位计数滴答? USB_AUDIO_CallBack 将是 每 1 毫秒调用一次,如何知道 FreeRTOS 基本滴答声是快还是慢 超过 1 毫秒。 FreeRTOS tick 是否等于 systick?
2、假设process_buffer的处理时间小于1毫秒。我想在这里完成的描述如下

  hardware trigger
  |
  usb ISR
  |
  USB_AUDIO_CallBack
  |
  state=1
  |
  vr_thread process_buffer
  |
  state=0, then wait for hardware trigger again.

我真的怀疑这是正确的方法。还是应该使用suspend() 和resume()?
3. 使用 extern 声明全局 PCM_Buffer 是在线程之间传递变量的正确方法还是应该在 FreeRTOS 中使用队列?
我知道这些问题是微不足道的,但我真的很想了解它们。欢迎任何有用的文档或网站。谢谢。

【问题讨论】:

    标签: usb interrupt stm32 freertos


    【解决方案1】:
    1. 要将实时转换为 systick,您可以使用宏 pdMS_TO_TICKS(xTimeInMS)
    2. 您也可以将USB_AUDIO_CallBack 定义为线程(或任务)或将回调中的代码粘贴到vr_thread(因为您的应用程序仅在一个处理器上工作)。然后在 USB ISR 中,您可以使用函数vTaskNotifyGiveFromISR 发送通知,并通过调用ulTaskNotifyTakevr_thread 中接收通知。收到通知后可以拨打Send_Audio_to_USB((int16_t *)(PCM_Buffer), NUM_AUDIO_BUF);
      然后process_buffer(PCM_Buffer);。最好将代码从回调带出到任务,因为 ISR 处理程序将更快地完成它的工作,因为Send_Audio_to_USB 函数可能会运行很长时间。您还可以让事情按照您需要的顺序执行。
    3. 我认为您的意思是volatile 而不是extern。如果您想在不同的线程和 ISR 中使用此缓冲区,则应将其定义为 volatile,但如果您将只使用一个任务的方法,则可以将此缓冲区声明为本地缓冲区。

    【讨论】:

    • 您好,感谢您的回复,但目前我正忙于其他任务,无法尝试此操作。我会尽快尝试。
    猜你喜欢
    • 2011-07-09
    • 1970-01-01
    • 2019-10-23
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多