Code refactoring 6

This commit is contained in:
dreamsourcelabTAI 2022-08-01 10:40:29 +08:00
parent 092abdcc63
commit 2433d33b5b
9 changed files with 197 additions and 79 deletions

View File

@ -23,6 +23,9 @@
#include "config.h" /* Needed for HAVE_LIBUSB_1_0 and others. */
#include "log.h"
#undef LOG_PREFIX
#define LOG_PREFIX "backend: "
/**
* @mainpage libsigrok API
*
@ -83,8 +86,8 @@
* called, which will (among other things) free the struct sr_context.
*
* Example for a minimal program using libsigrok:
*
*/
/**
* Sanity-check all libsigrok drivers.
@ -331,12 +334,9 @@ SR_API int sr_init(struct sr_context **ctx)
context->libusb_ctx = NULL;
context->hotplug_handle = 0;
context->hotplug_callback = NULL;
context->hotplug_user_data = NULL;
context->hotplug_callback = NULL;
context->hotplug_tv.tv_sec = 0;
context->hotplug_tv.tv_usec = 0;
context->event_callback = NULL;
context->deiveList = NULL;
context->hotplug_tv.tv_usec = 0;
ret = libusb_init(&context->libusb_ctx);
if (LIBUSB_SUCCESS != ret) {
@ -386,7 +386,7 @@ LIBUSB_CALL int sr_hotplug_callback(struct libusb_context *ctx, struct libusb_de
libusb_hotplug_event event, void *user_data){
if (user_data == NULL){
sr_err("%s(): libsigrok usb event callback, userdata is NULL.", __func__);
sr_err("%s(): libsigrok usb event callback, userdata is NULL.", __func__);
return 0;
}
@ -398,13 +398,13 @@ LIBUSB_CALL int sr_hotplug_callback(struct libusb_context *ctx, struct libusb_de
struct sr_context *user_ctx = (struct sr_context*)user_data;
if (user_ctx->hotplug_callback != NULL){
user_ctx->hotplug_callback(ctx, dev, ev, user_ctx->hotplug_user_data);
user_ctx->hotplug_callback(ctx, dev, ev);
}
return 0;
}
SR_API int sr_listen_hotplug(struct sr_context *ctx, hotplug_event_callback callback, void *userdata)
SR_PRIV int sr_listen_hotplug(struct sr_context *ctx, hotplug_event_callback callback)
{
int ret;
@ -416,9 +416,9 @@ SR_API int sr_listen_hotplug(struct sr_context *ctx, hotplug_event_callback call
sr_err("%s(): callback was NULL.", __func__);
return SR_ERR;
}
sr_info("%s", "Register hotplug callback.");
ctx->hotplug_callback = callback;
ctx->hotplug_user_data = userdata;
ret = libusb_hotplug_register_callback(ctx->libusb_ctx,
(libusb_hotplug_event)(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT),
@ -427,7 +427,7 @@ SR_API int sr_listen_hotplug(struct sr_context *ctx, hotplug_event_callback call
LIBUSB_HOTPLUG_MATCH_ANY,
LIBUSB_HOTPLUG_MATCH_ANY,
(libusb_hotplug_callback_fn)sr_hotplug_callback,
ctx,
ctx, //user data
&ctx->hotplug_handle);
if (LIBUSB_SUCCESS != ret){
return -1;
@ -436,25 +436,25 @@ SR_API int sr_listen_hotplug(struct sr_context *ctx, hotplug_event_callback call
return 0;
}
SR_API int sr_close_hotplug(struct sr_context *ctx)
SR_PRIV int sr_close_hotplug(struct sr_context *ctx)
{
if (!ctx) {
sr_err("%s(): libsigrok context was NULL.", __func__);
return SR_ERR;
}
sr_info("%s", "Unregister hotplug callback.");
libusb_hotplug_deregister_callback(ctx->libusb_ctx, ctx->hotplug_handle);
return 0;
}
SR_API void sr_hotplug_wait_timout(struct sr_context *ctx)
SR_PRIV void sr_hotplug_wait_timout(struct sr_context *ctx)
{
if (!ctx) {
sr_err("%s(): libsigrok context was NULL.", __func__);
return;
}
libusb_handle_events_timeout(ctx->libusb_ctx, &ctx->hotplug_tv);
}
libusb_handle_events_timeout(ctx->libusb_ctx, &ctx->hotplug_tv);
}
/** @} */

View File

@ -308,7 +308,7 @@ static GSList *scan(GSList *options)
}
else {
char *firmware;
char *res_path = sr_get_firmware_res_path();
char *res_path = DS_RES_PATH;
if (!(firmware = g_try_malloc(strlen(res_path)+strlen(prof->firmware)+1))) {
sr_err("Firmware path malloc error!");
return NULL;

View File

@ -1919,7 +1919,7 @@ SR_PRIV int dsl_dev_open(struct sr_dev_driver *di, struct sr_dev_inst *sdi, gboo
if (sdi->status == SR_ST_ACTIVE) {
if (!(*fpga_done)) {
char *fpga_bit;
char *res_path = sr_get_firmware_res_path();
char *res_path = DS_RES_PATH;
if (!(fpga_bit = g_try_malloc(strlen(res_path)+strlen(devc->profile->fpga_bit33)+1))) {
sr_err("fpag_bit path malloc error!");
return SR_ERR_MALLOC;

View File

@ -379,7 +379,7 @@ static GSList *scan(GSList *options)
}
else {
char *firmware;
char *res_path = sr_get_firmware_res_path();
char *res_path = DS_RES_PATH;
if (!(firmware = g_try_malloc(strlen(res_path)+strlen(prof->firmware)+1))) {
sr_err("Firmware path malloc error!");
return NULL;
@ -1008,7 +1008,7 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi,
ret = SR_ERR;
}
char *fpga_bit;
char *res_path = sr_get_firmware_res_path();
char *res_path = DS_RES_PATH;
if (!(fpga_bit = g_try_malloc(strlen(res_path)+strlen(devc->profile->fpga_bit33)+1))) {
sr_err("fpag_bit path malloc error!");
return SR_ERR_MALLOC;

View File

@ -22,55 +22,68 @@
#include "libsigrok-internal.h"
#include "log.h"
struct device_all_info
{
struct sr_device_info _base_info;
};
#ifdef _WIN32
#include <windows.h>
#define _sleep(m) Sleep((m))
#else
#include <unistd.h>
#define _sleep(m) usleep((m) * 1000)
#endif
#define SR_DEVICE_MAX_COUNT 100
#undef LOG_PREFIX
#define LOG_PREFIX "lib_main: "
static char DS_RES_PATH[500] = {0};
static struct sr_context *g_sr_ctx = NULL;
char DS_RES_PATH[500] = {0};
static struct sr_context *sr_ctx = NULL;
static libsigrok_event_callback_t event_callback = NULL;
static GList* all_device_list = NULL; // All device instance, sr_dev_inst* type
static GThread *hotplug_thread = NULL;
static int sr_exit_flag = 0;
static int attach_event_flag = 0;
static int detach_event_flag = 0;
static int wait_redo_attch_flag = 0;
static int wait_redo_attch_times = 0;
//----------------------------private function----------------
/**
* Free device resource
*/
static sr_free_device(struct device_all_info *dev)
{
if (dev){
free(dev);
}
}
static void hotplug_event_listen_callback(struct libusb_context *ctx, struct libusb_device *dev, int event);
static void usb_hotplug_process_proc();
/**
* Must call first
*/
SR_API int sr_lib_init()
{
{
int ret = 0;
struct sr_dev_driver **drivers = NULL;
struct sr_dev_driver **dr = NULL;
if (g_sr_ctx != NULL){
if (sr_ctx != NULL){
return SR_ERR_HAVE_DONE;
}
ret = sr_init(&g_sr_ctx);
ret = sr_init(&sr_ctx);
if (ret != SR_OK){
return ret;
}
sr_exit_flag = 0;
// Initialise all libsigrok drivers
drivers = sr_driver_list();
for (dr = drivers; *dr; dr++) {
if (sr_driver_init(g_sr_ctx, *dr) != SR_OK) {
if (sr_driver_init(sr_ctx, *dr) != SR_OK) {
sr_err("Failed to initialize driver '%s'", (*dr)->name);
return SR_ERR;
}
}
sr_ctx->hotplug_tv.tv_sec = 0;
sr_ctx->hotplug_tv.tv_usec = 0;
sr_listen_hotplug(sr_ctx, hotplug_event_listen_callback);
/** Start usb hotplug thread */
hotplug_thread = g_thread_new("hotplug_proc", usb_hotplug_process_proc, NULL);
return SR_OK;
}
@ -84,13 +97,22 @@ SR_API int sr_lib_exit()
struct sr_dev_driver *driver_ins;
GSList *l;
struct sr_dev_inst *dev;
if (g_sr_ctx == NULL){
if (sr_ctx == NULL){
return SR_ERR_HAVE_DONE;
}
sr_close_hotplug(sr_ctx);
sr_exit_flag = 1; //all thread to exit
if (hotplug_thread != NULL){
g_thread_join(hotplug_thread);
hotplug_thread = NULL;
}
// Release all device
for (l=g_sr_ctx->deiveList; l; l = l->next)
for (l = all_device_list; l; l = l->next)
{
dev = l->data;
if (dev && dev->driver)
@ -103,12 +125,13 @@ SR_API int sr_lib_exit()
driver_ins->dev_close(dev);
}
}
g_safe_free_list(g_sr_ctx->deiveList);
g_safe_free_list(all_device_list);
if (sr_exit(g_sr_ctx) != SR_OK){
if (sr_exit(sr_ctx) != SR_OK){
sr_err("%s", "call sr_exit error");
}
g_sr_ctx = NULL;
sr_ctx = NULL;
return SR_OK;
}
@ -129,21 +152,84 @@ SR_API void sr_set_firmware_resource_dir(const char *dir)
}
}
SR_PRIV char* sr_get_firmware_res_path()
{
return DS_RES_PATH;
}
/**
* Set event callback, event type see enum libsigrok_event_type
*/
SR_API void sr_set_event_callback(libsigrok_event_callback_t *cb)
{
if (g_sr_ctx == NULL)
sr_lib_init();
if (g_sr_ctx != NULL){
g_sr_ctx->event_callback = cb;
event_callback = cb;
}
/**-------------------private function ---------------*/
static int scan_hardware_device()
{
}
static void hotplug_event_listen_callback(struct libusb_context *ctx, struct libusb_device *dev, int event)
{
if (event == USB_EV_HOTPLUG_ATTACH){
sr_info("One device attached.");
if (wait_redo_attch_flag){
sr_info("%s", "Device loose contact, but it reconnect success.");
}
wait_redo_attch_flag = 0;
attach_event_flag = 1;
}
else if (event == USB_EV_HOTPLUG_DETTACH){
sr_info("One device detached.");
wait_redo_attch_flag = 1; //Begin wait the device reconnect, if timeout, will process the detach event.
wait_redo_attch_times = 0;
}
else{
sr_err("%s", "Unknown usb event");
wait_redo_attch_flag = 1;
}
}
static void process_attach_event()
{
sr_info("%s", "Process device attch event.");
}
static void process_detach_event()
{
sr_info("%s", "Process device detach event.");
}
static void usb_hotplug_process_proc()
{
sr_info("%s", "Hotplug thread start!");
while (!sr_exit_flag)
{
sr_hotplug_wait_timout(sr_ctx);
if (attach_event_flag){
process_attach_event();
attach_event_flag = 0;
}
if (detach_event_flag){
process_detach_event();
detach_event_flag = 0;
}
_sleep(100);
if (wait_redo_attch_flag){
wait_redo_attch_times++;
// 500ms
if (wait_redo_attch_times == 5){
//Device loose contact,wait for it reconnection timeout.
detach_event_flag = 1; // use detach event
wait_redo_attch_flag = 0;
}
}
}
sr_info("%s", "Hotplug thread end!");
}

View File

@ -48,17 +48,23 @@
#undef max
#define max(a,b) ((a)>(b)?(a):(b))
#define USB_EV_HOTPLUG_UNKNOW 0
#define USB_EV_HOTPLUG_ATTACH 1
#define USB_EV_HOTPLUG_DETTACH 2
#define g_safe_free(p) if((p)) g_free((p)); ((p)) = NULL;
#define g_safe_free_list(p) if((p)) g_slist_free((p)); ((p)) = NULL;
/** global variable */
extern char DS_RES_PATH[500];
typedef void (*hotplug_event_callback)(struct libusb_context *ctx, struct libusb_device *dev, int event);
struct sr_context {
libusb_context* libusb_ctx;
libusb_hotplug_callback_handle hotplug_handle;
hotplug_event_callback hotplug_callback;
void *hotplug_user_data;
struct timeval hotplug_tv;
libsigrok_event_callback_t event_callback;
GList *deiveList; // All device instance, sr_dev_inst* type
};
struct sr_session {
@ -182,6 +188,7 @@ SR_PRIV int sr_session_source_add_channel(GIOChannel *channel, int events,
SR_PRIV int sr_session_source_remove(int fd);
SR_PRIV int sr_session_source_remove_pollfd(GPollFD *pollfd);
SR_PRIV int sr_session_source_remove_channel(GIOChannel *channel);
SR_PRIV int sr_session_datafeed_callback_add(sr_datafeed_callback_t cb,void *cb_data);
/*--- std.c -----------------------------------------------------------------*/
@ -259,7 +266,10 @@ SR_PRIV int sr_usb_open(libusb_context *usb_ctx, struct sr_usb_dev_inst *usb);
SR_PRIV int sr_init(struct sr_context **ctx);
SR_PRIV int sr_exit(struct sr_context *ctx);
/*--- lib_main.c -------------------------------------------------*/
SR_PRIV char* sr_get_firmware_res_path();
SR_PRIV int sr_listen_hotplug(struct sr_context *ctx, hotplug_event_callback callback);
SR_PRIV int sr_close_hotplug(struct sr_context *ctx);
SR_PRIV void sr_hotplug_wait_timout(struct sr_context *ctx);
/*--- lib_main.c -------------------------------------------------*/
#endif

View File

@ -160,11 +160,6 @@ enum {
#define SR_PRIV
#endif
#define USB_EV_HOTPLUG_UNKNOW 0
#define USB_EV_HOTPLUG_ATTACH 1
#define USB_EV_HOTPLUG_DETTACH 2
typedef unsigned long long sr_device_handle;
enum sr_device_type{
@ -1263,11 +1258,6 @@ struct ds_trigger_pos {
/*--- backend.c -------------------------------------------------------------*/
//@event, 1:attach, 2:left
typedef void (*hotplug_event_callback)(void *context,void *device, int event, void *userdata);
SR_API int sr_listen_hotplug(struct sr_context *ctx, hotplug_event_callback callback, void *userdata);
SR_API int sr_close_hotplug(struct sr_context *ctx);
SR_API void sr_hotplug_wait_timout(struct sr_context *ctx);
SR_PRIV int sr_init(struct sr_context **ctx);
SR_PRIV int sr_exit(struct sr_context *ctx);
@ -1327,8 +1317,7 @@ SR_API int sr_session_dev_list(GSList **devlist);
/* Datafeed setup */
SR_API int sr_session_datafeed_callback_remove_all(void);
SR_API int sr_session_datafeed_callback_add(sr_datafeed_callback_t cb,
void *cb_data);
/* Session control */
SR_API int sr_session_start(void);
@ -1478,7 +1467,7 @@ SR_API void sr_set_firmware_resource_dir(const char *dir);
/**
* Get the device list, the last item is null.
* Call free to release buffer. If the list is empty, it returns null.
* User need call free() to release the buffer. If the list is empty, it returns null.
*/
SR_API struct sr_device_info* sr_device_get_list(int *out_count);
@ -1488,6 +1477,13 @@ SR_API struct sr_device_info* sr_device_get_list(int *out_count);
*/
SR_API int sr_device_select(sr_device_handle handle);
/**
* Active a device, if success, it will trigs the event of EV_CURRENT_DEVICE_CHANGED.
* If the old actived device is hardware, maybe user need store the data first.
* @index is -1, will select the last one.
*/
SR_API int sr_device_select_by_index(int index);
/**
* Create a device from session file, it auto load the data.
*/

View File

@ -253,7 +253,7 @@ SR_API int sr_session_datafeed_callback_remove_all(void)
*
* @return SR_OK upon success, SR_ERR_BUG if no session exists.
*/
SR_API int sr_session_datafeed_callback_add(sr_datafeed_callback_t cb, void *cb_data)
SR_PRIV int sr_session_datafeed_callback_add(sr_datafeed_callback_t cb, void *cb_data)
{
struct datafeed_callback *cb_struct;

View File

@ -1,8 +1,34 @@
#include <libsigrok.h>
#include "../log.h"
#include <stdio.h>
int main2()
#undef LOG_PREFIX
#define LOG_PREFIX "test_main: "
int main()
{
int ret = 0;
if ((ret = sr_lib_init()) != SR_OK)
{
return 0;
}
sr_info("%s", "start.");
char c = 0;
while (1)
{
c = getchar();
if (c == 'x'){
sr_lib_exit();
sr_info("%s", "exit.");
break;
}
}
return 0;
}