调用期望const char8 string []作为参数的c函数的正确方法

时间:2019-05-08 17:58:20

标签: c pointers

在微控制器的ISR内,我试图按以下方式调用函数:

//adc.c
static volatile char uartBuf[6]={0};

CY_ISR(ISR_ADC)
{

for (uint8_t i=0; i < NS; i++)
  total += adc2_buffer0[i];

uartBuf[0] = total >> 24 & 0xFF;
uartBuf[1] = total >> 16 & 0xFF;
uartBuf[2] = total >> 8 & 0xFF;
uartBuf[3] = total & 0xFF; 
uartBuf[4] = '\n';
UART_1_PutString(uartBuf); //doesn't work
}

//uart.c
void UART_1_PutString(const char8 string[]) 
{
...
}

但是在函数UART_1_PutString中,字符串始终指向'\ 0'而不是uartBuf吗? 可能是什么问题呢?从理论上讲,变量uartBuf不应由编译器优化。

1 个答案:

答案 0 :(得分:1)

代码似乎正确

您是说string[0] == '\0'吗?

也许总是(total >> 24 & 0xFF) == 0(或大部分时间)。

编辑:

该功能应该是

void UART_1_PutString(const volatile unsigned char buff[]);

不应将其称为字符串,因为它不是文本,它只是一个缓冲区(至少看起来像它)。

unsigned,因为“字符串”来自一些数学运算后的无符号位操作,这可能会导致无效的有符号值(不太可能失败,但规则应为:char用于文本, unsigned char用于未知数据(其他所有数据)。

volatile,因为如果没有,您将丢弃volatile限定词。具有足够高的标志的编译器(在GCC:-Wall -Wextra -Werror中会突出显示几乎所有内容,因为错误)会警告您。编译器可能认为,即使在知道您将使用volatile数据调用该函数之前,该函数的内容也可以得到简化,因此可以优化一些不应该优化的内容。

如果没有其他函数同时访问该缓冲区,则还可以添加restrict关键字(C11),以便帮助编译器生成更好的代码:

void UART_1_PutString(const volatile unsigned char buff[restrict]);

EDIT2:

如果仅将要使用该缓冲区的缓冲区,则应声明该缓冲区的大小;否则,请将该缓冲区的大小传递给函数:

void UART_1_PutString(const volatile unsigned char buff[restrict 6]);

(6可能应该用某个宏代替)或

void UART_1_PutString(size_t size, const volatile unsigned char buff[restrict size]);