嵌入式 C 在将全局变量复制到临界区的堆栈变量时避免优化

问题描述 投票:0回答:1

我正在研究我们的软件组件中的 RTOS 支持。

在某些情况下,将全局变量的副本创建为关键部分中的局部变量(例如受互斥锁保护)是有意义的,然后在关键部分之外的耗时操作中进一步使用本地副本。

我担心C编译器可能会优化局部变量赋值并直接使用全局变量,这会破坏消除代码中竞争条件的努力。

我写了一个过于简化的 LCD 显示示例代码来说明问题。

我有以下问题:

  • 如何保证局部变量不被优化?
  • 如何保证加锁-解锁和复制的顺序按预期发生?
  • 在这种情况下,易失性类型限定符有帮助吗(局部变量)?
uint8_t page_sel = 0;
char lcd_text[PAGE_CNT][ROW_CNT][COLUMN_CNT];

void lcd_print_text(uint8_t page, uint8_t row, const char* text)
{
  lock();
  // Store text in global variable which represents
  // the text on the display
  copy_text_to_lcd_text(page, row, text);
  unlock();

  // Display update request to run the lcd background task
  refresh_semaphore_set();
}

void lcd_select_page(uint8_t page)
{
  lock();
  // Store the selected page
  page_sel = page;
  unlock();

  // Display update request to run the lcd background task
  // If the selected page changes then lcd shall be updated
  refresh_semaphore_set();
}

void lcd_task(void)
{
  while(1) {
    // Update the display only if there are modifications
    refresh_semaphore_get();
    refresh();
  }
}

void refresh(void)
{ 
  char page_lcd_text[ROW_CNT][COLUMN_CNT]
  uint8_t page;

  lock();
  // Page number and text shall be consistent
  // so critical section is necessary
  page = page_sel;
  // Copy is created to avoid partial overwrites during
  // display update
  copy_page(page_lcd_text, lcd_text, page);
  // It is essential to have a local copy before
  // the critical section is left
  unlock();
  
  // Create pixel data in frame buffer from text (slow)
  render_text(page_lcd_text);

  // Create pixel data in frame buffer to display (slow)
  // selected page number on display
  render_page_num(page);

  // Transfer pixel data to LCD driver chip (even slower)
  lcd_spi_transfer();
}
c optimization mutex compiler-optimization rtos
1个回答
0
投票

如果它总是被写入,而不是被优化掉,您应该使用

volatile
关键字。它允许您始终写入变量,而无需优化任何内容。 C 语言中为什么需要 volatile?

就像该线程中提到的那样,易失性也用于跨线程写入局部变量,因此它应该按预期工作。为了确保这种情况发生,您可以使用compiler explorer等工具来留意写入您的值。

© www.soinside.com 2019 - 2024. All rights reserved.