added ftdi on linux

This commit is contained in:
François Dausseur
2025-02-12 12:37:38 +01:00
parent b6775ae680
commit a8e7599b96
13 changed files with 315 additions and 92 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/build

33
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,33 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/app/bs",
"args": ["-l", "scan"],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
}
]
}

View File

@@ -1,8 +1,10 @@
file(GLOB_RECURSE ALL_SOURCES "src/*.c")
# Application configuration # Application configuration
add_executable( add_executable(
bs bs
main.c ${ALL_SOURCES}
) )
# linking configuration # linking configuration

View File

@@ -1,21 +0,0 @@
#include <stdio.h>
#include "jtag_core.h"
void jtcprint(jtag_core *jc, const char *msg) {
printf(msg);
}
int main(int argc, char **argv) {
jtag_core *jc;
jc = jtagcore_init();
if (jtagcore_set_logs_callback(jc, jtcprint) < 0) goto end;
end:
jtagcore_deinit(jc);
printf("Finished.");
return 0;
}

65
app/src/args.c Normal file
View File

@@ -0,0 +1,65 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <string.h>
#include "args.h"
char * COMMAND_STRINGS[COMMANDS_NUMBER-1] = {
"scan"
};
void usage() {
printf("Usage: bs [[-l] [--list]] [[-n] [--nprobe] PROBE_NUM] [scan]\n");
}
int parse_args(struct args *a, int argc, char *argv[]) {
int opt = 0;
int i = 0;
int command = 0;
__uint8_t option_arg[32] = {0};
// Définir les options longues
static struct option long_options[] = {
{"list", no_argument, 0, 'l'},
{"nprobe", required_argument, 0, 'n'},
{0, 0, 0, 0}
};
// Utilisation de getopt_long pour parser les options
while ((opt = getopt_long(argc, argv, "ln:", long_options, NULL)) != -1) {
switch (opt) {
case 'l':
a->list = 1;
break;
case 'n':
snprintf(option_arg, sizeof(option_arg)-2, "%s");
a->probe = atoi(option_arg);
break;
default:
usage();
return EXIT_FAILURE;
}
}
// Positional arguments
if (optind < argc) {
/* Positional arguments */
while (optind < argc) {
for (i=0;i<COMMANDS_NUMBER-1;i++) {
if (0 == strcmp(COMMAND_STRINGS[i], argv[optind])) {
a->cmds[command] = (enum commands)i+1;
}
}
optind++;
}
}
// Si aucune option n'est fournie, afficher l'aide
if (optind == 1) {
usage();
}
return EXIT_SUCCESS;
}

20
app/src/args.h Normal file
View File

@@ -0,0 +1,20 @@
#ifndef _ARGS_H
#define _ARGS_H
#define MAX_COMMANDS 16
enum commands {
NO_COMMAND=0,
COMMAND_SCAN,
COMMANDS_NUMBER, /* The number of enums +1*/
};
struct args {
int list;
int probe;
enum commands cmds[MAX_COMMANDS];
};
int parse_args(struct args *a, int argc, char *argv[]);
#endif

108
app/src/main.c Normal file
View File

@@ -0,0 +1,108 @@
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include "jtag_core.h"
#include "args.h"
#define PROBES_MAX_NUM 16
#define PROBE_NAME_SIZE 64
struct probe {
int drv;
int probe;
int probe_id;
char name[PROBE_NAME_SIZE];
};
void jprint(jtag_core *jc, const char *msg) {
printf(msg);
}
int list_probes(jtag_core *jc, struct probe probes[], int show) {
int i = 0;
int j = 0;
int n = 0;
char probe_name[PROBE_NAME_SIZE] = {0};
int n_probe_drv = 0;
int n_probes = 0;
/* Drivers and probes */
n_probe_drv = jtagcore_get_number_of_probes_drv(jc);
if (n_probe_drv > 0) {
if (0 != show) printf("Found a debug probe driver:\n");
} else {
if (0 != show) printf("No probes driver found\n");
return n;
}
for (i=0;i<n_probe_drv;i++) {
if (0 != show) printf(" JTAG probe driver %d\n", i);
n_probes = jtagcore_get_number_of_probes(jc, i);
if (n_probes > 0) {
if (0 != show) printf("Found a debug probe:\n");
} else {
if (0 != show) printf("No probe found.\n");
continue;
}
for (j=0;j<n_probes;j++) {
jtagcore_get_probe_name(jc, PROBE_ID(i,j), probe_name);
if (n < PROBES_MAX_NUM) {
probes[n].drv = i;
probes[n].probe = j;
probes[n].probe_id = PROBE_ID(i,j);
strncpy(probes[n].name, probe_name, PROBE_NAME_SIZE);
}
n++;
if (0 != show) {
printf(" JTAG probe %d: ", n+1);
printf("%s.\n", probe_name);
}
}
}
return n;
}
int main(int argc, char *argv[]) {
int success;
int n_probes;
jtag_core *jc = NULL;
struct args a = {0};
struct probe probes[PROBES_MAX_NUM] = {0};
success = parse_args(&a, argc, argv);
if (EXIT_FAILURE == success) exit(EXIT_FAILURE);
/* initialize the JTAG library */
jc = jtagcore_init();
/* Log printing callback */
if (jtagcore_set_logs_callback(jc, jprint) < 0) goto err;
jtagcore_set_logs_level(jc, MSG_DEBUG);
/* List the probes (and display if asked) */
n_probes = list_probes(jc, probes, a.list);
goto end;
err:
printf("Error while executing a command.\n");
end:
jtagcore_deinit(jc);
printf("Finished.");
return 0;
}

View File

@@ -1,4 +1,5 @@
set(SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src") set(SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src")
set(LIB_FTD2XXX "${CMAKE_CURRENT_SOURCE_DIR}/../libs/libftd2xx.a")
file(GLOB_RECURSE ALL_SOURCES "src/*.c") file(GLOB_RECURSE ALL_SOURCES "src/*.c")
@@ -16,7 +17,13 @@ add_custom_target(
DEPENDS prebuild_command_done DEPENDS prebuild_command_done
) )
add_compile_definitions(FTD2XX_STATIC)
add_compile_definitions(FTDILIB)
add_library(jtag_core ${ALL_SOURCES}) add_library(jtag_core ${ALL_SOURCES})
add_dependencies(jtag_core prebuild) add_dependencies(jtag_core prebuild)
target_link_libraries(jtag_core PRIVATE ${LIB_FTD2XXX})
target_include_directories(jtag_core PUBLIC ${SOURCE_DIR}) target_include_directories(jtag_core PUBLIC ${SOURCE_DIR})

View File

@@ -31,7 +31,6 @@
#include "../bsdl_parser/bsdl_loader.h" #include "../bsdl_parser/bsdl_loader.h"
#ifdef WIN32 #ifdef WIN32
#include "./ftdi_jtag/ftdi_jtag_drv.h"
#include "./lpt_jtag/lpt_jtag_drv.h" #include "./lpt_jtag/lpt_jtag_drv.h"
#endif #endif
@@ -40,6 +39,7 @@
#endif #endif
#if defined(__linux__) || defined(WIN32) #if defined(__linux__) || defined(WIN32)
#include "./ftdi_jtag/ftdi_jtag_drv.h"
#include "./jlink_jtag/jlink_jtag_drv.h" #include "./jlink_jtag/jlink_jtag_drv.h"
#endif #endif
@@ -48,7 +48,6 @@
const drv_entry staticdrvs[] = const drv_entry staticdrvs[] =
{ {
#ifdef WIN32 #ifdef WIN32
{(DRV_GETMODULEINFOS)drv_FTDI_libGetDrv,0},
#if !defined(_WIN64) #if !defined(_WIN64)
{(DRV_GETMODULEINFOS)drv_LPT_libGetDrv,0}, {(DRV_GETMODULEINFOS)drv_LPT_libGetDrv,0},
{(DRV_GETMODULEINFOS)drv_LPT_libGetDrv,1}, {(DRV_GETMODULEINFOS)drv_LPT_libGetDrv,1},
@@ -56,6 +55,7 @@ const drv_entry staticdrvs[] =
#endif #endif
#endif #endif
#if defined(__linux__) || defined(WIN32) #if defined(__linux__) || defined(WIN32)
{(DRV_GETMODULEINFOS)drv_FTDI_libGetDrv,0},
{(DRV_GETMODULEINFOS)drv_JLINK_libGetDrv,0}, {(DRV_GETMODULEINFOS)drv_JLINK_libGetDrv,0},
#endif #endif
#if defined(__linux__) #if defined(__linux__)

20
lib_jtag_core/src/drivers/ftdi_jtag/ftdi/WinTypes.h Normal file → Executable file
View File

@@ -9,6 +9,7 @@ typedef unsigned short USHORT;
typedef unsigned short SHORT; typedef unsigned short SHORT;
typedef unsigned char UCHAR; typedef unsigned char UCHAR;
typedef unsigned short WORD; typedef unsigned short WORD;
typedef unsigned short WCHAR;
typedef unsigned char BYTE; typedef unsigned char BYTE;
typedef BYTE *LPBYTE; typedef BYTE *LPBYTE;
typedef unsigned int BOOL; typedef unsigned int BOOL;
@@ -32,13 +33,19 @@ typedef ULONG *PULONG;
typedef LONG *LPLONG; typedef LONG *LPLONG;
typedef PVOID LPVOID; typedef PVOID LPVOID;
typedef void VOID; typedef void VOID;
typedef USHORT *PUSHORT;
typedef unsigned long long int ULONGLONG; typedef unsigned long long int ULONGLONG;
typedef struct _OVERLAPPED { typedef struct _OVERLAPPED {
DWORD Internal; DWORD Internal;
DWORD InternalHigh; DWORD InternalHigh;
union {
struct{
DWORD Offset; DWORD Offset;
DWORD OffsetHigh; DWORD OffsetHigh;
};
PVOID Pointer;
};
HANDLE hEvent; HANDLE hEvent;
} OVERLAPPED, *LPOVERLAPPED; } OVERLAPPED, *LPOVERLAPPED;
@@ -61,13 +68,24 @@ typedef struct _EVENT_HANDLE
typedef struct timeval SYSTEMTIME; typedef struct timeval SYSTEMTIME;
typedef struct timeval FILETIME; typedef struct timeval FILETIME;
// WaitForSingleObject return values.
#define WAIT_ABANDONED 0x00000080L
#define WAIT_OBJECT_0 0x00000000L
#define WAIT_TIMEOUT 0x00000102L
#define WAIT_FAILED 0xFFFFFFFF
// Special value for WaitForSingleObject dwMilliseconds parameter
#define INFINITE 0xFFFFFFFF // Infinite timeout
#ifndef TRUE #ifndef TRUE
#define TRUE 1 #define TRUE 1
#endif #endif
#ifndef FALSE #ifndef FALSE
#define FALSE 0 #define FALSE 0
#endif #endif
#ifndef CONST
#define CONST const
#endif
// //
// Modem Status Flags // Modem Status Flags
// //

5
lib_jtag_core/src/drivers/ftdi_jtag/ftdi/ftd2xx.h Normal file → Executable file
View File

@@ -225,6 +225,9 @@ enum {
FT_DEVICE_4222H_1_2, FT_DEVICE_4222H_1_2,
FT_DEVICE_4222H_3, FT_DEVICE_4222H_3,
FT_DEVICE_4222_PROG, FT_DEVICE_4222_PROG,
FT_DEVICE_900,
FT_DEVICE_930,
FT_DEVICE_UMFTPD3A,
}; };
// //
@@ -1178,7 +1181,7 @@ extern "C" {
WORD XoffLim; /* Transmit X-OFF threshold */ WORD XoffLim; /* Transmit X-OFF threshold */
BYTE ByteSize; /* Number of bits/byte, 4-8 */ BYTE ByteSize; /* Number of bits/byte, 4-8 */
BYTE Parity; /* 0-4=None,Odd,Even,Mark,Space */ BYTE Parity; /* 0-4=None,Odd,Even,Mark,Space */
BYTE StopBits; /* 0,1,2 = 1, 1.5, 2 */ BYTE StopBits; /* FT_STOP_BITS_1 or FT_STOP_BITS_2 */
char XonChar; /* Tx and Rx X-ON character */ char XonChar; /* Tx and Rx X-ON character */
char XoffChar; /* Tx and Rx X-OFF character */ char XoffChar; /* Tx and Rx X-OFF character */
char ErrorChar; /* Error replacement char */ char ErrorChar; /* Error replacement char */

View File

@@ -34,11 +34,8 @@
#include "../drv_loader.h" #include "../drv_loader.h"
#include "../../jtag_core_internal.h" #include "../../jtag_core_internal.h"
#include "../../jtag_core.h" #include "../../jtag_core.h"
#include "../../bsdl_parser/bsdl_loader.h" #include "../../bsdl_parser/bsdl_loader.h"
#include "../../dbg_logs.h" #include "../../dbg_logs.h"
#include "../../os_interface/os_interface.h" #include "../../os_interface/os_interface.h"
#ifdef __cplusplus #ifdef __cplusplus
@@ -57,8 +54,6 @@ extern "C" {
#define MACH_WORD int #define MACH_WORD int
#endif #endif
#if defined(WIN32)
typedef struct _drv_desc typedef struct _drv_desc
{ {
char drv_id[128]; char drv_id[128];
@@ -117,8 +112,6 @@ static drv_desc subdrv_list[MAX_PROBES_FTDI]=
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
static HMODULE lib_handle = 0;
static FT_HANDLE ftdih = NULL; static FT_HANDLE ftdih = NULL;
static FT_DEVICE ftdi_device; static FT_DEVICE ftdi_device;
@@ -191,7 +184,23 @@ FT_RESETDEVICE pFT_ResetDevice;
FT_SETCHARS pFT_SetChars; FT_SETCHARS pFT_SetChars;
#else #else
#define pFT_Open FT_Open
#define pFT_OpenEx FT_OpenEx
#define pFT_Read FT_Read
#define pFT_Write FT_Write
#define pFT_GetStatus FT_GetStatus
#define pFT_Purge FT_Purge
#define pFT_SetUSBParameters FT_SetUSBParameters
#define pFT_SetLatencyTimer FT_SetLatencyTimer
#define pFT_SetEventNotification FT_SetEventNotification
#define pFT_Close FT_Close
#define pFT_ListDevices FT_ListDevices
#define pFT_SetBitMode FT_SetBitMode
#define pFT_SetTimeouts FT_SetTimeouts
#define pFT_GetQueueStatus FT_GetQueueStatus
#define pFT_GetDeviceInfo FT_GetDeviceInfo
#define pFT_ResetDevice FT_ResetDevice
#define pFT_SetChars FT_SetChars
#endif #endif
@@ -254,15 +263,6 @@ int drv_FTDI_Detect(jtag_core * jc)
FT_STATUS status; FT_STATUS status;
char SerialNumber[512]; char SerialNumber[512];
if(lib_handle == NULL)
lib_handle = LoadLibrary("ftd2xx.dll");
if (lib_handle)
{
pFT_ListDevices = (FT_LISTDEVICES)GetProcAddress(lib_handle, "FT_ListDevices");
if (!pFT_ListDevices)
return 0;
status = pFT_ListDevices(&numDevs, NULL, FT_LIST_NUMBER_ONLY); status = pFT_ListDevices(&numDevs, NULL, FT_LIST_NUMBER_ONLY);
if (status != FT_OK && !numDevs) if (status != FT_OK && !numDevs)
{ {
@@ -299,13 +299,7 @@ int drv_FTDI_Detect(jtag_core * jc)
jtagcore_logs_printf( jc, MSG_INFO_1, "drv_FTDI_Detect : %d interface(s) found !\r\n", numDevs ); jtagcore_logs_printf( jc, MSG_INFO_1, "drv_FTDI_Detect : %d interface(s) found !\r\n", numDevs );
return numDevs; return numDevs;
}
else
{
jtagcore_logs_printf( jc, MSG_INFO_1, "drv_FTDI_Detect : ftd2xx.dll not found !\r\n" );
}
return 0;
} }
void update_gpio_state(int index,int state) void update_gpio_state(int index,int state)
@@ -423,8 +417,7 @@ int drv_FTDI_Init(jtag_core * jc, int sub_drv, char * params)
return -1; return -1;
} }
#else #else
// TODO : Linux lib loader.
return -1;
#endif #endif
status = pFT_ListDevices(&numDevs, NULL, FT_LIST_NUMBER_ONLY); status = pFT_ListDevices(&numDevs, NULL, FT_LIST_NUMBER_ONLY);
@@ -678,16 +671,12 @@ int drv_FTDI_Init(jtag_core * jc, int sub_drv, char * params)
return 0; return 0;
loadliberror: loadliberror:
FreeLibrary(lib_handle);
lib_handle = NULL;
return -1; return -1;
} }
int drv_FTDI_DeInit(jtag_core * jc) int drv_FTDI_DeInit(jtag_core * jc)
{ {
pFT_Close(ftdih); pFT_Close(ftdih);
FreeLibrary(lib_handle);
lib_handle = NULL;
return 0; return 0;
} }
@@ -963,5 +952,3 @@ int drv_FTDI_libGetDrv(jtag_core * jc,int sub_drv,unsigned int infotype,void * r
&drv_funcs &drv_funcs
); );
} }
#endif

BIN
libs/libftd2xx.a Normal file

Binary file not shown.