59 lines
2.7 KiB
Python
59 lines
2.7 KiB
Python
from pathlib import Path
|
|
import re, subprocess, tempfile
|
|
src=(Path(__file__).resolve().parents[1]/'components/platform/src/lcd_direct.c').read_text()
|
|
def extract(name):
|
|
m=re.search(r'static [^;{}]+\b'+name+r'\([^;{}]*\)\s*\{',src)
|
|
a=m.start();b=src.index('{',a)+1;depth=1
|
|
while depth:
|
|
if src[b]=='{':depth+=1
|
|
if src[b]=='}':depth-=1
|
|
b+=1
|
|
return src[a:b]
|
|
prefix='''#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
#include <assert.h>
|
|
#include <stdio.h>
|
|
#define ESP_OK 0
|
|
#define ESP_ERR_INVALID_STATE 1
|
|
#define LCD_DIRECT_EMOTE_STEP_MS 34U
|
|
#define LCD_DIRECT_PRESENTATION_WAIT_POLL_MS 20U
|
|
#define pdMS_TO_TICKS(x) ((x)/10)
|
|
#define ESP_RETURN_ON_ERROR(expr,...) do {int e=(expr);if(e)return e;}while(0)
|
|
typedef int esp_err_t;
|
|
typedef uint32_t TickType_t;
|
|
static int s_emote_handle, delays, stop_after, locks, unlocks;
|
|
static bool stop;
|
|
static int64_t now;
|
|
static int64_t esp_timer_get_time(void){return now;}
|
|
static bool lcd_direct_should_stop_idle(void){return stop;}
|
|
static int gfx_emote_lock(int h){++locks;return 0;}
|
|
static int gfx_emote_unlock(int h){++unlocks;return 0;}
|
|
static int lcd_direct_emote_update_hud(bool force,bool *changed){*changed=false;return 0;}
|
|
static int lcd_direct_emote_refresh(void){return 0;}
|
|
static void vTaskDelay(TickType_t ticks){assert(ticks>0);now+=ticks*10000;++delays;if(stop_after && delays>=stop_after)stop=true;}
|
|
'''
|
|
test='''int main(void){
|
|
for(size_t i=0;i<12;++i){
|
|
assert(lcd_direct_emote_step_deadline(123000,i)==123000+(int64_t)(i+1)*34000);
|
|
now+=13000;
|
|
assert(lcd_direct_emote_wait_until(lcd_direct_emote_step_deadline(0,i))==0);
|
|
assert(now>=(int64_t)(i+1)*34000 && now<(int64_t)(i+1)*34000+10000);
|
|
}
|
|
int64_t anchored=now;
|
|
now=0;
|
|
for(size_t i=0;i<12;++i){now+=13000;assert(lcd_direct_emote_wait(21)==0);}
|
|
assert(anchored<418000 && now>=480000);
|
|
now=200000;int before=delays;
|
|
assert(lcd_direct_emote_wait_until(100000)==0 && now==200000 && delays==before);
|
|
stop=true;assert(lcd_direct_emote_wait_until(100000)==1);
|
|
stop=false;stop_after=delays+1;assert(lcd_direct_emote_wait_until(now+100000)==1);
|
|
assert(locks==unlocks);
|
|
printf("PASS: fixed deadlines, 10ms tick drift reduction (anchored=%lldus), late/stop handling and paired HUD locks\\n",(long long)anchored);
|
|
}'''
|
|
with tempfile.TemporaryDirectory(prefix='emote-timeline-') as tmp:
|
|
c=Path(tmp)/'test.c';exe=Path(tmp)/'test'
|
|
c.write_text(prefix+'\n'.join(extract(n) for n in ['lcd_direct_emote_wait_until','lcd_direct_emote_wait','lcd_direct_emote_step_deadline'])+'\n'+test)
|
|
subprocess.run(['clang','-std=c11','-fsanitize=address,undefined',str(c),'-o',str(exe)],check=True)
|
|
subprocess.run([str(exe)],check=True)
|