新增:FPGA 升级后热恢复射频链路

This commit is contained in:
2026-08-28 13:26:45 +08:00
parent 47b782e976
commit 33d8f4f428
7 changed files with 257 additions and 93 deletions
+7 -4
View File
@@ -101,10 +101,13 @@ all: imx_atsc_app
rm -rf ~/nfs/imx_atsc_app
cp imx_atsc_app ~/nfs/
install: all
cp imx_atsc_app ../../out/upgrade_imx_fs/SMOD/src/aw/anywave/app/
cp imx_atsc_app ../../out/rootfs/aw/anywave/app/
@echo "\n\n\t ATSC_APP intall ok\n\n"
install: all
cp imx_atsc_app ../../out/upgrade_imx_fs/SMOD/src/aw/anywave/app/
cp imx_atsc_app ../../out/rootfs/aw/anywave/app/
cp runme.sh ../../out/upgrade_imx_fs/SMOD/runme.sh
cp anywave_exc_start.sh ../../out/upgrade_imx_fs/SMOD/src/aw/anywave_exc_start.sh
cp anywave_exc_start.sh ../../out/rootfs/aw/anywave_exc_start.sh
@echo "\n\n\t ATSC_APP intall ok\n\n"
clean:
rm -rf *.o ./imx_atsc_app
+88
View File
@@ -0,0 +1,88 @@
#!/bin/sh
# The upgrade shell is forked by the running app and inherits every app socket.
# Re-exec after closing inherited non-stdio descriptors so the old process can
# release its ports cleanly. Keep upgrade diagnostics on the debug serial port.
if [ "$SMOD_FD_CLEAN" != "1" ]; then
export SMOD_FD_CLEAN=1
exec /bin/sh -c '
i=3
while [ $i -lt 256 ]; do
eval "exec ${i}>&-" 2>/dev/null
i=$((i + 1))
done
exec /bin/sh "$1" </dev/null >/dev/ttymxc0 2>&1
' smod_fd_clean "$0"
fi
# Kernel and device-tree updates only take effect after an IMX reboot. Pure
# userspace packages keep the clock/RF hardware powered and restart only the
# application so RF can recover without a power cycle.
need_reboot=0
reboot_reason=""
if [ -f ./src/zImage ]; then
need_reboot=1
reboot_reason="kernel"
echo "kernel image found: reboot required"
fi
if [ -f ./src/imx6ull-S-gpmi-1024x600c7.dtb ]; then
need_reboot=1
if [ -n "$reboot_reason" ]; then
reboot_reason="$reboot_reason+device-tree"
else
reboot_reason="device-tree"
fi
echo "device-tree image found: reboot required"
fi
killall logrotateStart daemon_system 2>/dev/null
sh remove.sh
sh cp.sh
sync
sleep 2
if [ "$need_reboot" = "1" ]; then
echo "boot component updated ($reboot_reason), reboot IMX now"
reboot
exit 0
fi
# pthread_setname_np changes the app's /proc comm, so identify it by the exact
# executable path. Also match "(deleted)" after cp.sh replaces the running ELF.
find_app_pids()
{
for exe in /proc/[0-9]*/exe; do
target=`readlink "$exe" 2>/dev/null` || continue
case "$target" in
/aw/anywave/app/imx_atsc_app|/aw/anywave/app/imx_atsc_app\ \(deleted\))
echo "$exe" | sed 's#/proc/##;s#/exe##'
;;
esac
done
}
old_pids=`find_app_pids`
[ -n "$old_pids" ] && kill $old_pids 2>/dev/null
i=0
while [ -n "`find_app_pids`" ] && [ $i -lt 15 ]; do
sleep 1
i=$((i + 1))
done
old_pids=`find_app_pids`
[ -n "$old_pids" ] && kill -9 $old_pids 2>/dev/null
while [ -n "`find_app_pids`" ]; do sleep 1; done
# Remove stale logging pipelines only after the old application has exited.
killall loglog 2>/dev/null
# Start without the legacy argument 1 so the normal no-power-off RF recovery
# path rebuilds the TALISE handle and FPGA-side JESD link.
sleep 2
cd /aw/anywave/app && nohup sh -c './imx_atsc_app 2>&1 | /usr/sbin/loglog /var/module_log/ imx_atsc_app.log 1' </dev/null >/dev/ttymxc0 2>&1 &
# Restore the system watchdog/housekeeper and log rotation. BusyBox on this
# target has no setsid, and /usr/sbin is not in the default PATH.
sleep 2
nohup sh -c '/usr/sbin/daemon_system 2>&1 | /usr/sbin/loglog /var/module_log/ daemon_system.log 1' >/dev/null 2>&1 &
nohup sh -c '/usr/sbin/logrotateStart 2>&1 | /usr/sbin/loglog /var/module_log/ logrotateStart.log 0' >/dev/null 2>&1 &
+8 -10
View File
@@ -1055,15 +1055,14 @@ void http_write_sys(S_CGI_SET *ppara)
}
if(ppara->sys_reset) {
log_printf(LOG_DEBUG, I_USER_CFG, "SYSTEM RESET NOW (IMX+FPGA)!!!!!!!!!!!!!\n");
//复位 FPGA本身复位
fpga_byte_write(0x01,0xfe,0x5a);
fpga_byte_write(0x01,0xfe,0xa5);
// [one@20220419 add imx reset]
system("sync");
system("reboot");
}
/* A Web System Reset is an IMX warm reboot. Keep FPGA, AD9528 and
* ADRV9009 powered so the normal boot path can preserve the RF link. */
log_printf(LOG_DEBUG, I_USER_CFG,
"WEB SYSTEM RESET NOW (IMX warm reboot, keep RF hardware)\n");
system("sync");
system("reboot");
return;
}
}
@@ -1624,4 +1623,3 @@ void http_save_change_para(void *p)
/*****************************END**************************************/
+4 -1
View File
@@ -1576,8 +1576,8 @@ int get_tsoip_systs1(char *pbuf, short bufMaxLen)
((pnet->udp_rtp&0xff)<<16)|((pnet->packet_len&0xff)<<8)|(pnet->receive_type&0xff),
pnet->fec,
pnet->delay,
pnet->col,
pnet->row,
pnet->col,
pnet->dest_ip[0],
(pnet->dest_ip[1]<<16)|(pnet->dest_ip[2]<<8)|pnet->dest_ip[3],
pnet->dest_port,
@@ -1777,6 +1777,9 @@ int start_fpga_upgrade(char *value,short maxlen)
return 0;
}
log_printf(LOG_INFO, I_USER_CFG, "get FPGA .mcs upgrade cmd from web.\n");
/* Clear the previous request's terminal status before the asynchronous
* imx_up_thr starts. Otherwise the web poll can consume a stale DONE. */
fpga_up_write_status("PENDING", 0, 0);
set_fpga_up_flg(1);
return 0;
}
+4 -4
View File
@@ -863,7 +863,7 @@ static uint32 fpga_upgrade_process(void)
#define FPGA_UP_STATUS_PATH "/tmp/fpga_up_status"
/* Publish flash progress for the web page: one line "<PHASE> <PCT> <RET>".
* PHASE: PENDING|ERASE|WRITE|DONE|ERROR ; fpga_up_status.cgi serves this file. */
* PHASE: PENDING|ERASE|WRITE|RELINK|READY|ERROR ; fpga_up_status.cgi serves this file. */
void fpga_up_write_status(const char *phase, int pct, int ret)
{
FILE *sf = fopen(FPGA_UP_STATUS_PATH, "w");
@@ -990,7 +990,7 @@ int fpga_upgrade_from_file(const char *path)
delay_ms(200);
}
g_now_only_upgrade_fpga = 0;
if(ret == 0) fpga_up_write_status("DONE", 100, 0);
if(ret == 0) fpga_up_write_status("RELINK", 100, 0);
else fpga_up_write_status("ERROR", last_pct < 0 ? 0 : last_pct, ret);
log_printf(LOG_DEBUG, I_NOUSED, "fpga upgrade: finished ret=%d lines=%d\n", ret, upState.lineCnt);
return ret;
@@ -2174,8 +2174,8 @@ void check_fpga_up_finished_reboot_sys(void)
fpga_up_sys_reboot=0;
sec_cnt=0;
/* PR10: the FPGA update image was already IPROG-loaded by reset_fpga_system() in
* check_fpga_upgrade_done(). The old reset_imx_system() reboot is a no-op on this
* board (Task10: no HW soft-reboot path). Instead re-establish RF in-place: reconfig
* check_fpga_upgrade_done(). An IMX reboot is unnecessary for an FPGA-only update.
* Re-establish RF in-place: reconfig
* the FPGA + re-handshake the JESD link (skip 9009, which stayed powered) + reload the
* DPD HOLD curve. This makes a web FPGA .mcs upgrade self-recover WITHOUT a power cycle. */
extern void hot_reinit_rf(int reload_fpga);
+14 -5
View File
@@ -59,6 +59,7 @@ extern int g_trigger_up_start_flg;
static volatile int g_hot_relink_busy = 0; /* re-entrancy guard: only one relink at a time
* (the upgrade-completion path and the runtime
* cfg_valid poll can both request one). */
static volatile int g_fpga_upgrade_relink_pending = 0; /* web upgrade waits for RF relink */
void hot_reinit_rf(int reload_fpga)
{
extern uint8 hot_get_adpc_mode(void);
@@ -70,6 +71,8 @@ void hot_reinit_rf(int reload_fpga)
return;
}
g_hot_relink_busy = 1;
if(g_fpga_upgrade_relink_pending)
fpga_up_write_status("RELINK", 100, 0);
prev_adpc = hot_get_adpc_mode(); /* capture DPD mode BEFORE force-stop wipes it */
log_printf(LOG_INFO, I_USER_CFG, "[HOT-RESTART] begin (reload_fpga=%d, jesd-relink, skip TALISE, prev_adpc=%d)\n", reload_fpga, prev_adpc);
@@ -105,6 +108,10 @@ void hot_reinit_rf(int reload_fpga)
hot_dpd_rearm(prev_adpc);
}
log_printf(LOG_INFO, I_USER_CFG, "[HOT-RESTART] done\n");
if(g_fpga_upgrade_relink_pending){
fpga_up_write_status("READY", 100, 0);
g_fpga_upgrade_relink_pending = 0;
}
g_hot_relink_busy = 0;
}
@@ -125,10 +132,9 @@ void sys_upgrade(void)
result = atoi(msg);
//usleep(1000000);
if(result == 0){
log_printf(LOG_DEBUG,I_NOUSED,"run upgrade sh, and will reboot\n");
log_printf(LOG_DEBUG,I_NOUSED,"run upgrade sh (kernel/DTB -> reboot, userspace-only -> app restart)\n");
system(DO_UPGRADE_RUN);
log_printf(LOG_DEBUG,I_NOUSED,"system rebooting....\n");
// reboot in runme.sh
log_printf(LOG_DEBUG,I_NOUSED,"upgrade script started restart/reboot flow\n");
}
}
}
@@ -165,8 +171,11 @@ void* imx_up_thr(void * args)
atsc_adpc_force_stop_flag = TRUE;
usleep(2000000);
int fret = fpga_upgrade_from_file(FPGA_UP_MCS_PATH);
log_printf(LOG_DEBUG,I_NOUSED,"FPGA upgrade result=%d (0=ok, app will reset+reboot)\n", fret);
/* success path: check_fpga_upgrade_done() set fpga_up_sys_reboot=1 -> imx6 reboots */
if(fret == 0)
g_fpga_upgrade_relink_pending = 1;
log_printf(LOG_DEBUG,I_NOUSED,"FPGA upgrade result=%d (0=ok, app will hot-relink RF)\n", fret);
/* Success path uses fpga_up_sys_reboot as a legacy delayed-work flag;
* check_fpga_up_finished_reboot_sys() now performs an in-place RF relink. */
}
/* test hook: `touch /tmp/hot_restart_now` (or `echo 1 > ...` for reload_fpga) triggers