This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] RTOS:EK-TM4C1294XL、UART 线程不工作

Guru**** 2466550 points
Other Parts Discussed in Thread: SYSBIOS

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/666160/rtos-ek-tm4c1294xl-uart-thread-not-working

Thread 中讨论的其他器件:SYSBIOS

工具/软件:TI-RTOS

您好!


我在 TM4C1294XL 上有一个 RTOS 项目、该项目当前用于接收数据并将其传输到外部传感器上的 UART。  只有一个线程在这个项目上运行:一个定时器模块、此模块的 ISR 是 UART 接收/发送函数。  没有其他事情发生。  CPU 设置为40MHz、定时器模块每500、000微秒或每0.5秒调用一次。  似乎每次都有不同的错误、但最近的错误是:ti.sysbios.gates.gateMutex:第99行:断言失败:a_badContext:调用上下文错误。 有关详细信息、请参阅 GateMutex API 文档。
xdc.runtime.Error.raise:终止执行


我已经看到其他线程询问了这个错误、解决方案是将线程更改为具有信标挂起的任务。  但我真的不想这么做。  我只想让计时器模块来完成它的任务。  当这是系统中的唯一线程时、我不知道为什么我需要使用信标阻止任何内容。  代码如下。

///--------------------------------
// BIOS 头文件
//---------------
#include //mand强制-对于 BIOS 类型
#include、必须首先包含 //mandedis-如果您调用诸如 BIOS_start()
#include 之类的 API //needed 用于任何 Log_info()调用
#include 用于静态定义的对象/句柄
#include 的//头文件 


///----------------------
// TivaWare 头文件
//---------------
#include 
#include 
#include "inc/hw_types.h"
#include "lib/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "inc/hw_ints.h"
#include "driverlib/interrupt.h"
#include "driverlib/timer.h"#include--"drivermap-/nuart.h"





//定义
//---------------

#define UART2_AUDRATE 9600//---------------


//原型
///----------------
void hardware_init (void);
void UART_exchange (void);


//-------------------
//全局
//---------------

//包含“读取 CO2浓度”命令的阵列。 这将从
//目标 UART 发送到 CO2传感器 UART,以发出我们希望传感器发送//
其当前 CO2读数的信号。
uint8_t read_Bytes[9]={0xFF、0x01、0x86、0x00、0x00、 0x00、0x00、0x00、0x79};

//包含传感器 Tx 响应的阵列。
uint8_t RESPONSE_Bytes[9]={0x00、0x00、0x00、0x00、0x00、 0x00,0x00,0x00,0x00};

//保留 CO2浓度计算值
uint32_t CO2_value = 0;

//当前时钟速率
uint32_t sys_clock = 40000000;

//-----
// main()//-----------------

void main (void)

{
hardware_init (); //通过 TIVAware
BIOS_start()初始化硬件;

}


void hardware_init (void)
{

//将 CPU 时钟设置为40MHz。 400MHz PLL/2 = 200 DIV 5 = 40MHz
//SysCtlClockSet (SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHz|SYSCTL_OSC_MAIN);

SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);
SysCtlPeripheralEnable (SYSCTL_Periph_UART2);
GPIOPinConfigure (GPIO_PA6_U2RX);
GPIOPinConfigure (GPIO_PA7_U2TX);
GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_6 | GPIO_PIN_7);

UARTEnable (UART2_base);
UARTConfigSetExpClk (UART2_base、sys_clock、UART2_BAUDRATE、(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));

}


//---
// uart_exchange ()
//
//将命令发送到 Sensor Rx,等待响应,将响应//存储
在 RESPONSE_BYTES[9]数组中。
///-------------------------------------------------------
void UART_exchange (void)
{
TimerIntClear (TIMER2_base、TIMER_TINA_TIMEOUT); //必须清除计时器的计时器标志

uint32_t w、x = 0;

对于(w = 0;w < 9;w++)
{
UARTCharPut (UART2_base、read_Bytes[w]);
}

while (UARTBusy (UART2_base))
{
//在此处旋转,直到 UART 完成发送
}

System_printf ("UART 已完成传输。\n"\});

//获取接收 FIFO 中的字节

while (UARTCharsAvail (UART2_base))
{
RESPONSE_Bytes[x]= UARTCharGet (UART2_base);
X++;
}

System_printf ("UART 已完成接收。 \n");


CO2_value = RESPONSE_BYTE[2]*256 + RESPONSE_BYTE[3];

system_printf ("CO2 value in ppm is:");
System_printf ("%d \n"、CO2_value);

}



  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Rodney、

    如何设置 UART 中断以及中断的功能是什么? 您是否不想在 TI-RTOS 中使用 UART 驱动程序(例如、查看 UART 回波示例)。

    Todd

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    很抱歉耽误您的回答。

    我这样做的原因是、虽然 UART Echo 示例似乎可以即插即用、用于与 PuTTY (使用 UART0)进行通信、 使用 UART1或任何其他 UART 与外部器件通信需要编辑数量似乎无限的头文件和库。 我不是很清楚要进行哪些更改。 这使得这一过程更加困难和耗时。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Rodney、

    合理的反馈。 您如何在应用程序中设置中断?

    如果不使用 UART0、则只能将 EK_TM4C1294XL.c 文件添加到 uartTivaHWAttrs 和 EK_TM4C1294XL_initUART 中的 pinmux UART1、而不是 UART0。 然后仍然使用 Board_UART0。 或将 Board_UART0更改为 Board_UART1 (在 Board.h 中)、并将 EK_TM4C1294XL_UART0更改为 EK_TM4C1294XL_UART1 (在 EK_TM4C1294XL.h 中)以实现完整性。

    Todd
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Todd、

    该中断由 RTOS 定时器模块触发。 一旦这个定时器递减计数(每0.5秒)、"UART_EXCHANGE"就是被调用的 ISR。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Rodney、

    当您尝试输入一个 GateMutex (基本上是一个信标)时、调用该断言。 您不能在 Hwi 或 Swi 的上下文中执行此操作。 如果你在 SYS/BIOS 管理的定时器中调用你的函数、它将在 Hwi 上下文中执行。 根据您在.cfg 中设置系统提供程序的方式、System_printf 可能会调用 GateMutx_enter (因为 GateMutex 已插入 RTS 库...假设您使用的是 TI 编译器)。 有几种方法可以解决此问题、但最简单的方法可能是注释掉 UART_EXCHANGE 中的 System_printf 函数或更改为
    VAR SysCallback = xdc.useModule('xdc.runtime.SysCallback');
    System.SupportProxy = SysCallback;
    文件中。 这会插入基本上为空的系统提供商。

    注:如果您不使用内核管理的计时器中断、您可能也会获得此信息。 如果使用时钟模块或使用 Timer_create (或 Timer_con构)、则没关系。 非托管中断无法调用内核 API。

    Todd
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Todd、

    这确实解决了我的错误、因此非常感谢。 但是、我希望我的调试工具不必如此有限。